[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17193] branches/sim_physics/source/ blender/render/intern/source/volumetric.c: * More improvements for light cache

Matt Ebb matt at mke3.net
Thu Oct 23 05:50:56 CEST 2008


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
+}
+





More information about the Bf-blender-cvs mailing list