[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16915] branches/sim_physics/source/ blender: * New volumetrics feature: scattering types

Matt Ebb matt at mke3.net
Sat Oct 4 14:23:59 CEST 2008


Revision: 16915
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16915
Author:   broken
Date:     2008-10-04 14:23:57 +0200 (Sat, 04 Oct 2008)

Log Message:
-----------
* New volumetrics feature: scattering types

Otherwise known as a phase function, this determines in which directions 
the light is scattered in the volume. Until now it's been isotropic 
scattering, meaning that the light gets scattered equally in all 
directions. This adds some new types for anisotropic scattering, to 
scatter light more forwards or backwards towards the viewing direction, 
which can be more similar to how light is scattered by particles in nature.

Here's a diagram of how light is scattered isotropically and anisotropically:
http://mke3.net/blender/devel/rendering/volumetrics/phase_diagram.png

The new additions are:
- Rayleigh
describes scattering by very small particles in the atmosphere.
- Mie Hazy / Mie Murky
more generalised, describes scattering from large particle sizes.
- Henyey-Greenstein
a very flexible formula, that can be used to simulate a wide range of 
scattering. It uses an additional 'Asymmetry' slider, ranging from -1.0 
(backward scattering) to 1.0 (forward scattering) to control the 
direction of scattering.
- Schlick
an approximation of Henyey-Greenstein, working similarly but faster.

And a description of how they look visually (just an omnidirectional lamp 
inside a volume box)
http://mke3.net/blender/devel/rendering/volumetrics/phasefunctions.jpg


* Sun/sky integration

Volumes now correctly render in front of the new physical sky. Atmosphere 
still doesn't work correctly with volumes, due to something that i hope 
can be fixed in the atmosphere rendering, but the sky looks quite good.

http://mke3.net/blender/devel/rendering/volumetrics/sky_clouds.png

This also works very nicely with the anisotropic scattering, giving 
clouds their signature bright halos when the sun is behind them:

http://mke3.net/blender/devel/rendering/volumetrics/phase_cloud.mov

in comparison here's a render with isotropic scattering:

http://mke3.net/blender/devel/rendering/volumetrics/phase_cloud_isotropic.png


* Added back the max volume depth tracing limit, as a hard coded value - 
fixes crashes with weird geometry, like the overlapping faces around 
suzanne's eyes. As a general note, it's always best to use volume 
materials on airtight geometry, without intersecting or overlapping faces.

Modified Paths:
--------------
    branches/sim_physics/source/blender/makesdna/DNA_material_types.h
    branches/sim_physics/source/blender/render/extern/include/RE_shader_ext.h
    branches/sim_physics/source/blender/render/intern/source/volumetric.c
    branches/sim_physics/source/blender/src/buttons_shading.c

Modified: branches/sim_physics/source/blender/makesdna/DNA_material_types.h
===================================================================
--- branches/sim_physics/source/blender/makesdna/DNA_material_types.h	2008-10-04 11:04:09 UTC (rev 16914)
+++ branches/sim_physics/source/blender/makesdna/DNA_material_types.h	2008-10-04 12:23:57 UTC (rev 16915)
@@ -71,7 +71,8 @@
 	float vol_absorption, vol_scattering;
 	float vol_absorption_col[3];
 	short vol_shadeflag;
-	short volpad[3];
+	short vol_phasefunc_type;
+	float vol_phasefunc_g;
 		
 	float fresnel_mir, fresnel_mir_i;
 	float fresnel_tra, fresnel_tra_i;
@@ -351,5 +352,13 @@
 #define MA_VOL_ATTENUATED	2
 #define MA_VOL_SHADOWED		4
 
+/* vol_phasefunc_type */
+#define MA_VOL_PH_ISOTROPIC		0
+#define MA_VOL_PH_MIEHAZY		1
+#define MA_VOL_PH_MIEMURKY		2
+#define MA_VOL_PH_RAYLEIGH		3
+#define MA_VOL_PH_HG			4
+#define MA_VOL_PH_SCHLICK		5
+
 #endif
 

