[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [30630] trunk/blender/source/blender/ render/intern: Fix for volume render light cache:

Matt Ebb matt at mke3.net
Thu Jul 22 13:54:12 CEST 2010


Revision: 30630
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=30630
Author:   broken
Date:     2010-07-22 13:54:12 +0200 (Thu, 22 Jul 2010)

Log Message:
-----------
Fix for volume render light cache:

Now the bounding box for the light cache's voxel grid is calculated in 
global space, rather than camera space as it was previously. This fixes
flickering lighting on static volumes with camera motion, caused by
the camera space bounding box changing from frame to frame. 

Modified Paths:
--------------
    trunk/blender/source/blender/render/intern/include/render_types.h
    trunk/blender/source/blender/render/intern/include/volume_precache.h
    trunk/blender/source/blender/render/intern/source/volume_precache.c
    trunk/blender/source/blender/render/intern/source/volumetric.c

Modified: trunk/blender/source/blender/render/intern/include/render_types.h
===================================================================
--- trunk/blender/source/blender/render/intern/include/render_types.h	2010-07-22 11:27:54 UTC (rev 30629)
+++ trunk/blender/source/blender/render/intern/include/render_types.h	2010-07-22 11:54:12 UTC (rev 30630)
@@ -464,6 +464,7 @@
 	struct RayObject *tree;
 	struct ShadeInput *shi;
 	struct ObjectInstanceRen *obi;
+	float viewmat[4][4];
 	int num;
 	int minx, maxx;
 	int miny, maxy;
@@ -477,6 +478,7 @@
 typedef struct VolumePrecache
 {
 	int res[3];
+	float *bbmin, *bbmax;
 	float *data_r;
 	float *data_g;
 	float *data_b;

Modified: trunk/blender/source/blender/render/intern/include/volume_precache.h
===================================================================
--- trunk/blender/source/blender/render/intern/include/volume_precache.h	2010-07-22 11:27:54 UTC (rev 30629)
+++ trunk/blender/source/blender/render/intern/include/volume_precache.h	2010-07-22 11:54:12 UTC (rev 30630)
@@ -25,9 +25,11 @@
  *
  * ***** END GPL LICENSE BLOCK *****
  */
- 
+
+void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float *bbmin, float *bbmax);
+int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co);
+
 void volume_precache(Render *re);
 void free_volume_precache(Render *re);
-int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co);
 
 #define VOL_MS_TIMESTEP	0.1f

Modified: trunk/blender/source/blender/render/intern/source/volume_precache.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/volume_precache.c	2010-07-22 11:27:54 UTC (rev 30629)
+++ trunk/blender/source/blender/render/intern/source/volume_precache.c	2010-07-22 11:54:12 UTC (rev 30630)
@@ -115,6 +115,47 @@
 	else return 1;
 }
 
+/* find the bounding box of an objectinstance in global space */
+void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float *bbmin, float *bbmax)
+{
+	ObjectRen *obr = obi->obr;
+	VolumePrecache *vp = obi->volume_precache;
+	VertRen *ver= NULL;
+	float co[3];
+	int a;
+	
+	if (vp->bbmin != NULL && vp->bbmax != NULL) {
+		copy_v3_v3(bbmin, vp->bbmin);
+		copy_v3_v3(bbmax, vp->bbmax);
+		return;
+	}
+	
+	vp->bbmin = MEM_callocN(sizeof(float)*3, "volume precache min boundbox corner");
+	vp->bbmax = MEM_callocN(sizeof(float)*3, "volume precache max boundbox corner");
+	
+	INIT_MINMAX(bbmin, bbmax);
+	
+	for(a=0; a<obr->totvert; a++) {
+		if((a & 255)==0) ver= obr->vertnodes[a>>8].vert;
+		else ver++;
+		
+		copy_v3_v3(co, ver->co);
+		
+		/* transformed object instance in camera space */
+		if(obi->flag & R_TRANSFORMED)
+			mul_m4_v3(obi->mat, co);
+		
+		/* convert to global space */
+		mul_m4_v3(re->viewinv, co);
+		
+		DO_MINMAX(co, vp->bbmin, vp->bbmax);
+	}
+	
+	copy_v3_v3(bbmin, vp->bbmin);
+	copy_v3_v3(bbmax, vp->bbmax);
+	
+}
+
 /* *** light cache filtering *** */
 
 static float get_avg_surrounds(float *cache, int *res, int xx, int yy, int zz)
