[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17055] branches/sim_physics/source/ blender/render/intern: * Raytraced shadow casting for volumes

Matt Ebb matt at mke3.net
Mon Oct 13 07:22:31 CEST 2008


Revision: 17055
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17055
Author:   broken
Date:     2008-10-13 07:22:31 +0200 (Mon, 13 Oct 2008)

Log Message:
-----------
* Raytraced shadow casting for volumes

This is a first version and still has a couple of things undefined or
unimplemented, such as external objects casting shadows on or within volumes, 
however volume->solid shadows are going ok.

http://mke3.net/blender/devel/rendering/volumetrics/shadows_test_02.mov
http://mke3.net/blender/devel/rendering/volumetrics/vol_test_shad3.blend

As with other transparent raytraced shadows in Blender ,in order to make it work,
you must enable 'TraShad' on the material *receiving* the shadow. It would be 
nice to make this a bit easier to use, since there's not much chance you want a
volume material to be casting solid shadows, but that's a bigger issue in the 
renderer outside this scope.

The volume shadows are working from the same physical basis of absorption, and 
support coloured absorption:

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

They also work properly with multi-sampled (i.e. QMC) soft shadows:

http://mke3.net/blender/devel/rendering/volumetrics/vol_shad_sharp.png
http://mke3.net/blender/devel/rendering/volumetrics/vol_shad_soft.png

And by popular request the test file:
http://mke3.net/blender/devel/rendering/volumetrics/vol_test_shad_clouds.blend

Modified Paths:
--------------
    branches/sim_physics/source/blender/render/intern/include/pointdensity.h
    branches/sim_physics/source/blender/render/intern/include/rendercore.h
    branches/sim_physics/source/blender/render/intern/include/volumetric.h
    branches/sim_physics/source/blender/render/intern/source/convertblender.c
    branches/sim_physics/source/blender/render/intern/source/rayshade.c
    branches/sim_physics/source/blender/render/intern/source/volumetric.c

Modified: branches/sim_physics/source/blender/render/intern/include/pointdensity.h
===================================================================
--- branches/sim_physics/source/blender/render/intern/include/pointdensity.h	2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/include/pointdensity.h	2008-10-13 05:22:31 UTC (rev 17055)
@@ -37,6 +37,7 @@
 struct TexResult;
 
 void make_pointdensities(struct Render *re);
+void free_pointdensities(struct Render *re);
 int pointdensitytex(struct Tex *tex, float *texvec, struct TexResult *texres);
 
 #endif /* POINTDENSITY_H */

Modified: branches/sim_physics/source/blender/render/intern/include/rendercore.h
===================================================================
--- branches/sim_physics/source/blender/render/intern/include/rendercore.h	2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/include/rendercore.h	2008-10-13 05:22:31 UTC (rev 17055)
@@ -48,6 +48,7 @@
 struct RenderLayer;
 struct ObjectRen;
 struct ListBase;
+struct Isect;
 
 /* ------------------------------------------------------------------------- */
 
@@ -98,6 +99,7 @@
 
 extern void ray_shadow(ShadeInput *, LampRen *, float *);
 extern void ray_trace(ShadeInput *, ShadeResult *);
+extern void ray_trace_shadow_tra(struct Isect *is, int depth, int traflag);
 extern void ray_ao(ShadeInput *, float *);
 extern void init_jitter_plane(LampRen *lar);
 extern void init_ao_sphere(struct World *wrld);

Modified: branches/sim_physics/source/blender/render/intern/include/volumetric.h
===================================================================
--- branches/sim_physics/source/blender/render/intern/include/volumetric.h	2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/include/volumetric.h	2008-10-13 05:22:31 UTC (rev 17055)
@@ -26,4 +26,5 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr);
\ No newline at end of file
+void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr);
+void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is);
\ No newline at end of file

Modified: branches/sim_physics/source/blender/render/intern/source/convertblender.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/convertblender.c	2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/source/convertblender.c	2008-10-13 05:22:31 UTC (rev 17055)
@@ -965,8 +965,6 @@
 	if(ma->nodetree && ma->use_nodes)
 		flag_render_node_material(re, ma->nodetree);
 	
-	if (ma->material_type == MA_VOLUME) re->r.mode |= R_RAYTRACE;
-	
 	check_material_is_textured(ma);
 	
 	return ma;

Modified: branches/sim_physics/source/blender/render/intern/source/rayshade.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/rayshade.c	2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/source/rayshade.c	2008-10-13 05:22:31 UTC (rev 17055)
@@ -54,6 +54,7 @@
 #include "pixelshading.h"
 #include "shading.h"
 #include "texture.h"
+#include "volumetric.h"
 
 #include "RE_raytrace.h"
 
@@ -262,21 +263,28 @@
 
 	shade_input_set_shade_texco(shi);
 	
-	if(is->mode==RE_RAY_SHADOW_TRA) 
+	if (shi->mat->material_type == MA_VOLUME) {
+		if(ELEM(is->mode, RE_RAY_SHADOW, RE_RAY_SHADOW_TRA)) {
+			volume_trace_shadow(shi, shr, is);
+		} else {
+			shade_volume_loop(shi, shr);
+		}
+	}
+	else if(is->mode==RE_RAY_SHADOW_TRA) 
 		if(shi->mat->nodetree && shi->mat->use_nodes) {
 			ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
 			shi->mat= vlr->mat;		/* shi->mat is being set in nodetree */
 		}
