[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23059] branches/blender2.5/blender/source /blender/render/intern/source: * Volume render weaks/fixes/etc from Alfredo , after code review

Matt Ebb matt at mke3.net
Tue Sep 8 10:15:56 CEST 2009


Revision: 23059
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23059
Author:   broken
Date:     2009-09-08 10:15:56 +0200 (Tue, 08 Sep 2009)

Log Message:
-----------
* Volume render weaks/fixes/etc from Alfredo, after code review

- General correctness tweaks
- Light cache is enabled for all objects now
- Metaballs now give density info, for smooth falloff

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/render/intern/source/convertblender.c
    branches/blender2.5/blender/source/blender/render/intern/source/volume_precache.c
    branches/blender2.5/blender/source/blender/render/intern/source/volumetric.c

Modified: branches/blender2.5/blender/source/blender/render/intern/source/convertblender.c
===================================================================
--- branches/blender2.5/blender/source/blender/render/intern/source/convertblender.c	2009-09-08 07:35:07 UTC (rev 23058)
+++ branches/blender2.5/blender/source/blender/render/intern/source/convertblender.c	2009-09-08 08:15:56 UTC (rev 23059)
@@ -3078,9 +3078,6 @@
 				}
 				need_nmap_tangent= 1;
 			}
-			
-			if (ma->material_type == MA_TYPE_VOLUME)
-				add_volume(re, obr, ma);
 		}
 	}
 
@@ -4273,7 +4270,7 @@
 	ObjectRen *obr;
 	ObjectInstanceRen *obi;
 	ParticleSystem *psys;
-	int show_emitter, allow_render= 1, index, psysindex;
+	int show_emitter, allow_render= 1, index, psysindex, i;
 
 	index= (dob)? dob->index: 0;
 
@@ -4309,6 +4306,12 @@
 		}
 		else
 			find_dupli_instances(re, obr);
+			
+		for (i=1; i<=ob->totcol; i++) {
+			Material* ma = give_render_material(re, ob, i);
+			if (ma && ma->material_type == MA_TYPE_VOLUME)
+				add_volume(re, obr, ma);
+		}
 	}
 
 	/* and one render object per particle system */