@@ -443,7 +484,7 @@
 	RayObject *tree = pa->tree;
 	ShadeInput *shi = pa->shi;
 	float scatter_col[3] = {0.f, 0.f, 0.f};
-	float co[3];
+	float co[3], cco[3];
 	int x, y, z, i;
 	const int res[3]= {pa->res[0], pa->res[1], pa->res[2]};
 
@@ -455,24 +496,29 @@
 			
 			for (x=pa->minx; x < pa->maxx; x++) {
 				co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f));
-							
+				
+				/* convert from world->camera space for shading */
+				mul_v3_m4v3(cco, pa->viewmat, co);
+				
 				i= V_I(x, y, z, res);
 				
 				// 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, cco)) {
 					obi->volume_precache->data_r[i] = -1.0f;
 					obi->volume_precache->data_g[i] = -1.0f;
 					obi->volume_precache->data_b[i] = -1.0f;
 					continue;
 				}
 				
-				copy_v3_v3(shi->view, co);
+				/* this view coordinate is very wrong! */
+				copy_v3_v3(shi->view, cco);
 				normalize_v3(shi->view);
-				vol_get_scattering(shi, scatter_col, co);
+				vol_get_scattering(shi, scatter_col, cco);
 			
 				obi->volume_precache->data_r[i] = scatter_col[0];
 				obi->volume_precache->data_g[i] = scatter_col[1];
 				obi->volume_precache->data_b[i] = scatter_col[2];
+				
 			}
 		}
 	}
@@ -503,7 +549,7 @@
 	int i=0, x, y, z;
 	float voxel[3];
 	int sizex, sizey, sizez;
-	float *bbmin=obi->obr->boundbox[0], *bbmax=obi->obr->boundbox[1];
+	float bbmin[3], bbmax[3];
 	int *res;
 	int minx, maxx;
 	int miny, maxy;
@@ -517,11 +563,13 @@
 	parts[0] = parts[1] = parts[2] = totthread;
 	res = vp->res;
 	
+	/* using boundbox in worldspace */
+	global_bounds_obi(re, obi, bbmin, bbmax);
 	sub_v3_v3v3(voxel, bbmax, bbmin);
 	
-	voxel[0] /= res[0];
-	voxel[1] /= res[1];
-	voxel[2] /= res[2];
+	voxel[0] /= (float)res[0];
+	voxel[1] /= (float)res[1];
+	voxel[2] /= (float)res[2];
 
 	for (x=0; x < parts[0]; x++) {
 		sizex = ceil(res[0] / (float)parts[0]);
@@ -550,8 +598,10 @@
 				pa->tree = tree;
 				pa->shi = shi;
 				pa->obi = obi;
-				VECCOPY(pa->bbmin, bbmin);
-				VECCOPY(pa->voxel, voxel);
+				copy_m4_m4(pa->viewmat, re->viewmat);
+				
+				copy_v3_v3(pa->bbmin, bbmin);
+				copy_v3_v3(pa->voxel, voxel);
 				VECCOPY(pa->res, res);
 				
 				pa->minx = minx; pa->maxx = maxx;
@@ -582,10 +632,14 @@
 	return nextpa;
 }
 