-		else
+		else {
 			shade_color(shi, shr);
+		}
 	else {
 		if(shi->mat->nodetree && shi->mat->use_nodes) {
 			ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
 			shi->mat= vlr->mat;		/* shi->mat is being set in nodetree */
 		}
 		else {
-			if (shi->mat->material_type == MA_SOLID) shade_material_loop(shi, shr);
-			else if (shi->mat->material_type == MA_VOLUME) shade_volume_loop(shi, shr);
+			shade_material_loop(shi, shr);
 		}
 		/* raytrace likes to separate the spec color */
 		VECSUB(shr->diff, shr->combined, shr->spec);
@@ -1274,7 +1282,7 @@
 	shadfac[3]= (1.0f-alpha)*shadfac[3];
 }
 
-static void ray_trace_shadow_tra(Isect *is, int depth, int traflag)
+void ray_trace_shadow_tra(Isect *is, int depth, int traflag)
 {
 	/* ray to lamp, find first face that intersects, check alpha properties,
 	   if it has col[3]>0.0f  continue. so exit when alpha is full */
@@ -1303,12 +1311,17 @@
 		shi.mat_override= NULL;*/
 		
 		shade_ray(is, &shi, &shr);
-		if (traflag & RAY_TRA)
-			d= shade_by_transmission(is, &shi, &shr);
+		if (shi.mat->material_type == MA_SOLID) {
+			if (traflag & RAY_TRA)
+				d= shade_by_transmission(is, &shi, &shr);
+			
+			/* mix colors based on shadfac (rgb + amount of light factor) */
+			addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter);
+		} else {
+			// MA_VOLUME
+			addAlphaLight(is->col, shr.combined, shr.alpha, 1.0f);
+		}
 		
-		/* mix colors based on shadfac (rgb + amount of light factor) */
-		addAlphaLight(is->col, shr.diff, shr.alpha, d*shi.mat->filter);
-		
 		if(depth>0 && is->col[3]>0.0f) {
 			
 			/* adapt isect struct */

Modified: branches/sim_physics/source/blender/render/intern/source/volumetric.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/volumetric.c	2008-10-13 03:55:59 UTC (rev 17054)
+++ branches/sim_physics/source/blender/render/intern/source/volumetric.c	2008-10-13 05:22:31 UTC (rev 17055)
@@ -149,6 +149,8 @@
 		else if (context == STEPSIZE_SHADE)
 			return shi->mat->vol_shade_stepsize;
 	}
+	
+	return shi->mat->vol_stepsize;
 }
 
 float vol_get_density(struct ShadeInput *shi, float *co)
@@ -247,6 +249,8 @@
 	dist = VecLenf(co, endco);
 	nsteps = (int)ceil(dist / stepsize);
 	
+	if (density < -0.001f) density = vol_get_density(shi, co);
+	
 	if (nsteps == 1) {
 		/* homogenous volume within the sampled distance */
 		tau[0] = tau[1] = tau[2] = dist * density;
@@ -485,7 +489,7 @@
 	shi_new.mask= shi->mask;
 	shi_new.osatex= shi->osatex;
 	shi_new.thread= shi->thread;
-	shi_new.depth= shi->depth;
+	shi_new.depth= 1;
 	shi_new.volume_depth= shi->volume_depth + 1;
 	shi_new.xs= shi->xs;
 	shi_new.ys= shi->ys;
@@ -597,3 +601,57 @@
 		shr->combined[3] = shr->alpha =  1.0f;
 	}
 }
+
+void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is)
+{
+	float hitco[3], col[4] = {0.f,0.f,0.f,0.f};
+	float tr[3] = {1.0,1.0,1.0};
+	float tau[3] = {0.0,0.0,0.0};
+	Isect is;
+	float shade_stepsize = vol_get_stepsize(shi, STEPSIZE_SHADE);
+
+	memset(shr, 0, sizeof(ShadeResult));
+	
+	/* if 1st hit normal is facing away from the camera, 
+	 * then we're inside the volume already. */
+	if (shi->flippednor) {
+	
+		vol_get_attenuation(shi, tau, last_is->start, shi->co, -1.0f, shade_stepsize);
+		tr[0] = exp(-tau[0]);
+		tr[1] = exp(-tau[1]);
+		tr[2] = exp(-tau[2]);
+		
+		shr->combined[0] = tr[0];
+		shr->combined[1] = tr[1];
+		shr->combined[2] = tr[2];
+		
+		shr->combined[3] = 1.0f -(tr[0] + tr[1] + tr[2]) * 0.333f;
+		shr->alpha = shr->combined[3];
+	}
+	/* trace to find a backface, the other side bounds of the volume */
+	/* (ray intersect ignores front faces here) */
+	else if (vol_get_bounds(shi, shi->co, shi->view, hitco, &is, VOL_BOUNDS_DEPTH, 0)) {
+		float dist = VecLenf(shi->co, hitco);
+		
+		vol_get_attenuation(shi, tau, shi->co, hitco, -1.0f, shade_stepsize);
+		tr[0] = exp(-tau[0]);
+		tr[1] = exp(-tau[1]);
+		tr[2] = exp(-tau[2]);
+		
+		shr->combined[0] = tr[0];
+		shr->combined[1] = tr[1];
+		shr->combined[2] = tr[2];
+		
+		shr->combined[3] = 1.0f -(tr[0] + tr[1] + tr[2]) * 0.333f;
+		shr->alpha = shr->combined[3];
+
+	}
+	else {
+		shr->combined[0] = 0.0f;
+		shr->combined[1] = 0.0f;
+		shr->combined[2] = 0.0f;
+		shr->combined[3] = shr->alpha =  0.0f;
+	}
+
+}
+





More information about the Bf-blender-cvs mailing list