[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [25693] trunk/blender/source/blender: Patch from Raul Fernandez Hernandez - volume render multiple scattering fixes

Matt Ebb matt at mke3.net
Mon Jan 4 00:45:24 CET 2010


Revision: 25693
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=25693
Author:   broken
Date:     2010-01-04 00:45:13 +0100 (Mon, 04 Jan 2010)

Log Message:
-----------
Patch from Raul Fernandez Hernandez - volume render multiple scattering fixes

Also: Changed 'Spread' value to be proportional to the light cache voxel grid 
(i.e. 0.5 spreads half the width of the grid), so that it's independent of light 
cache resolution. This means that results should be similar as you increase/
decrease resolution.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/material.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/makesdna/DNA_material_types.h
    trunk/blender/source/blender/makesrna/intern/rna_material.c
    trunk/blender/source/blender/render/intern/source/volume_precache.c
    trunk/blender/source/blender/render/intern/source/volumetric.c

Modified: trunk/blender/source/blender/blenkernel/intern/material.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/material.c	2010-01-03 20:35:13 UTC (rev 25692)
+++ trunk/blender/source/blender/blenkernel/intern/material.c	2010-01-03 23:45:13 UTC (rev 25693)
@@ -184,6 +184,9 @@
 	ma->vol.shade_type = MA_VOL_SHADE_SHADED;
 	ma->vol.shadeflag |= MA_VOL_PRECACHESHADING;
 	ma->vol.precache_resolution = 50;
+	ma->vol.ms_spread = 0.2f;
+	ma->vol.ms_diff = 1.f;
+	ma->vol.ms_intensity = 1.f;
 	
 	ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RAYBIAS|MA_TANGENT_STR|MA_ZTRANSP;
 

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2010-01-03 20:35:13 UTC (rev 25692)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2010-01-03 23:45:13 UTC (rev 25693)
@@ -10324,6 +10324,7 @@
 		Scene *sce;
 		Object *ob;
 		Brush *brush;
+		Material *ma;
 		
 		/* game engine changes */
 		for(sce = main->scene.first; sce; sce = sce->id.next) {
@@ -10386,6 +10387,15 @@
 		for (brush= main->brush.first; brush; brush= brush->id.next) {
 			default_mtex(&brush->mtex);
 		}
+
+		for (ma= main->mat.first; ma; ma= ma->id.next) {
+			if (ma->vol.ms_spread < 0.0001f) {
+				ma->vol.ms_spread = 0.2f;
+				ma->vol.ms_diff = 1.f;
+				ma->vol.ms_intensity = 1.f;	
+			}
+		}
+		
 	}
 
 	/* WATCH IT!!!: pointers from libdata have not been converted yet here! */

Modified: trunk/blender/source/blender/makesdna/DNA_material_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_material_types.h	2010-01-03 20:35:13 UTC (rev 25692)
+++ trunk/blender/source/blender/makesdna/DNA_material_types.h	2010-01-03 23:45:13 UTC (rev 25693)
@@ -69,7 +69,7 @@
 	float stepsize;
 	float ms_diff;
 	float ms_intensity;
-	int ms_steps;
+	float ms_spread;
 } VolumeSettings;
 
 typedef struct Material {

Modified: trunk/blender/source/blender/makesrna/intern/rna_material.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_material.c	2010-01-03 20:35:13 UTC (rev 25692)
+++ trunk/blender/source/blender/makesrna/intern/rna_material.c	2010-01-03 23:45:13 UTC (rev 25693)
@@ -1023,10 +1023,11 @@
 	RNA_def_property_ui_text(prop, "Diffusion", "Diffusion factor, the strength of the blurring effect");
 	RNA_def_property_update(prop, 0, "rna_Material_update");
 	
-	prop= RNA_def_property(srna, "ms_spread", PROP_INT, PROP_NONE);
-	RNA_def_property_int_sdna(prop, NULL, "ms_steps");
-	RNA_def_property_range(prop, 0, 1024);
-	RNA_def_property_ui_text(prop, "Spread", "Simulation steps, the effective distance over which the light is diffused");
+	prop= RNA_def_property(srna, "ms_spread", PROP_FLOAT, PROP_NONE);
+	RNA_def_property_float_sdna(prop, NULL, "ms_spread");
+	RNA_def_property_range(prop, 0, FLT_MAX);
+	RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 3);
+	RNA_def_property_ui_text(prop, "Spread", "Proportional distance over which the light is diffused");
 	RNA_def_property_update(prop, 0, "rna_Material_update");
 	
 	prop= RNA_def_property(srna, "ms_intensity", PROP_FLOAT, PROP_NONE);

