[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [18191] branches/sim_physics/source/ blender/render/intern: Volume rendering

Matt Ebb matt at mke3.net
Wed Dec 31 06:08:06 CET 2008


Revision: 18191
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=18191
Author:   broken
Date:     2008-12-31 06:08:04 +0100 (Wed, 31 Dec 2008)

Log Message:
-----------
Volume rendering

* Fixed an old problem where if both the camera and a solid surface were 
inside a volume, the volume wouldn't attenuate in front of the surface (was 
visible in the blender conference art festival clouds animation:

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

* Initial support for refracting solids inside volumes. I might be able to 
make this work better, but not sure at the moment. It's a bit dodgy, 
limited by the code that does the recursive ray shading - it's really not 
set up for this kind of thing and could use a refactor very much.

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

Modified: branches/sim_physics/source/blender/render/intern/include/volumetric.h
===================================================================
--- branches/sim_physics/source/blender/render/intern/include/volumetric.h	2008-12-31 04:47:01 UTC (rev 18190)
+++ branches/sim_physics/source/blender/render/intern/include/volumetric.h	2008-12-31 05:08:04 UTC (rev 18191)
@@ -30,8 +30,9 @@
 float vol_get_density(struct ShadeInput *shi, float *co);
 void vol_get_scattering(ShadeInput *shi, float *scatter, float *co, float stepsize, float density);
 
-void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr);
-void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is);
+void shade_volume_outside(ShadeInput *shi, ShadeResult *shr);
+void shade_volume_inside(ShadeInput *shi, ShadeResult *shr);
+void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is);
 
 #define STEPSIZE_VIEW	0
 #define STEPSIZE_SHADE	1
@@ -40,4 +41,7 @@
 #define VOL_IS_SAMEMATERIAL		2
 
 #define VOL_BOUNDS_DEPTH	0
-#define VOL_BOUNDS_SS		1
\ No newline at end of file
+#define VOL_BOUNDS_SS		1
+
+#define VOL_SHADE_OUTSIDE	0
+#define VOL_SHADE_INSIDE	1
\ No newline at end of file

Modified: branches/sim_physics/source/blender/render/intern/source/rayshade.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/rayshade.c	2008-12-31 04:47:01 UTC (rev 18190)
+++ branches/sim_physics/source/blender/render/intern/source/rayshade.c	2008-12-31 05:08:04 UTC (rev 18191)
@@ -276,9 +276,9 @@
 	
 	if (shi->mat->material_type == MA_VOLUME) {
 		if(ELEM(is->mode, RE_RAY_SHADOW, RE_RAY_SHADOW_TRA)) {
-			volume_trace_shadow(shi, shr, is);
+			shade_volume_shadow(shi, shr, is);
 		} else {
-			shade_volume_loop(shi, shr);
+			shade_volume_outside(shi, shr);
 		}
 	}
 	else if(is->mode==RE_RAY_SHADOW_TRA) 
@@ -295,7 +295,18 @@
 			shi->mat= vlr->mat;		/* shi->mat is being set in nodetree */
 		}
 		else {
-			shade_material_loop(shi, shr);
+			int tempdepth;
+			/* XXX dodgy business here, set ray depth to -1
+			 * to ignore raytrace in shade_material_loop()
+			 * this could really use a refactor --Matt */
+			if (shi->volume_depth == 0) {
+				tempdepth = shi->depth;
+				shi->depth = -1;
+				shade_material_loop(shi, shr);
+				shi->depth = tempdepth;
+			} else {
+				shade_material_loop(shi, shr);
+			}
 		}
 		/* raytrace likes to separate the spec color */
 		VECSUB(shr->diff, shr->combined, shr->spec);
@@ -467,7 +478,7 @@
 		
 		shi.mask= origshi->mask;
 		shi.osatex= origshi->osatex;
-		shi.depth= 1;					/* only used to indicate tracing */
+		shi.depth = origshi->depth + 1;					/* only used to indicate tracing */
 		shi.thread= origshi->thread;
 		//shi.sample= 0; // memset above, so dont need this
 		shi.xs= origshi->xs;
@@ -482,6 +493,7 @@
 		memset(&shr, 0, sizeof(ShadeResult));
 		
 		shade_ray(&isec, &shi, &shr);
+
 		if (traflag & RAY_TRA)
 			d= shade_by_transmission(&isec, &shi, &shr);
 		

Modified: branches/sim_physics/source/blender/render/intern/source/shadeinput.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/shadeinput.c	2008-12-31 04:47:01 UTC (rev 18190)
+++ branches/sim_physics/source/blender/render/intern/source/shadeinput.c	2008-12-31 05:08:04 UTC (rev 18191)
@@ -121,7 +121,7 @@
 	}
 	
 	/* depth >= 1 when ray-shading */