Modified: branches/blender2.5/blender/source/blender/render/intern/source/volume_precache.c
===================================================================
--- branches/blender2.5/blender/source/blender/render/intern/source/volume_precache.c	2009-09-08 07:35:07 UTC (rev 23058)
+++ branches/blender2.5/blender/source/blender/render/intern/source/volume_precache.c	2009-09-08 08:15:56 UTC (rev 23059)
@@ -430,13 +430,13 @@
 	const float stepsize = vol_get_stepsize(shi, STEPSIZE_VIEW);
 
 	for (z= pa->minz; z < pa->maxz; z++) {
-		co[2] = pa->bbmin[2] + (pa->voxel[2] * z);
+		co[2] = pa->bbmin[2] + (pa->voxel[2] * (z + 0.5f));
 		
 		for (y= pa->miny; y < pa->maxy; y++) {
-			co[1] = pa->bbmin[1] + (pa->voxel[1] * y);
+			co[1] = pa->bbmin[1] + (pa->voxel[1] * (y + 0.5f));
 			
 			for (x=pa->minx; x < pa->maxx; x++) {
-				co[0] = pa->bbmin[0] + (pa->voxel[0] * x);
+				co[0] = pa->bbmin[0] + (pa->voxel[0] * (x + 0.5f));
 				
 				// don't bother if the point is not inside the volume mesh
 				if (!point_inside_obi(tree, obi, co)) {

Modified: branches/blender2.5/blender/source/blender/render/intern/source/volumetric.c
===================================================================
--- branches/blender2.5/blender/source/blender/render/intern/source/volumetric.c	2009-09-08 07:35:07 UTC (rev 23058)
+++ branches/blender2.5/blender/source/blender/render/intern/source/volumetric.c	2009-09-08 08:15:56 UTC (rev 23059)
@@ -44,6 +44,7 @@
 #include "DNA_material_types.h"
 #include "DNA_group_types.h"
 #include "DNA_lamp_types.h"
+#include "DNA_meta_types.h"
 
 #include "BKE_global.h"
 
@@ -64,6 +65,11 @@
 extern struct Render R;
 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
+/* luminance rec. 709 */
+inline float luminance(float* col)
+{
+	return (0.212671f*col[0] + 0.71516f*col[1] + 0.072169f*col[2]);
+}
 
 /* tracing */
 
@@ -211,13 +217,66 @@
 	scatter_col[2] = voxel_sample_trilinear(vp->data_b, vp->res, sample_co);
 }
 
+/* Meta object density, brute force for now 
+ * (might be good enough anyway, don't need huge number of metaobs to model volumetric objects */
+static float metadensity(Object* ob, float* co)
+{
+	float mat[4][4], imat[4][4], dens = 0.f;
+	MetaBall* mb = (MetaBall*)ob->data;
+	MetaElem* ml;
+	
+	/* transform co to meta-element */
+	float tco[3] = {co[0], co[1], co[2]};
+	Mat4MulMat4(mat, ob->obmat, R.viewmat);
+	Mat4Invert(imat, mat);
+	Mat4MulVecfl(imat, tco);
+	
+	for (ml = mb->elems.first; ml; ml=ml->next) {
+		float bmat[3][3], dist2;
+		
+		/* element rotation transform */
+		float tp[3] = {ml->x - tco[0], ml->y - tco[1], ml->z - tco[2]};
+		QuatToMat3(ml->quat, bmat);
+		Mat3Transp(bmat);	// rot.only, so inverse == transpose
+		Mat3MulVecfl(bmat, tp);
+		
+		/* MB_BALL default */
+		switch (ml->type) {
+			case MB_ELIPSOID:
+				tp[0] /= ml->expx, tp[1] /= ml->expy, tp[2] /= ml->expz;
+				break;
+			case MB_CUBE:
+				tp[2] = (tp[2] > ml->expz) ? (tp[2] - ml->expz) : ((tp[2] < -ml->expz) ? (tp[2] + ml->expz) : 0.f);
+				// no break, xy as plane
+			case MB_PLANE:
+				tp[1] = (tp[1] > ml->expy) ? (tp[1] - ml->expy) : ((tp[1] < -ml->expy) ? (tp[1] + ml->expy) : 0.f);
+				// no break, x as tube
+			case MB_TUBE:
+				tp[0] = (tp[0] > ml->expx) ? (tp[0] - ml->expx) : ((tp[0] < -ml->expx) ? (tp[0] + ml->expx) : 0.f);
+		}
+		
+		/* ml->rad2 is not set */
+		dist2 = 1.f - ((tp[0]*tp[0] + tp[1]*tp[1] + tp[2]*tp[2]) / (ml->rad*ml->rad));
+		if (dist2 > 0.f)
+			dens += (ml->flag & MB_NEGATIVE) ? -ml->s*dist2*dist2*dist2 : ml->s*dist2*dist2*dist2;
+	}
+	
+	dens -= mb->thresh;
+	return (dens < 0.f) ? 0.f : dens;
+}
+
 float vol_get_density(struct ShadeInput *shi, float *co)
 {
 	float density = shi->mat->vol.density;
 	float density_scale = shi->mat->vol.density_scale;
-	float col[3] = {0.0, 0.0, 0.0};
+		
+	do_volume_tex(shi, co, MAP_DENSITY, NULL, &density);
 	
-	do_volume_tex(shi, co, MAP_DENSITY, col, &density);
+	// if meta-object, modulate by metadensity without increasing it
+	if (shi->obi->obr->ob->type == OB_MBALL) {
+		const float md = metadensity(shi->obi->obr->ob, co);
+		if (md < 1.f) density *= md;
+ 	}
 	
 	return density * density_scale;
 }
@@ -260,7 +319,6 @@
 	absorb_col[2] = (1.0f - absorb_col[2]) * absorption;
 }
 
-
 /* phase function - determines in which directions the light 
  * is scattered in the volume relative to incoming direction 
  * and view direction */
@@ -298,70 +356,66 @@
 	}
 }
 
-/* Compute attenuation, otherwise known as 'optical thickness', extinction, or tau.
- * Used in the relationship Transmittance = e^(-attenuation)
- */
-void vol_get_attenuation_seg(ShadeInput *shi, float *transmission, float stepsize, float *co, float density)
+/* Compute transmittance = e^(-attenuation) */
+void vol_get_transmittance_seg(ShadeInput *shi, float *tr, float stepsize, float *co, float density)
 {
 	/* input density = density at co */
 	float tau[3] = {0.f, 0.f, 0.f};
-	float absorb_col[3];
+	float absorb[3];
+	const float scatter_dens = vol_get_scattering_fac(shi, co) * density * stepsize;
 
-	vol_get_absorption(shi, absorb_col, co);
+	vol_get_absorption(shi, absorb, co);
 	
 	/* homogenous volume within the sampled distance */
-	tau[0] = stepsize * density * absorb_col[0];
-	tau[1] = stepsize * density * absorb_col[1];
-	tau[2] = stepsize * density * absorb_col[2];
+	tau[0] += scatter_dens * absorb[0];
+	tau[1] += scatter_dens * absorb[1];
+	tau[2] += scatter_dens * absorb[2];
 	
-	transmission[0] *= exp(-tau[0]);
-	transmission[1] *= exp(-tau[1]);
-	transmission[2] *= exp(-tau[2]);
+	tr[0] *= exp(-tau[0]);
+	tr[1] *= exp(-tau[1]);
+	tr[2] *= exp(-tau[2]);
 }
 
