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

Reply via email to