-	if(shi->depth==0) {
+	if(shi->depth >= 0 && (shi->depth < MAX2(shi->mat->ray_depth_tra, shi->mat->ray_depth))) {
 		if(R.r.mode & R_RAYTRACE) {
 			if(shi->ray_mirror!=0.0f || ((shi->mat->mode & MA_RAYTRANSP) && shr->alpha!=1.0f)) {
 				/* ray trace works on combined, but gives pass info */
@@ -132,16 +132,13 @@
 		if(shi->mat->mode & MA_RAYTRANSP) 
 			if((shi->layflag & SCE_LAY_SKY) && (R.r.alphamode==R_ADDSKY))
 				shr->alpha= 1.0f;
-	}	
+	}
+	
+	if(R.r.mode & R_RAYTRACE) {
+		shade_volume_inside(shi, shr);
+	}
 }
 
-/* delivers a fully filled in ShadeResult, for all passes */
-void shade_volume_loop(ShadeInput *shi, ShadeResult *shr)
-{
-	if(R.r.mode & R_RAYTRACE) volume_trace(shi, shr);
-}
-
-
 /* do a shade, finish up some passes, apply mist */
 void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
 {
@@ -157,8 +154,12 @@
 		memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
 		shi->har= shi->mat->har;
 		
-		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);
+		if (shi->mat->material_type == MA_SOLID) {
+			shade_material_loop(shi, shr);
+		} else if (shi->mat->material_type == MA_VOLUME) {
+			if(R.r.mode & R_RAYTRACE)
+				shade_volume_outside(shi, shr);
+		}
 	}
 	
 	/* copy additional passes */

Modified: branches/sim_physics/source/blender/render/intern/source/volumetric.c
===================================================================
--- branches/sim_physics/source/blender/render/intern/source/volumetric.c	2008-12-31 04:47:01 UTC (rev 18190)
+++ branches/sim_physics/source/blender/render/intern/source/volumetric.c	2008-12-31 05:08:04 UTC (rev 18191)
@@ -548,7 +548,7 @@
 	shi_new.mask= shi->mask;
 	shi_new.osatex= shi->osatex;
 	shi_new.thread= shi->thread;
-	shi_new.depth= 1;
+	shi_new.depth = shi->depth + 1;
 	shi_new.volume_depth= shi->volume_depth + 1;
 	shi_new.xs= shi->xs;
 	shi_new.ys= shi->ys;
@@ -601,19 +601,32 @@
 }
 
 /* the main entry point for volume shading */
-void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr)
+static void volume_trace(struct ShadeInput *shi, struct ShadeResult *shr, int inside_volume)
 {
 	float hitco[3], col[4] = {0.f,0.f,0.f,0.f};
+	int trace_behind = 1;
 	Isect is;
 
-	memset(shr, 0, sizeof(ShadeResult));
+	/* check for shading an internal face a volume object directly */
+	if (inside_volume == VOL_SHADE_INSIDE) {
+		trace_behind = 0;
+	}
+	if (inside_volume == VOL_SHADE_OUTSIDE) {
+		if (shi->flippednor)
+			inside_volume = VOL_SHADE_INSIDE;
+	}
 
-	/* if 1st hit normal is facing away from the camera, 
-	 * then we're inside the volume already. */
-	if (shi->flippednor) {
-		/* trace behind the 1st hit point */
-		vol_trace_behind(shi, shi->vlr, shi->co, col);
+	if (inside_volume == VOL_SHADE_INSIDE) {
 		
+		if (trace_behind) {
+			/* trace behind the volume object */
+			vol_trace_behind(shi, shi->vlr, shi->co, col);
+		} else {
+			/* we're tracing through the volume between the camera 
+			 * and a solid surface, so use that pre-shaded radiance */
+			QUATCOPY(col, shr->combined);
+		}
+		
 		/* shade volume from 'camera' to 1st hit point */
 		volumeintegrate(shi, col, shi->camera_co, shi->co);
 		
@@ -673,7 +686,7 @@
 
 /* Traces a shadow through the object, 
  * pretty much gets the transmission over a ray path */
-void volume_trace_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is)
+void shade_volume_shadow(struct ShadeInput *shi, struct ShadeResult *shr, struct Isect *last_is)
 {
 	float hitco[3];
 	float tr[3] = {1.0,1.0,1.0};
@@ -724,3 +737,33 @@
 	}
 }
 
+
+/* delivers a fully filled in ShadeResult, for all passes */
+void shade_volume_outside(ShadeInput *shi, ShadeResult *shr)
+{
+	memset(shr, 0, sizeof(ShadeResult));
+	
+	volume_trace(shi, shr, VOL_SHADE_OUTSIDE);
+}
+
+
+void shade_volume_inside(ShadeInput *shi, ShadeResult *shr)
+{
+	MatInside *m;
+	Material *mat_backup;
+	
+	if (BLI_countlist(&R.render_volumes_inside) == 0) return;
+	
+	mat_backup = shi->mat;
+	
+//	for (m=R.render_volumes_inside.first; m; m=m->next) {
+//		printf("matinside: ma: %s \n", m->ma->id.name+2);
+//	}
+
+	m = R.render_volumes_inside.first;
+	shi->mat = m->ma;
+	
+	volume_trace(shi, shr, VOL_SHADE_INSIDE);
+
+	shi->mat = mat_backup;
+}
\ No newline at end of file





More information about the Bf-blender-cvs mailing list