[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22713] branches/volume25: * Volume rendering - z transparency

Matt Ebb matt at mke3.net
Sun Aug 23 04:54:31 CEST 2009


Revision: 22713
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22713
Author:   broken
Date:     2009-08-23 04:54:30 +0200 (Sun, 23 Aug 2009)

Log Message:
-----------
* Volume rendering - z transparency

This solves one of the last remaining hurdles for 
volume rendering. Previously it always used ray 
tracing to shade other objects inside or behind the 
volume. This meant that said objects would look 
aliased, unless you used Full OSA on the volume 
(which is slow!). As well as this, it meant that you didn't 
get a good alpha channel out of the volume to use for 
compositing, similar to ray refracting materials.

This commit enables z transparency for volume 
materials. Although it can be potentially less 
physically correct, in most situations there's no 
difference, and you get the benefit of nice sampling for 
other objects and an alpha channel for compositing too.

Modified Paths:
--------------
    branches/volume25/release/ui/buttons_material.py
    branches/volume25/source/blender/makesdna/DNA_material_types.h
    branches/volume25/source/blender/makesrna/intern/rna_material.c
    branches/volume25/source/blender/render/intern/source/convertblender.c
    branches/volume25/source/blender/render/intern/source/shadeinput.c
    branches/volume25/source/blender/render/intern/source/volumetric.c

Modified: branches/volume25/release/ui/buttons_material.py
===================================================================
--- branches/volume25/release/ui/buttons_material.py	2009-08-22 23:59:50 UTC (rev 22712)
+++ branches/volume25/release/ui/buttons_material.py	2009-08-23 02:54:30 UTC (rev 22713)
@@ -568,7 +568,28 @@
 		col.itemR(vol, "phase_function", text="")
 		if vol.phase_function in ('SCHLICK', 'HENYEY-GREENSTEIN'):
 			col.itemR(vol, "asymmetry")
+
+class MATERIAL_PT_volume_transp(MaterialButtonsPanel):
+	__label__= "Transparency"
+	COMPAT_ENGINES = set(['BLENDER_RENDER'])
 		
+	def poll(self, context):
+		mat = context.material
+		return mat and (mat.type == 'VOLUME') and (context.scene.render_data.engine in self.COMPAT_ENGINES)
+
+	def draw_header(self, context):
+		layout = self.layout
+
+	def draw(self, context):
+		layout = self.layout
+		
+		mat = context.material
+		rayt = context.material.raytrace_transparency
+		
+		row= layout.row()
+		row.itemR(mat, "transparency_method", expand=True)
+		row.active = mat.transparency and (not mat.shadeless)
+		
 class MATERIAL_PT_volume_integration(MaterialButtonsPanel):
 	__label__ = "Integration"
 	__default_closed__ = False
@@ -660,6 +681,7 @@
 bpy.types.register(MATERIAL_PT_sss)
 bpy.types.register(MATERIAL_PT_volume_shading)
 bpy.types.register(MATERIAL_PT_volume_scattering)
+bpy.types.register(MATERIAL_PT_volume_transp)
 bpy.types.register(MATERIAL_PT_volume_integration)
 bpy.types.register(MATERIAL_PT_halo)
 bpy.types.register(MATERIAL_PT_physics)

Modified: branches/volume25/source/blender/makesdna/DNA_material_types.h
===================================================================
--- branches/volume25/source/blender/makesdna/DNA_material_types.h	2009-08-22 23:59:50 UTC (rev 22712)
+++ branches/volume25/source/blender/makesdna/DNA_material_types.h	2009-08-23 02:54:30 UTC (rev 22713)
@@ -377,7 +377,6 @@
 #define MA_VOL_SHADED		1
 #define MA_VOL_RECVSHADOW	4
 #define MA_VOL_PRECACHESHADING	8
-#define MA_VOL_USEALPHA		16
 
 /* vol_shading_type */
 #define MA_VOL_SHADE_NONE					0

Modified: branches/volume25/source/blender/makesrna/intern/rna_material.c
===================================================================
--- branches/volume25/source/blender/makesrna/intern/rna_material.c	2009-08-22 23:59:50 UTC (rev 22712)
+++ branches/volume25/source/blender/makesrna/intern/rna_material.c	2009-08-23 02:54:30 UTC (rev 22713)
@@ -1017,11 +1017,6 @@
 	RNA_def_property_ui_text(prop, "Emission Color", "");
 	RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING_DRAW, NULL);
 	
-	prop= RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE);
-	RNA_def_property_boolean_sdna(prop, NULL, "shadeflag", MA_VOL_USEALPHA); /* use bitflags */
-	RNA_def_property_ui_text(prop, "Use Alpha", "Temp method for getting a usable alpha channel");
-	RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
-	
 	prop= RNA_def_property(srna, "phase_function", PROP_ENUM, PROP_NONE);
 	RNA_def_property_enum_sdna(prop, NULL, "phasefunc_type");
 	RNA_def_property_enum_items(prop, prop_phasefunction_items);

