Index: source/blender/render/intern/source/pixelshading.c =================================================================== --- source/blender/render/intern/source/pixelshading.c (revision 13044) +++ source/blender/render/intern/source/pixelshading.c (working copy) @@ -236,13 +236,55 @@ } +/** + * Converts a z-buffer value to absolute 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 ZtoD(int z) +{ + int ortho = R.r.mode & R_ORTHO; + float zco = 0; + if(z >= 8388607) + return 10e10; + else { + zco = ((float)z)/8388607.0f; + if(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); + } + return 10e10; +} + + +/** + * @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 o the pixel relaticve to the center of the halo. given in pixels + * @param yn The y coordinate o the pixel relaticve to the center of the halo. given in pixels + */ void shadeHaloFloat(HaloRen *har, float *col, int zz, float dist, float xn, float yn, short flarec) { /* fill in col */ float t, zn, radist, ringf=0.0f, linef=0.0f, alpha, si, co; int a; + + // Do depth test unless this is a soft halo + if (!(har->mat->mode & MA_HALO_SOFT)) { + if(zz <= har->zs) { + col[0] = 0.0; + col[1] = 0.0; + col[2] = 0.0; + col[3] = 0.0; + return; + } + } if(R.wrld.mode & WO_MIST) { if(har->type & HA_ONLYSKY) { @@ -360,11 +402,30 @@ } } - /* halo being intersected? */ - if(har->zs> zz-har->zd) { - t= ((float)(zz-har->zs))/(float)har->zd; - alpha*= sqrt(sqrt(t)); + // Soften the halo if it intersects geometry + if (har->mat->mode & MA_HALO_SOFT) { + // Calculate halo sphere depth at this pixel + float normalized_distance = sqrt(dist)/har->rad; + if (normalized_distance>1.0f) normalized_distance = 1.0f; + float segment_length = har->hasize * sqrt(1.0f-normalized_distance*normalized_distance); + float halo_depth = 2.0f * segment_length; + // Calculate how much of this depth is visible + float distance_from_z = ZtoD(zz) - ZtoD(har->zs); + float visible_depth = halo_depth; + if (distance_from_zzs> zz-har->zd) { + t= ((float)(zz-har->zs))/(float)har->zd; + alpha*= sqrt(sqrt(t)); + } + } /* disputable optimize... (ton) */ if(dist<=0.00001) { @@ -434,6 +495,7 @@ /* alpha requires clip, gives black dots */ if(col[3] > 1.0f) col[3]= 1.0f; + } /* ------------------------------------------------------------------------- */ Index: source/blender/render/intern/source/rendercore.c =================================================================== --- source/blender/render/intern/source/rendercore.c (revision 13044) +++ source/blender/render/intern/source/rendercore.c (working copy) @@ -177,7 +177,7 @@ amount+= amountm; zz= calchalo_z(har, ps->z); - if(zz> har->zs) { + //if(zz> har->zs) { float fac; shadeHaloFloat(har, col, zz, dist, xn, yn, flarec); @@ -187,7 +187,7 @@ accol[2]+= fac*col[2]; accol[3]+= fac*col[3]; flarec= 0; - } + //} ps= ps->next; } @@ -273,10 +273,10 @@ } else { zz= calchalo_z(har, *rz); - if(zz> har->zs) { + //if(zz> har->zs) { shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec); addalphaAddfacFloat(rb, col, har->add); - } + //} } } if(rd) rd++; Index: source/blender/render/intern/include/render_types.h =================================================================== --- source/blender/render/intern/include/render_types.h (revision 13044) +++ source/blender/render/intern/include/render_types.h (working copy) @@ -312,22 +312,27 @@ int index; } VlakRen; + typedef struct HaloRen { short miny, maxy; - float alfa, xs, ys, rad, radsq, sin, cos, co[3], no[3]; + float alfa, xs, ys; + float rad, radsq; // Radius of the halo in pixels (regular and squared) + float sin, cos, co[3], no[3]; float hard, b, g, r; - int zs, zd; - int zBufDist; /* depth in the z-buffer coordinate system */ + int zs; // Halo's z-value (the halo is a flat circle so all of it has the same z-value) + int zd; // I wonder what this one is for. Seriously, why don't people ever comment their code? + int zBufDist; // depth in the z-buffer coordinate system, (so what is the difference between this and zs?) char starpoints, type, add, tex; char linec, ringc, seed; - short flarec; /* used to be a char. why ?*/ - float hasize; + short flarec; // used to be a char. why ? + float hasize; // Size (radius) of the halo in blender units (default 0.5) int pixels; unsigned int lay; struct Material *mat; } HaloRen; + typedef struct StrandVert { float co[3]; float strandco; Index: source/blender/makesdna/DNA_material_types.h =================================================================== --- source/blender/makesdna/DNA_material_types.h (revision 13044) +++ source/blender/makesdna/DNA_material_types.h (working copy) @@ -177,6 +177,7 @@ #define MA_HALO_SHADE 0x4000 #define MA_HALO_FLARE 0x8000 #define MA_RADIO 0x10000 +#define MA_HALO_SOFT 0x10000 #define MA_RAYTRANSP 0x20000 #define MA_RAYMIRROR 0x40000 #define MA_SHADOW_TRA 0x80000 Index: source/blender/src/buttons_shading.c =================================================================== --- source/blender/src/buttons_shading.c (revision 13044) +++ source/blender/src/buttons_shading.c (working copy) @@ -3729,14 +3729,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"); + uiDefButBitI(block, TOG, MA_HALO_SHADE, B_MATPRV, "Shaded", 245,28,65, 18, &(ma->mode), 0, 0, 0, 0, "Lets halo receive light and shadows"); + uiDefButBitI(block, TOG, MA_HALO_SOFT, B_MATPRV, "Soft", 245,9,65, 18, &(ma->mode), 0, 0, 0, 0, "Softens the halo"); uiBlockEndAlign(block); } else { Index: config/linux2-config.py =================================================================== --- config/linux2-config.py (revision 13044) +++ config/linux2-config.py (working copy) @@ -115,7 +115,7 @@ BF_ICONV_LIBPATH = '${BF_ICONV}/lib' # enable ffmpeg support -WITH_BF_FFMPEG = 'true' # -DWITH_FFMPEG +WITH_BF_FFMPEG = 'false' # -DWITH_FFMPEG BF_FFMPEG = '#extern/ffmpeg' BF_FFMPEG_LIB = '' # Uncomment the following two lines to use system's ffmpeg