-/* Compute attenuation, otherwise known as 'optical thickness', extinction, or tau.
- * Used in the relationship Transmittance = e^(-attenuation)
- */
-void vol_get_attenuation(ShadeInput *shi, float *transmission, float *co, float *endco, float density, float stepsize)
+/* Compute transmittance = e^(-attenuation) */
+static void vol_get_transmittance(ShadeInput *shi, float *tr, float *co, float *endco)
 {
-	/* input density = density at co */
+	float p[3] = {co[0], co[1], co[2]};
+	float step_vec[3] = {endco[0] - co[0], endco[1] - co[1], endco[2] - co[2]};
+	//const float ambtau = -logf(shi->mat->vol.depth_cutoff);	// never zero
 	float tau[3] = {0.f, 0.f, 0.f};
-	float absorb_col[3];
-	int s, nsteps;
-	float step_vec[3], step_sta[3], step_end[3];
-	const float dist = VecLenf(co, endco);
 
-	vol_get_absorption(shi, absorb_col, co);
+	float t0 = 0.f;
+	float t1 = Normalize(step_vec);
+	float pt0 = t0;
+	
+	t0 += shi->mat->vol.shade_stepsize * ((shi->mat->vol.stepsize_type == MA_VOL_STEP_CONSTANT) ? 0.5f : BLI_thread_frand(shi->thread));
+	p[0] += t0 * step_vec[0];
+	p[1] += t0 * step_vec[1];
+	p[2] += t0 * step_vec[2];
+	VecMulf(step_vec, shi->mat->vol.shade_stepsize);
 
-	nsteps = (int)((dist / stepsize) + 0.5);
-	
-	VecSubf(step_vec, endco, co);
-	VecMulf(step_vec, 1.0f / nsteps);
-	
-	VecCopyf(step_sta, co);
-	VecAddf(step_end, step_sta, step_vec);
-	
-	for (s = 0;  s < nsteps; s++) {
-		if (s > 0)
-			density = vol_get_density(shi, step_sta);
+	for (; t0 < t1; pt0 = t0, t0 += shi->mat->vol.shade_stepsize) {
+		float absorb[3];
+		const float d = vol_get_density(shi, p);
+		const float stepd = (t0 - pt0) * d;
+		const float scatter_dens = vol_get_scattering_fac(shi, p) * stepd;
+		vol_get_absorption(shi, absorb, p);
 		
-		tau[0] += stepsize * density;
-		tau[1] += stepsize * density;
-		tau[2] += stepsize * density;
+		tau[0] += scatter_dens * absorb[0];
+		tau[1] += scatter_dens * absorb[1];
+		tau[2] += scatter_dens * absorb[2];
 		
-		if (s < nsteps-1) {
-			VecCopyf(step_sta, step_end);
-			VecAddf(step_end, step_end, step_vec);
-		}
+		//if (luminance(tau) >= ambtau) break;
+		VecAddf(p, p, step_vec);
 	}
-	VecMulVecf(tau, tau, absorb_col);
 	
-	transmission[0] *= exp(-tau[0]);
-	transmission[1] *= exp(-tau[1]);
-	transmission[2] *= exp(-tau[2]);
+	/* return transmittance */
+	tr[0] = expf(-tau[0]);
+	tr[1] = expf(-tau[1]);
+	tr[2] = expf(-tau[2]);
 }
 
-void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *lacol, float stepsize, float density)
+void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *lacol)
 {
 	float visifac, lv[3], lampdist;
 	float tr[3]={1.0,1.0,1.0};
@@ -383,7 +437,7 @@
 		do_lamp_tex(lar, lv, shi, lacol, LA_TEXTURE);
 	}
 
-	VecMulf(lacol, visifac*lar->energy);
+	VecMulf(lacol, visifac);
 
 	if (ELEM(lar->type, LA_SUN, LA_HEMI))
 		VECCOPY(lv, lar->vec);
@@ -411,7 +465,7 @@
 			} else
 				atten_co = hitco;
 			
-			vol_get_attenuation(shi, tr, co, atten_co, density, shade_stepsize);
+			vol_get_transmittance(shi, tr, co, atten_co);
 			
 			VecMulVecf(lacol, lacol, tr);
 		}
@@ -445,7 +499,7 @@
 		lar= go->lampren;
 		
 		if (lar) {
-			vol_shade_one_lamp(shi, co, lar, lacol, stepsize, density);
+			vol_shade_one_lamp(shi, co, lar, lacol);
 			VecAddf(scatter_col, scatter_col, lacol);
 		}
 	}
@@ -490,7 +544,7 @@
 		if (density > 0.01f) {
 		
 			/* transmittance component (alpha) */
-			vol_get_attenuation_seg(shi, tr, stepsize, co, density);
+			vol_get_transmittance_seg(shi, tr, stepsize, co, density);
 
 			step_mid[0] = step_sta[0] + (stepvec[0] * 0.5);
 			step_mid[1] = step_sta[1] + (stepvec[1] * 0.5);
@@ -654,7 +708,7 @@
 	}
 	
 	density = vol_get_density(shi, startco);
-	vol_get_attenuation(shi, tr, startco, endco, density, shade_stepsize);

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list