Modified: branches/volume25/source/blender/render/intern/source/convertblender.c
===================================================================
--- branches/volume25/source/blender/render/intern/source/convertblender.c	2009-08-22 23:59:50 UTC (rev 22712)
+++ branches/volume25/source/blender/render/intern/source/convertblender.c	2009-08-23 02:54:30 UTC (rev 22713)
@@ -920,6 +920,7 @@
 	
 	if(re->r.mode & R_SPEED) ma->texco |= NEED_UV;
 	
+	if(ma->material_type == MA_TYPE_VOLUME) ma->mode |= MA_TRANSP;
 	if((ma->mode & MA_TRANSP) && (ma->mode & MA_ZTRANSP))
 		re->flag |= R_ZTRA;
 	
@@ -3005,13 +3006,12 @@
 		}
 	}
 	
-	{
+	/* debug {
 	MatInside *m;
 	for (m=re->render_volumes_inside.first; m; m=m->next) {
 		printf("matinside: ma: %s \n", m->ma->id.name+2);
 	}
-	
-	}
+	}*/
 }
 
 static void add_volume(Render *re, ObjectRen *obr, Material *ma)
@@ -3862,6 +3862,7 @@
 			vlr->flag |= R_FULL_OSA;
 		else if(trace) {
 			if(mode & MA_SHLESS);
+			else if(vlr->mat->material_type == MA_TYPE_VOLUME);
 			else if((mode & MA_RAYMIRROR) || ((mode & MA_TRANSP) && (mode & MA_RAYTRANSP)))
 				/* for blurry reflect/refract, better to take more samples 
 				 * inside the raytrace than as OSA samples */

Modified: branches/volume25/source/blender/render/intern/source/shadeinput.c
===================================================================
--- branches/volume25/source/blender/render/intern/source/shadeinput.c	2009-08-22 23:59:50 UTC (rev 22712)
+++ branches/volume25/source/blender/render/intern/source/shadeinput.c	2009-08-23 02:54:30 UTC (rev 22713)
@@ -216,15 +216,17 @@
 	}
 	else alpha= 1.0f;
 	
+	
 	/* add mist and premul color */
 	if(shr->alpha!=1.0f || alpha!=1.0f) {
 		float fac= alpha*(shr->alpha);
 		shr->combined[3]= fac;
-		shr->combined[0]*= fac;
-		shr->combined[1]*= fac;
-		shr->combined[2]*= fac;
+		
+		if (shi->mat->material_type!= MA_TYPE_VOLUME)
+			VecMulf(shr->combined, fac);
 	}
-	else shr->combined[3]= 1.0f;
+	else
+		shr->combined[3]= 1.0f;
 	
 	/* add z */
 	shr->z= -shi->co[2];

Modified: branches/volume25/source/blender/render/intern/source/volumetric.c
===================================================================
--- branches/volume25/source/blender/render/intern/source/volumetric.c	2009-08-22 23:59:50 UTC (rev 22712)
+++ branches/volume25/source/blender/render/intern/source/volumetric.c	2009-08-23 02:54:30 UTC (rev 22713)
@@ -65,12 +65,20 @@
 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
 
-/* TODO: Box or sphere intersection types could speed things up */
+/* tracing */
+
 static int vol_get_bounds(ShadeInput *shi, float *co, float *vec, float *hitco, Isect *isect, int intersect_type)
 {
 	float maxsize = RE_ray_tree_max_size(R.raytree);
-
-	/* TODO: use object's bounding box to calculate max size */
+	
+	/* XXX TODO - get raytrace max distance from object instance's bounding box */
+	/* need to account for scaling only, but keep coords in camera space...
+	 * below code is WIP and doesn't work!
+	VecSubf(bb_dim, shi->obi->obr->boundbox[1], shi->obi->obr->boundbox[2]);
+	Mat3MulVecfl(shi->obi->nmat, bb_dim);
+	maxsize = VecLength(bb_dim);
+	*/
+	
 	VECCOPY(isect->start, co);
 	isect->end[0] = co[0] + vec[0] * maxsize;
 	isect->end[1] = co[1] + vec[1] * maxsize;
@@ -96,6 +104,68 @@
 	}
 }
 