-static int precache_resolution(VolumePrecache *vp, float *bbmin, float *bbmax, int res)
+/* calculate resolution from bounding box in world space */
+static int precache_resolution(Render *re, VolumePrecache *vp, ObjectInstanceRen *obi, int res)
 {
 	float dim[3], div;
+	float bbmin[3], bbmax[3];
 	
+	/* bound box in global space */
+	global_bounds_obi(re, obi, bbmin, bbmax);
 	sub_v3_v3v3(dim, bbmax, bbmin);
 	
 	div = MAX3(dim[0], dim[1], dim[2]);
@@ -593,9 +647,9 @@
 	dim[1] /= div;
 	dim[2] /= div;
 	
-	vp->res[0] = dim[0] * (float)res;
-	vp->res[1] = dim[1] * (float)res;
-	vp->res[2] = dim[2] * (float)res;
+	vp->res[0] = ceil(dim[0] * res);
+	vp->res[1] = ceil(dim[1] * res);
+	vp->res[2] = ceil(dim[2] * res);
 	
 	if ((vp->res[0] < 1) || (vp->res[1] < 1) || (vp->res[2] < 1))
 		return 0;
@@ -615,7 +669,6 @@
 	RayObject *tree;
 	ShadeInput shi;
 	ListBase threads;
-	float *bbmin=obi->obr->boundbox[0], *bbmax=obi->obr->boundbox[1];
 	int parts[3] = {1, 1, 1}, totparts;
 	
 	int caching=1, counter=0;
@@ -627,15 +680,13 @@
 
 	/* create a raytree with just the faces of the instanced ObjectRen, 
 	 * used for checking if the cached point is inside or outside. */
-	//tree = create_raytree_obi(obi, bbmin, bbmax);
 	tree = makeraytree_object(&R, obi);
 	if (!tree) return;
-	INIT_MINMAX(bbmin, bbmax);
-	RE_rayobject_merge_bb( tree, bbmin, bbmax);
 
 	vp = MEM_callocN(sizeof(VolumePrecache), "volume light cache");
+	obi->volume_precache = vp;
 	
-	if (!precache_resolution(vp, bbmin, bbmax, ma->vol.precache_resolution)) {
+	if (!precache_resolution(re, vp, obi, ma->vol.precache_resolution)) {
 		MEM_freeN(vp);
 		vp = NULL;
 		return;
@@ -649,7 +700,7 @@
 		vp = NULL;
 		return;
 	}
-	obi->volume_precache = vp;
+	//obi->volume_precache = vp;
 
 	/* Need a shadeinput to calculate scattering */
 	precache_setup_shadeinput(re, obi, ma, &shi);
@@ -749,6 +800,8 @@
 			MEM_freeN(obi->volume_precache->data_r);
 			MEM_freeN(obi->volume_precache->data_g);
 			MEM_freeN(obi->volume_precache->data_b);
+			MEM_freeN(obi->volume_precache->bbmin);
+			MEM_freeN(obi->volume_precache->bbmax);
 			MEM_freeN(obi->volume_precache);
 			obi->volume_precache = NULL;
 		}

Modified: trunk/blender/source/blender/render/intern/source/volumetric.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/volumetric.c	2010-07-22 11:27:54 UTC (rev 30629)
+++ trunk/blender/source/blender/render/intern/source/volumetric.c	2010-07-22 11:54:12 UTC (rev 30630)
@@ -205,7 +205,7 @@
 	} else {
 		shadeSkyView(col, co, shi->view, NULL, shi->thread);
 		shadeSunView(col, shi->view);
-	}
+	} 
 }
 
 
@@ -214,18 +214,19 @@
 {
 	VolumePrecache *vp = shi->obi->volume_precache;
 	float bbmin[3], bbmax[3], dim[3];
-	float sample_co[3];
+	float world_co[3], sample_co[3];
 	
 	if (!vp) return;
 	
-	/* convert input coords to 0.0, 1.0 */
-	VECCOPY(bbmin, shi->obi->obr->boundbox[0]);
-	VECCOPY(bbmax, shi->obi->obr->boundbox[1]);
+	/* find sample point in global space bounding box 0.0-1.0 */
+	global_bounds_obi(re, shi->obi, bbmin, bbmax);
 	sub_v3_v3v3(dim, bbmax, bbmin);
+	mul_v3_m4v3(world_co, re->viewinv, co);	
 
-	sample_co[0] = ((co[0] - bbmin[0]) / dim[0]);
-	sample_co[1] = ((co[1] - bbmin[1]) / dim[1]);
-	sample_co[2] = ((co[2] - bbmin[2]) / dim[2]);
+	/* sample_co in 0.0-1.0 */
+	sample_co[0] = (world_co[0] - bbmin[0]) / dim[0];
+	sample_co[1] = (world_co[1] - bbmin[1]) / dim[1];
+	sample_co[2] = (world_co[2] - bbmin[2]) / dim[2];
 
 	scatter_col[0] = voxel_sample_triquadratic(vp->data_r, vp->res, sample_co);
 	scatter_col[1] = voxel_sample_triquadratic(vp->data_g, vp->res, sample_co);
@@ -602,7 +603,7 @@
 		const float density = vol_get_density(shi, p);
 		
 		if (density > 0.01f) {
-			float scatter_col[3], emit_col[3];
+			float scatter_col[3] = {0.f, 0.f, 0.f}, emit_col[3];
 			const float stepd = (t0 - pt0) * density;
 			
 			/* transmittance component (alpha) */
@@ -619,7 +620,7 @@
 				p2[1] = p[1] + (step_vec[1] * 0.5);
 				p2[2] = p[2] + (step_vec[2] * 0.5);
 				
-				vol_get_precached_scattering(shi, scatter_col, p2);
+				vol_get_precached_scattering(&R, shi, scatter_col, p2);
 			} else
 				vol_get_scattering(shi, scatter_col, p);
 			





More information about the Bf-blender-cvs mailing list