Revision: 17193
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17193
Author:   broken
Date:     2008-10-23 05:50:56 +0200 (Thu, 23 Oct 2008)

Log Message:
-----------
* More improvements for light cache

Previously when using light cache, there could be artifacts caused when 
voxel points that were sampled outside the volume object's geometry got 
interpolated into the rest of the volume. This commit adds a (similar 
to a dilate) filter pass after creating the light cache, that fills 
these empty areas with the average of their surrounding voxels.

http://mke3.net/blender/devel/rendering/volumetrics/vol_lightcache_filter.jpg

Modified Paths:
--------------
    branches/sim_physics/source/blender/render/intern/source/volumetric.c

Modified: branches/sim_physics/source/blender/render/intern/source/volumetric.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/volumetric.c       
2008-10-23 02:15:36 UTC (rev 17192)
+++ branches/sim_physics/source/blender/render/intern/source/volumetric.c       
2008-10-23 03:50:56 UTC (rev 17193)
@@ -75,6 +75,7 @@
        return (INPR(is->vec, vlr->n) < 0.0f);
 }
 
+#if 0
 static int vol_frontface_intersect_check(Isect *is, int ob, RayFace *face)
 {
        VlakRen *vlr = (VlakRen *)face;
@@ -88,6 +89,7 @@
 {
        return 1;
 }
+#endif
 
 #define VOL_IS_BACKFACE                        1
 #define VOL_IS_SAMEMATERIAL            2
@@ -257,12 +259,6 @@
        return (1.f - t) * v1 + t * v2;
 }
 
-inline float do_lerp(float t, float a, float b) {
-       if (a > 0.f && b > 0.f) return lerp(t, a, b);
-       else if (a < 0.f)               return b;
-       else if (b < 0.f)               return a;
-}
-
 /* trilinear interpolation */
 static void vol_get_precached_scattering(ShadeInput *shi, float *scatter_col, 
float *co)
 {
@@ -384,7 +380,6 @@
        float p;
        float scatter_fac;
        float shade_stepsize = vol_get_stepsize(shi, STEPSIZE_SHADE);
-       float shadfac[4];
        
        if (lar->mode & LA_LAYER) if((lar->lay & shi->obi->lay)==0) return;
        if ((lar->lay & shi->lay)==0) return;
@@ -454,7 +449,6 @@
 void vol_get_scattering(ShadeInput *shi, float *scatter, float *co, float 
stepsize, float density)
 {
        GroupObject *go;
-       ListBase *lights;
        LampRen *lar;
        float col[3] = {0.f, 0.f, 0.f};
        int i=0;
@@ -530,10 +524,10 @@
                        
                        if ((shi->mat->vol_shadeflag & MA_VOL_PRECACHESHADING) 
&&
                                (shi->mat->vol_shadeflag & MA_VOL_ATTENUATED)) {
-                               if (G.rt==0)
+                               if (G.rt==100)
+                                       
vol_get_precached_scattering_nearest(shi, scatter_col, step_mid);
+                               else
                                        vol_get_precached_scattering(shi, 
scatter_col, step_mid);
-                               else
-                                       
vol_get_precached_scattering_nearest(shi, scatter_col, step_mid);
                        } else
                                vol_get_scattering(shi, scatter_col, step_mid, 
stepsize, density);
                                                
@@ -782,7 +776,6 @@
 int point_inside_obi(RayTree *tree, ObjectInstanceRen *obi, float *co)
 {
        float maxsize = RE_ray_tree_max_size(tree);
-       int intersected;
        Isect isect;
        float vec[3] = {0.0f,0.0f,1.0f};
        int final_depth=0, depth=0, limit=20;
@@ -848,6 +841,67 @@
        return tree;
 }
 
+static float get_avg_surrounds(float *cache, int res, int res_2, int res_3, 
int rgb, int xx, int yy, int zz)
+{
+       int x, y, z, x_, y_, z_;
+       int added=0;
+       float tot=0.0f;
+       int i;
+       
+       x_ = xx+x;
+       y_ = yy+y;
+       z_ = zz+z;
+       
+       for (x=-1; x <= 1; x++) {
+               if (x_ >= 0 && x_ <= res-1) {
+                       for (y=-1; y <= 1; y++) {
+                               if (y_ >= 0 && y_ <= res-1) {
+                                       for (z=-1; z <= 1; z++) {
+                                               if (z_ >= 0 && z_ <= res-1) {
+                                                       i = rgb*res_3 + 
x_*res_2 + y_*res + z_;
+                                                       if (cache[i] > 0.0f) {
+                                                               tot += cache[i];
+                                                               added++;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       tot /= added;
+       
+       return ((added>0)?tot:0.0f);
+}
+
+/* function to filter the edges of the light cache, where there was no volume 
originally.
+ * For each voxel which was originally external to the mesh, it finds the 
average values of
+ * the surrounding internal voxels and sets the original external voxel to 
that average amount.
+ * Works almost a bit like a 'dilate' filter */
+static void lightcache_filter(float *cache, int res)
+{
+       int x, y, z, rgb;
+       int res_2, res_3;
+       int i;
+       
+       res_2 = res*res;
+       res_3 = res*res*res;
+
+       for (x=0; x < res; x++) {
+               for (y=0; y < res; y++) {
+                       for (z=0; z < res; z++) {
+                               for (rgb=0; rgb < 3; rgb++) {
+                                       i = rgb*res_3 + x*res_2 + y*res + z;
+
+                                       /* trigger for outside mesh */
+                                       if (cache[i] < 0.5f) cache[i] = 
get_avg_surrounds(cache, res, res_2, res_3, rgb, x, y, z);
+                               }
+                       }
+               }
+       }
+}
+
 /* Precache a volume into a 3D voxel grid.
  * The voxel grid is stored in the ObjectInstanceRen, 
  * in camera space, aligned with the ObjectRen's bounding box.
@@ -941,9 +995,12 @@
                                }
                                
                                /* don't bother if the point is not inside the 
volume mesh */
-                               if (!point_inside_obi(tree, obi, co))
+                               if (!point_inside_obi(tree, obi, co)) {
+                                       obi->volume_precache[0*res_3 + x*res_2 
+ y*res + z] = -1.0f;
+                                       obi->volume_precache[1*res_3 + x*res_2 
+ y*res + z] = -1.0f;
+                                       obi->volume_precache[2*res_3 + x*res_2 
+ y*res + z] = -1.0f;
                                        continue;
-
+                               }
                                density = vol_get_density(&shi, co);
                                vol_get_scattering(&shi, scatter_col, co, 
stepsize, density);
                        
@@ -959,6 +1016,7 @@
                tree= NULL;
        }
        
+       lightcache_filter(obi->volume_precache, res);
 
 }
 
@@ -990,4 +1048,5 @@
        }
        
        BLI_freelistN(&re->vol_precache_obs);
-}
\ No newline at end of file
+}
+


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to