Modified: branches/sim_physics/source/blender/render/extern/include/RE_shader_ext.h
===================================================================
--- branches/sim_physics/source/blender/render/extern/include/RE_shader_ext.h	2008-10-04 11:04:09 UTC (rev 16914)
+++ branches/sim_physics/source/blender/render/extern/include/RE_shader_ext.h	2008-10-04 12:23:57 UTC (rev 16915)
@@ -160,6 +160,7 @@
 	
 	int samplenr;			/* sample counter, to detect if we should do shadow again */
 	int depth;				/* 1 or larger on raytrace shading */
+	int volume_depth;		/* number of intersections through volumes */
 	
 	/* stored copy of original face normal (facenor) 
 	 * before flipping. Used in Front/back output on geometry node */

Modified: branches/sim_physics/source/blender/render/intern/source/volumetric.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/volumetric.c	2008-10-04 11:04:09 UTC (rev 16914)
+++ branches/sim_physics/source/blender/render/intern/source/volumetric.c	2008-10-04 12:23:57 UTC (rev 16915)
@@ -164,6 +164,33 @@
 	*scatter_fac = shi->mat->vol_scattering;
 }
 
+float vol_get_phasefunc(ShadeInput *shi, short phasefunc_type, float g, float *w, float *wp)
+{
+	const float costheta = Inpf(w, wp);
+	
+	if (phasefunc_type == MA_VOL_PH_ISOTROPIC) {
+		return 1.f / (4.f * M_PI);
+	}
+	else if (phasefunc_type == MA_VOL_PH_MIEHAZY) {
+		return (0.5f + 4.5f * powf(0.5 * (1.f + costheta), 8.f)) / (4.f*M_PI);
+	}
+	else if (phasefunc_type == MA_VOL_PH_MIEMURKY) {
+		return (0.5f + 16.5f * powf(0.5 * (1.f + costheta), 32.f)) / (4.f*M_PI);
+	}
+	else if (phasefunc_type == MA_VOL_PH_RAYLEIGH) {
+		return 3.f/(16.f*M_PI) * (1 + costheta * costheta);
+	}
+	else if (phasefunc_type == MA_VOL_PH_HG) {
+		return 1.f / (4.f * M_PI) * (1.f - g*g) / powf(1.f + g*g - 2.f * g * costheta, 1.5f);
+	}
+	else if (phasefunc_type == MA_VOL_PH_SCHLICK) {
+		const float k = 1.55f * g - .55f * g * g * g;
+		const float kcostheta = k * costheta;
+		return 1.f / (4.f * M_PI) * (1.f - k*k) / ((1.f - kcostheta) * (1.f - kcostheta));
+	} else {
+		return 1.0f;
+	}
+}
 
 void vol_get_absorption(ShadeInput *shi, float *absorb_col, float *co)
 {
@@ -229,13 +256,14 @@
 	VecMulVecf(tau, tau, absorb_col);
 }
 
-void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *col, float stepsize, float density)
+void vol_shade_one_lamp(struct ShadeInput *shi, float *co, LampRen *lar, float *lacol, float stepsize, float density)
 {
 	float visifac, lv[3], lampdist;
-	float lacol[3];
 	float tau[3], tr[3]={1.0,1.0,1.0};
 	float hitco[3], *atten_co;
-	
+	float p;
+	float scatter_fac;
+			
 	if (lar->mode & LA_LAYER) if((lar->lay & shi->obi->lay)==0) return;
 	if ((lar->lay & shi->lay)==0) return;
 	if (lar->energy == 0.0) return;
@@ -253,15 +281,17 @@
 	}
 	
 	VecMulf(lacol, visifac*lar->energy);
-
-
+		
+	if (ELEM(lar->type, LA_SUN, LA_HEMI))
+		VECCOPY(lv, lar->vec);
+	VecMulf(lv, -1.0f);
+	
+	p = vol_get_phasefunc(shi, shi->mat->vol_phasefunc_type, shi->mat->vol_phasefunc_g, shi->view, lv);
+	VecMulf(lacol, p);
+	
 	if (shi->mat->vol_shadeflag & MA_VOL_ATTENUATED) {
 		Isect is;
 		
-		if (ELEM(lar->type, LA_SUN, LA_HEMI))
-			VECCOPY(lv, lar->vec);
-		VecMulf(lv, -1.0f);
-		
 		/* find minimum of volume bounds, or lamp coord */
 		if (vol_get_bounds(shi, co, lv, hitco, &is, VOL_BOUNDS_SS, 0)) {
 			float dist = VecLenf(co, hitco);
@@ -287,7 +317,11 @@
 		}
 	}
 	