Modified: trunk/blender/source/blender/render/intern/source/volume_precache.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/volume_precache.c	2010-01-03 20:35:13 UTC (rev 25692)
+++ trunk/blender/source/blender/render/intern/source/volume_precache.c	2010-01-03 23:45:13 UTC (rev 25693)
@@ -21,7 +21,7 @@
  *
  * The Original Code is: all of this file.
  *
- * Contributor(s): Matt Ebb.
+ * Contributor(s): Matt Ebb, Ra˙l Fern·ndez Hern·ndez (Farsthary).
  *
  * ***** END GPL LICENSE BLOCK *****
  */
@@ -134,9 +134,10 @@
 					for (x=-1; x <= 1; x++) {
 						x_ = xx+x;
 						if (x_ >= 0 && x_ <= res[0]-1) {
-						
-							if (cache[ V_I(x_, y_, z_, res) ] > 0.0f) {
-								tot += cache[ V_I(x_, y_, z_, res) ];
+							const int i= V_I(x_, y_, z_, res);
+							
+							if (cache[i] > 0.0f) {
+								tot += cache[i];
 								added++;
 							}
 							
@@ -164,12 +165,14 @@
 		for (y=0; y < vp->res[1]; y++) {
 			for (x=0; x < vp->res[0]; x++) {
 				/* trigger for outside mesh */
-				if (vp->data_r[ V_I(x, y, z, vp->res) ] < -0.f)
-					vp->data_r[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
-				if (vp->data_g[ V_I(x, y, z, vp->res) ] < -0.f)
-					vp->data_g[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
-				if (vp->data_b[ V_I(x, y, z, vp->res) ] < -0.f)
-					vp->data_b[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
+				const int i= V_I(x, y, z, vp->res);
+				
+				if (vp->data_r[i] < -0.f)
+					vp->data_r[i] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
+				if (vp->data_g[i] < -0.f)
+					vp->data_g[i] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
+				if (vp->data_b[i] < -0.f)
+					vp->data_b[i] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
 			}
 		}
 	}
@@ -194,12 +197,13 @@
 		for (y=0; y < vp->res[1]; y++) {
 			for (x=0; x < vp->res[0]; x++) {
 				/* trigger for outside mesh */
-				if (vp->data_r[ V_I(x, y, z, vp->res) ] < -0.f)
-					new_r[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
-				if (vp->data_g[ V_I(x, y, z, vp->res) ] < -0.f)
-					new_g[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
-				if (vp->data_b[ V_I(x, y, z, vp->res) ] < -0.f)
-					new_b[ V_I(x, y, z, vp->res) ] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
+				const int i= V_I(x, y, z, vp->res);
+				if (vp->data_r[i] < -0.f)
+					new_r[i] = get_avg_surrounds(vp->data_r, vp->res, x, y, z);
+				if (vp->data_g[i] < -0.f)
+					new_g[i] = get_avg_surrounds(vp->data_g, vp->res, x, y, z);
+				if (vp->data_b[i] < -0.f)
+					new_b[i] = get_avg_surrounds(vp->data_b, vp->res, x, y, z);
 			}
 		}
 	}
@@ -216,10 +220,22 @@
 
 static inline int ms_I(int x, int y, int z, int *n) //has a pad of 1 voxel surrounding the core for boundary simulation
 { 
-	return z*(n[1]+2)*(n[0]+2) + y*(n[0]+2) + x;
+	/* different ordering to light cache */
+	return x*(n[1]+2)*(n[2]+2) + y*(n[2]+2) + z; 	
 }
 
+static inline int v_I_pad(int x, int y, int z, int *n) //has a pad of 1 voxel surrounding the core for boundary simulation
+{ 
+	/* same ordering to light cache, with padding */
+	return z*(n[1]+2)*(n[0]+2) + y*(n[0]+2) + x;  	
+}
 
+static inline int lc_to_ms_I(int x, int y, int z, int *n)
+{ 
+	/* converting light cache index to multiple scattering index */
+	return (x-1)*(n[1]*n[2]) + (y-1)*(n[2]) + z-1;
+}
+
 /* *** multiple scattering approximation *** */
 
 /* get the total amount of light energy in the light cache. used to normalise after multiple scattering */
@@ -232,9 +248,11 @@
 	for (z=0; z < res[2]; z++) {
 		for (y=0; y < res[1]; y++) {
 			for (x=0; x < res[0]; x++) {
-				if (vp->data_r[ V_I(x, y, z, res) ] > 0.f) energy += vp->data_r[ V_I(x, y, z, res) ];
-				if (vp->data_g[ V_I(x, y, z, res) ] > 0.f) energy += vp->data_g[ V_I(x, y, z, res) ];
-				if (vp->data_b[ V_I(x, y, z, res) ] > 0.f) energy += vp->data_b[ V_I(x, y, z, res) ];
+				const int i=V_I(x, y, z, res);
+			
+				if (vp->data_r[i] > 0.f) energy += vp->data_r[i];
+				if (vp->data_g[i] > 0.f) energy += vp->data_g[i];
+				if (vp->data_b[i] > 0.f) energy += vp->data_b[i];
 			}
 		}
 	}
@@ -244,14 +262,14 @@
 
 static float total_ms_energy(float *sr, float *sg, float *sb, int *res)
 {
-	int x, y, z, i;
+	int x, y, z;
 	float energy=0.f;
 	
 	for (z=1;z<=res[2];z++) {
 		for (y=1;y<=res[1];y++) {
 			for (x=1;x<=res[0];x++) {
-			
-				i = ms_I(x,y,z,res);
+				const int i = ms_I(x,y,z,res);
+				
 				if (sr[i] > 0.f) energy += sr[i];
 				if (sg[i] > 0.f) energy += sg[i];
 				if (sb[i] > 0.f) energy += sb[i];
@@ -262,7 +280,7 @@
 	return energy;
 }
 
-static void ms_diffuse(int b, float* x0, float* x, float diff, int *n)
+static void ms_diffuse(float *x0, float *x, float diff, int *n) //n is the unpadded resolution
 {
 	int i, j, k, l;
 	const float dt = VOL_MS_TIMESTEP;
@@ -276,10 +294,9 @@
 			{
 				for (i=1; i<=n[0]; i++)
 				{
-					x[ms_I(i,j,k,n)] = (x0[ms_I(i,j,k,n)] + a*(
-						 x[ms_I(i-1,j,k,n)]+x[ms_I(i+1,j,k,n)]+
-						 x[ms_I(i,j-1,k,n)]+x[ms_I(i,j+1,k,n)]+
-						 x[ms_I(i,j,k-1,n)]+x[ms_I(i,j,k+1,n)]))/(1+6*a);
+				   x[v_I_pad(i,j,k,n)] = (x0[v_I_pad(i,j,k,n)]) + a*(	x0[v_I_pad(i-1,j,k,n)]+ x0[v_I_pad(i+1,j,k,n)]+ x0[v_I_pad(i,j-1,k,n)]+
+																		x0[v_I_pad(i,j+1,k,n)]+ x0[v_I_pad(i,j,k-1,n)]+x0[v_I_pad(i,j,k+1,n)]
+																		) / (1+6*a);
 				}
 			}
 		}
@@ -289,7 +306,7 @@
 void multiple_scattering_diffusion(Render *re, VolumePrecache *vp, Material *ma)
 {
 	const float diff = ma->vol.ms_diff * 0.001f; 	/* compensate for scaling for a nicer UI range */
-	const float simframes = ma->vol.ms_steps;
+	const int simframes = (int)(ma->vol.ms_spread * (float)MAX3(vp->res[0], vp->res[1], vp->res[2]));
 	const int shade_type = ma->vol.shade_type;
 	float fac = ma->vol.ms_intensity;
 	
@@ -299,7 +316,6 @@
 	double time, lasttime= PIL_check_seconds_timer();
 	float total;
 	float c=1.0f;
-	int i;
 	float origf;	/* factor for blending in original light cache */
 	float energy_ss, energy_ms;
 
@@ -324,22 +340,22 @@
 			{
 				for (x=1; x<=n[0]; x++)
 				{
-					i = V_I((x-1), (y-1), (z-1), n);
+					const int i = lc_to_ms_I(x, y ,z, n);	//lc index					
+					const int j = ms_I(x, y, z, n);			//ms index
+					
 					time= PIL_check_seconds_timer();
-					c++;
-										
-					if (vp->data_r[i] > 0.f)
-						sr[ms_I(x,y,z,n)] += vp->data_r[i];
-					if (vp->data_g[i] > 0.f)
-						sg[ms_I(x,y,z,n)] += vp->data_g[i];
-					if (vp->data_b[i] > 0.f)
-						sb[ms_I(x,y,z,n)] += vp->data_b[i];
+					c++;										
+					if (vp->data_r[i] > 0.0f)
+						sr[j] += vp->data_r[i];
+					if (vp->data_g[i] > 0.0f)
+						sg[j] += vp->data_g[i];
+					if (vp->data_b[i] > 0.0f)
+						sb[j] += vp->data_b[i];
 					
 					/* Displays progress every second */
 					if(time-lasttime>1.0f) {
 						char str[64];
-						sprintf(str, "Simulating multiple scattering: %d%%", (int)
-								(100.0f * (c / total)));
+						sprintf(str, "Simulating multiple scattering: %d%%", (int)(100.0f * (c / total)));
 						re->i.infostr= str;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list