+static void shade_intersection(ShadeInput *shi, float *col, Isect *is)
+{
+	ShadeInput shi_new;
+	ShadeResult shr_new;
+	
+	memset(&shi_new, 0, sizeof(ShadeInput)); 
+	
+	shi_new.mask= shi->mask;
+	shi_new.osatex= shi->osatex;
+	shi_new.thread= shi->thread;
+	shi_new.depth = shi->depth + 1;
+	shi_new.volume_depth= shi->volume_depth + 1;
+	shi_new.xs= shi->xs;
+	shi_new.ys= shi->ys;
+	shi_new.lay= shi->lay;
+	shi_new.passflag= SCE_PASS_COMBINED; /* result of tracing needs no pass info */
+	shi_new.combinedflag= 0xFFFFFF;		 /* ray trace does all options */
+	shi_new.light_override= shi->light_override;
+	shi_new.mat_override= shi->mat_override;
+	
+	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);
+	}
+	
+	VecCopyf(col, shr_new.combined);
+	col[3] = shr_new.alpha;
+}
+
+static void vol_trace_behind(ShadeInput *shi, VlakRen *vlr, float *co, float *col)
+{
+	Isect isect;
+	float maxsize = RE_ray_tree_max_size(R.raytree);
+	
+	VECCOPY(isect.start, co);
+	isect.end[0] = isect.start[0] + shi->view[0] * maxsize;
+	isect.end[1] = isect.start[1] + shi->view[1] * maxsize;
+	isect.end[2] = isect.start[2] + shi->view[2] * maxsize;
+	
+	isect.faceorig= (RayFace *)vlr;
+	
+	isect.mode= RE_RAY_MIRROR;
+	isect.oborig= RAY_OBJECT_SET(&R, shi->obi);
+	isect.face_last= NULL;
+	isect.ob_last= 0;
+	isect.lay= -1;
+	
+	/* check to see if there's anything behind the volume, otherwise shade the sky */
+	if(RE_ray_tree_intersect(R.raytree, &isect)) {
+		shade_intersection(shi, col, &isect);
+	} else {
+		shadeSkyView(col, co, shi->view, NULL, shi->thread);
+		shadeSunView(col, shi->view);
+	}
+}
+
+/* input shader data */
+
 float vol_get_stepsize(struct ShadeInput *shi, int context)
 {
 	if (shi->mat->vol.stepsize_type == MA_VOL_STEP_RANDOMIZED) {
@@ -280,7 +350,7 @@
 		tau[2] += stepsize * density;
 		
 		if (s < nsteps-1) {
-			VECCOPY(step_sta, step_end);
+			VecCopyf(step_sta, step_end);
 			VecAddf(step_end, step_end, step_vec);
 		}
 	}
@@ -319,9 +389,6 @@
 		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.shade_type != MA_VOL_SHADE_NONE) {
 		Isect is;
 		
@@ -337,6 +404,7 @@
 			}
 
 			if (ELEM(lar->type, LA_SUN, LA_HEMI))
+				/* infinite lights, can never be inside volume */
 				atten_co = hitco;
 			else if ( lampdist < dist ) {
 				atten_co = lar->co;
@@ -354,6 +422,9 @@
 		}
 	}
 	
+	p = vol_get_phasefunc(shi, shi->mat->vol.phasefunc_type, shi->mat->vol.phasefunc_g, shi->view, lv);
+	VecMulf(lacol, p);
+	
 	scatter_fac = vol_get_scattering_fac(shi, co);
 	VecMulf(lacol, scatter_fac);
 }
@@ -390,14 +461,6 @@
 + added radiance from all points along the ray due to participating media
 	--> radiance for each segment = 
 		(radiance added by scattering + radiance added by emission) * beam transmittance/attenuation
-
--- To find transmittance:
-	compute optical thickness with tau (perhaps involving monte carlo integration)
-	transmittance = exp(-tau)
-	
--- To find radiance from segments along the way:
-	find radiance for one step: 
-	- loop over lights and weight by phase function
 */
 static void volumeintegrate(struct ShadeInput *shi, float *col, float *co, float *endco)
 {
@@ -462,150 +525,102 @@
 	VecMulVecf(col, tr, col);	
 	VecAddf(col, col, radiance);
 	
-	/* alpha - transmission */
-	col[3] = 1.0f -(tr[0] + tr[1] + tr[2]) * 0.333f;
+	/* alpha <-- transmission luminance */
+	col[3] = 1.0f -(0.2126*tr[0] + 0.7152*tr[1] + 0.0722*tr[2]);
 }
 
-static void shade_intersection(ShadeInput *shi, float *col, Isect *is)
-{
-	ShadeInput shi_new;
-	ShadeResult shr_new;
-	
-	memset(&shi_new, 0, sizeof(ShadeInput)); 
-	
-	shi_new.mask= shi->mask;
-	shi_new.osatex= shi->osatex;
-	shi_new.thread= shi->thread;
-	shi_new.depth = shi->depth + 1;
-	shi_new.volume_depth= shi->volume_depth + 1;
-	shi_new.xs= shi->xs;
-	shi_new.ys= shi->ys;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list