-	VecAddf(col, col, lacol);
+	vol_get_scattering_fac(shi, &scatter_fac, co, density);
+	VecMulf(lacol, scatter_fac);
+	
+	
+
 }
 
 /* shadows -> trace a ray to find blocker geometry
@@ -309,19 +343,12 @@
 	for(go=lights->first; go; go= go->next)
 	{
 		float lacol[3] = {0.f, 0.f, 0.f};
-		float scatter_fac;
 	
 		lar= go->lampren;
 		if (lar==NULL) continue;
 		
 		vol_shade_one_lamp(shi, co, lar, lacol, stepsize, density);
-		
-		vol_get_scattering_fac(shi, &scatter_fac, co, density);
-		VecMulf(lacol, scatter_fac);
-		
-		/* isotropic phase function */
-		VecMulf(lacol, 1.0f / (4.f * M_PI));
-	
+			
 		VecMulf(lacol, density);
 		
 		VecAddf(col, col, lacol);
@@ -435,6 +462,8 @@
 	shi_new.mask= shi->mask;
 	shi_new.osatex= shi->osatex;
 	shi_new.thread= shi->thread;
+	shi_new.depth= shi->depth;
+	shi_new.volume_depth= shi->volume_depth + 1;
 	shi_new.xs= shi->xs;
 	shi_new.ys= shi->ys;
 	shi_new.lay= shi->lay;
@@ -446,9 +475,12 @@
 	VECCOPY(shi_new.camera_co, is->start);
 	
 	memset(&shr_new, 0, sizeof(ShadeResult));
+
+	/* hardcoded limit of 100 for now - prevents problems in weird geometry */
+	if (shi->volume_depth < 100) {
+		shade_ray(is, &shi_new, &shr_new);
+	}
 	
-	shade_ray(is, &shi_new, &shr_new);
-	
 	col[0] = shr_new.combined[0];
 	col[1] = shr_new.combined[1];
 	col[2] = shr_new.combined[2];
@@ -478,6 +510,7 @@
 		shade_intersection(shi, col, &isect);
 	} else {
 		shadeSkyView(col, co, shi->view, NULL);
+		shadeSunView(col, shi->view);
 	}
 }
 

Modified: branches/sim_physics/source/blender/src/buttons_shading.c
===================================================================
--- branches/sim_physics/source/blender/src/buttons_shading.c	2008-10-04 11:04:09 UTC (rev 16914)
+++ branches/sim_physics/source/blender/src/buttons_shading.c	2008-10-04 12:23:57 UTC (rev 16915)
@@ -4342,6 +4342,18 @@
 	uiDefButF(block, NUM, B_MATPRV, "Step Size: ",
 		X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_shade_stepsize), 0.001, 100.0, 10, 2, "Step");
 	uiBlockEndAlign(block);
+	
+	yco -= YSPACE;
+	
+	uiBlockBeginAlign(block);
+	uiDefButS(block, MENU, B_TEXREDR_PRV, "Scattering Direction %t|Isotropic %x0|Mie Hazy %x1|Mie Murky %x2|Rayleigh %x3|Henyey-Greenstein %x4|Schlick %x5",
+		X2CLM1, yco-=BUTH, BUTW2, BUTH, &ma->vol_phasefunc_type, 0.0, 0.0, 0, 0, "Scattering Direction (Phase Function)");
+	if (ELEM(ma->vol_phasefunc_type, MA_VOL_PH_HG, MA_VOL_PH_SCHLICK)) {
+		uiDefButF(block, NUM, B_MATPRV, "Asymmetry: ",
+			X2CLM1, yco-=BUTH, BUTW2, BUTH, &(ma->vol_phasefunc_g), -1.0, 1.0, 0, 0, "> 0 is forward scattering, < 0 is back scattering");
+	}
+	uiBlockEndAlign(block);
+	
 		
 	yco = PANEL_YMAX;
 	





More information about the Bf-blender-cvs mailing list