Revision: 14421 http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=14421 Author: blendix Date: 2008-04-14 21:48:14 +0200 (Mon, 14 Apr 2008)
Log Message: ----------- Patch #8034: "soft" option for halos, which avoids ugly intersections with geometry, and makes halos look more volumetric. Patch contributed by Markus Ilmola, thanks! Modified Paths: -------------- trunk/blender/source/blender/makesdna/DNA_material_types.h trunk/blender/source/blender/render/intern/include/pixelshading.h trunk/blender/source/blender/render/intern/source/pixelshading.c trunk/blender/source/blender/render/intern/source/rendercore.c trunk/blender/source/blender/src/buttons_shading.c Modified: trunk/blender/source/blender/makesdna/DNA_material_types.h =================================================================== --- trunk/blender/source/blender/makesdna/DNA_material_types.h 2008-04-14 15:40:32 UTC (rev 14420) +++ trunk/blender/source/blender/makesdna/DNA_material_types.h 2008-04-14 19:48:14 UTC (rev 14421) @@ -161,6 +161,7 @@ #define MA_SHLESS 4 #define MA_WIRE 8 #define MA_VERTEXCOL 16 +#define MA_HALO_SOFT 16 #define MA_HALO 32 #define MA_ZTRA 64 #define MA_VERTEXCOLP 128 Modified: trunk/blender/source/blender/render/intern/include/pixelshading.h =================================================================== --- trunk/blender/source/blender/render/intern/include/pixelshading.h 2008-04-14 15:40:32 UTC (rev 14420) +++ trunk/blender/source/blender/render/intern/include/pixelshading.h 2008-04-14 19:48:14 UTC (rev 14421) @@ -45,7 +45,7 @@ * mask is pixel coverage in bits * @return pointer to the object */ -void shadeHaloFloat(HaloRen *har, +int shadeHaloFloat(HaloRen *har, float *col, int zz, float dist, float xn, float yn, short flarec); Modified: trunk/blender/source/blender/render/intern/source/pixelshading.c =================================================================== --- trunk/blender/source/blender/render/intern/source/pixelshading.c 2008-04-14 15:40:32 UTC (rev 14420) +++ trunk/blender/source/blender/render/intern/source/pixelshading.c 2008-04-14 19:48:14 UTC (rev 14421) @@ -24,6 +24,7 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include <float.h> #include <math.h> #include <string.h> #include "BLI_arithb.h" @@ -243,8 +244,36 @@ } +/** + * Converts a halo z-buffer value to distance from the camera's near plane + * @param z The z-buffer value to convert + * @return a distance from the camera's near plane in blender units + */ +static float haloZtoDist(int z) +{ + float zco = 0; -void shadeHaloFloat(HaloRen *har, float *col, int zz, + if(z >= 0x7FFFFF) + return 10e10; + else { + zco = (float)z/(float)0x7FFFFF; + if(R.r.mode & R_ORTHO) + return (R.winmat[3][2] - zco*R.winmat[3][3])/(R.winmat[2][2]); + else + return (R.winmat[3][2])/(R.winmat[2][2] - R.winmat[2][3]*zco); + } +} + +/** + * @param col (float[4]) Store the rgb color here (with alpha) + * The alpha is used to blend the color to the background + * color_new = (1-alpha)*color_background + color + * @param zz The current zbuffer value at the place of this pixel + * @param dist Distance of the pixel from the center of the halo squared. Given in pixels + * @param xn The x coordinate of the pixel relaticve to the center of the halo. given in pixels + * @param yn The y coordinate of the pixel relaticve to the center of the halo. given in pixels + */ +int shadeHaloFloat(HaloRen *har, float *col, int zz, float dist, float xn, float yn, short flarec) { /* fill in col */ @@ -263,13 +292,41 @@ } else alpha= har->alfa; - if(alpha==0.0) { - col[0] = 0.0; - col[1] = 0.0; - col[2] = 0.0; - col[3] = 0.0; - return; + if(alpha==0.0) + return 0; + + /* soften the halo if it intersects geometry */ + if(har->mat->mode & MA_HALO_SOFT) { + float segment_length, halo_depth, distance_from_z, visible_depth, soften; + + /* calculate halo depth */ + segment_length= har->hasize*sasqrt(1.0f - dist/(har->rad*har->rad)); + halo_depth= 2.0f*segment_length; + + if(halo_depth < FLT_EPSILON) + return 0; + + /* calculate how much of this depth is visible */ + distance_from_z = haloZtoDist(zz) - haloZtoDist(har->zs); + visible_depth = halo_depth; + if(distance_from_z < segment_length) { + soften= (segment_length + distance_from_z)/halo_depth; + + /* apply softening to alpha */ + if(soften < 1.0f) + alpha *= soften; + if(alpha <= 0.0f) + return 0; + } } + else { + /* not a soft halo. use the old softening code */ + /* halo being intersected? */ + if(har->zs> zz-har->zd) { + t= ((float)(zz-har->zs))/(float)har->zd; + alpha*= sqrt(sqrt(t)); + } + } radist= sqrt(dist); @@ -366,21 +423,10 @@ if(ster<1.0) dist*= sqrt(ster); } } - - /* halo being intersected? */ - if(har->zs> zz-har->zd) { - t= ((float)(zz-har->zs))/(float)har->zd; - alpha*= sqrt(sqrt(t)); - } /* disputable optimize... (ton) */ - if(dist<=0.00001) { - col[0] = 0.0; - col[1] = 0.0; - col[2] = 0.0; - col[3] = 0.0; - return; - } + if(dist<=0.00001) + return 0; dist*= alpha; ringf*= dist; @@ -441,6 +487,8 @@ /* alpha requires clip, gives black dots */ if(col[3] > 1.0f) col[3]= 1.0f; + + return 1; } /* ------------------------------------------------------------------------- */ Modified: trunk/blender/source/blender/render/intern/source/rendercore.c =================================================================== --- trunk/blender/source/blender/render/intern/source/rendercore.c 2008-04-14 15:40:32 UTC (rev 14420) +++ trunk/blender/source/blender/render/intern/source/rendercore.c 2008-04-14 19:48:14 UTC (rev 14421) @@ -165,9 +165,11 @@ return zz; } + + static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, int od, float dist, float xn, float yn, PixStr *ps) { - float col[4], accol[4]; + float col[4], accol[4], fac; int amount, amountm, zz, flarec, sample, fullsample, mask=0; fullsample= (totsample > 1); @@ -180,24 +182,23 @@ amount+= amountm; zz= calchalo_z(har, ps->z); - if(zz> har->zs) { - float fac; - - shadeHaloFloat(har, col, zz, dist, xn, yn, flarec); - flarec= 0; + if((zz> har->zs) || (har->mat->mode & MA_HALO_SOFT)) { + if(shadeHaloFloat(har, col, zz, dist, xn, yn, flarec)) { + flarec= 0; - if(fullsample) { - for(sample=0; sample<totsample; sample++) - if(ps->mask & (1 << sample)) - addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add); + if(fullsample) { + for(sample=0; sample<totsample; sample++) + if(ps->mask & (1 << sample)) + addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add); + } + else { + fac= ((float)amountm)/(float)R.osa; + accol[0]+= fac*col[0]; + accol[1]+= fac*col[1]; + accol[2]+= fac*col[2]; + accol[3]+= fac*col[3]; + } } - else { - fac= ((float)amountm)/(float)R.osa; - accol[0]+= fac*col[0]; - accol[1]+= fac*col[1]; - accol[2]+= fac*col[2]; - accol[3]+= fac*col[3]; - } } mask |= ps->mask; @@ -207,16 +208,14 @@ /* now do the sky sub-pixels */ amount= R.osa-amount; if(amount) { - float fac; - - shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec); - - if(!fullsample) { - fac= ((float)amount)/(float)R.osa; - accol[0]+= fac*col[0]; - accol[1]+= fac*col[1]; - accol[2]+= fac*col[2]; - accol[3]+= fac*col[3]; + if(shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec)) { + if(!fullsample) { + fac= ((float)amount)/(float)R.osa; + accol[0]+= fac*col[0]; + accol[1]+= fac*col[1]; + accol[2]+= fac*col[2]; + accol[3]+= fac*col[3]; + } } } @@ -301,11 +300,11 @@ } else { zz= calchalo_z(har, *rz); - if(zz> har->zs) { - shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec); - - for(sample=0; sample<totsample; sample++) - addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add); + if((zz> har->zs) || (har->mat->mode & MA_HALO_SOFT)) { + if(shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) { + for(sample=0; sample<totsample; sample++) + addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add); + } } } } @@ -1634,8 +1633,8 @@ dist= xsq+ysq; if(dist<har->radsq) { - shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec); - addalphaAddfacFloat(rtf, colf, har->add); + if(shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec)) + addalphaAddfacFloat(rtf, colf, har->add); } rtf+=4; } Modified: trunk/blender/source/blender/src/buttons_shading.c =================================================================== --- trunk/blender/source/blender/src/buttons_shading.c 2008-04-14 15:40:32 UTC (rev 14420) +++ trunk/blender/source/blender/src/buttons_shading.c 2008-04-14 19:48:14 UTC (rev 14421) @@ -3843,14 +3843,15 @@ uiBlockSetCol(block, TH_BUT_SETTING1); uiBlockBeginAlign(block); - uiDefButBitI(block, TOG, MA_HALO_FLARE, B_MATPRV, "Flare",245,142,65,28, &(ma->mode), 0, 0, 0, 0, "Renders halo as a lensflare"); - uiDefButBitI(block, TOG, MA_HALO_RINGS, B_MATPRV, "Rings", 245,123,65, 18, &(ma->mode), 0, 0, 0, 0, "Renders rings over halo"); - uiDefButBitI(block, TOG, MA_HALO_LINES, B_MATPRV, "Lines", 245,104,65, 18, &(ma->mode), 0, 0, 0, 0, "Renders star shaped lines over halo"); - uiDefButBitI(block, TOG, MA_STAR, B_MATPRV, "Star", 245,85,65, 18, &(ma->mode), 0, 0, 0, 0, "Renders halo as a star"); - uiDefButBitI(block, TOG, MA_HALOTEX, B_MATPRV, "HaloTex", 245,66,65, 18, &(ma->mode), 0, 0, 0, 0, "Gives halo a texture"); - uiDefButBitI(block, TOG, MA_HALOPUNO, B_MATPRV, "HaloPuno", 245,47,65, 18, &(ma->mode), 0, 0, 0, 0, "Uses the vertex normal to specify the dimension of the halo"); - uiDefButBitI(block, TOG, MA_HALO_XALPHA, B_MATPRV, "X Alpha", 245,28,65, 18, &(ma->mode), 0, 0, 0, 0, "Uses extreme alpha"); - uiDefButBitI(block, TOG, MA_HALO_SHADE, B_MATPRV, "Shaded", 245,9,65, 18, &(ma->mode), 0, 0, 0, 0, "Lets halo receive light and shadows"); + uiDefButBitI(block, TOG, MA_HALO_FLARE, B_MATPRV, "Flare", 245,161,65,28, &(ma->mode), 0, 0, 0, 0, "Renders halo as a lensflare"); + uiDefButBitI(block, TOG, MA_HALO_RINGS, B_MATPRV, "Rings", 245,142,65,18, &(ma->mode), 0, 0, 0, 0, "Renders rings over halo"); + uiDefButBitI(block, TOG, MA_HALO_LINES, B_MATPRV, "Lines", 245,123,65,18, &(ma->mode), 0, 0, 0, 0, "Renders star shaped lines over halo"); + uiDefButBitI(block, TOG, MA_STAR, B_MATPRV, "Star", 245,104,65, 18, &(ma->mode), 0, 0, 0, 0, "Renders halo as a star"); + uiDefButBitI(block, TOG, MA_HALOTEX, B_MATPRV, "HaloTex", 245,85,65, 18, &(ma->mode), 0, 0, 0, 0, "Gives halo a texture"); + uiDefButBitI(block, TOG, MA_HALOPUNO, B_MATPRV, "HaloPuno", 245,66,65, 18, &(ma->mode), 0, 0, 0, 0, "Uses the vertex normal to specify the dimension of the halo"); + uiDefButBitI(block, TOG, MA_HALO_XALPHA, B_MATPRV, "X Alpha", 245,47,65, 18, &(ma->mode), 0, 0, 0, 0, "Uses extreme alpha"); @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs