[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12375] trunk/blender/source/blender: * Adaptive QMC AO feature - "Adapt from speed vectors"

Matt Ebb matt at mke3.net
Wed Oct 24 14:42:09 CEST 2007


Revision: 12375
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12375
Author:   broken
Date:     2007-10-24 14:42:08 +0200 (Wed, 24 Oct 2007)

Log Message:
-----------
* Adaptive QMC AO feature - "Adapt from speed vectors"

This is a new feature that can make using AO a lot more attractive when rendering 
animations with vector blur. It uses the speed vector info calculated in the 'Vec' 
speed vector pass, in order to reduce AO samples where pixels are moving more 
quickly. There's not much point calculating all those AO samples when the result is 
going to be smeared anyway, so you can save a bit of render time by doing 
a more noisy render in those areas.


You can use this with a new slider in the Adaptive QMC settings 'Adapt Vec'. The 
higher the value, the more aggressively it will reduce samples. 0.0 means no 
reduction, and 1.0 reduces one sample per pixel of average displacement for that 
pixel. 0.25 or so generally gives decent results, but it depends on how fast things 
are moving.

Here's a demo (compare the final blurred result, and render times):
http://mke3.net/blender/devel/raytracing/adapt_speed_off2.jpg
http://mke3.net/blender/devel/raytracing/adapt_speed_on2.jpg

And a less contrived example, a short clip from macouno's 'petunia' bconf animation:
http://mke3.net/blender/devel/raytracing/petunia-adaptvec-noblur-h264.mov
http://mke3.net/blender/devel/raytracing/petunia-adaptvec-blur-h264.mov

Modified Paths:
--------------
    trunk/blender/source/blender/include/butspace.h
    trunk/blender/source/blender/makesdna/DNA_world_types.h
    trunk/blender/source/blender/render/intern/source/rayshade.c
    trunk/blender/source/blender/src/buttons_shading.c

Modified: trunk/blender/source/blender/include/butspace.h
===================================================================
--- trunk/blender/source/blender/include/butspace.h	2007-10-24 11:16:48 UTC (rev 12374)
+++ trunk/blender/source/blender/include/butspace.h	2007-10-24 12:42:08 UTC (rev 12375)
@@ -290,7 +290,7 @@
 #define B_COLZEN		1503
 #define B_WMTEXPASTE	1504
 #define B_WMTEXCOPY		1505
-#define B_AO_DISTANCES	1506
+#define B_AO_FALLOFF	1506
 
 /* *********************** */
 #define B_RENDERBUTS	1700

Modified: trunk/blender/source/blender/makesdna/DNA_world_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_world_types.h	2007-10-24 11:16:48 UTC (rev 12374)
+++ trunk/blender/source/blender/makesdna/DNA_world_types.h	2007-10-24 12:42:08 UTC (rev 12375)
@@ -103,8 +103,8 @@
 	/* ambient occlusion */
 	float aodist, aodistfac, aoenergy, aobias;
 	short aomode, aosamp, aomix, aocolor;
-	float ao_adapt_thresh;
-	float pad2[3];
+	float ao_adapt_thresh, ao_adapt_speed_fac;
+	float pad2[2];
 	short ao_samp_method;
 	short pad1[3];
 	

Modified: trunk/blender/source/blender/render/intern/source/rayshade.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/rayshade.c	2007-10-24 11:16:48 UTC (rev 12374)
+++ trunk/blender/source/blender/render/intern/source/rayshade.c	2007-10-24 12:42:08 UTC (rev 12375)
@@ -806,6 +806,23 @@
 	vec[2] = 1.f - s[1]*s[1];
 }
 
+/* cosine weighted hemisphere sampling */
+static void QMC_sampleHemiCosine(float *vec, QMCSampler *qsa, int thread, int num)
+{
+	double s[2];
+	float phi, sqr;
+	
+	QMC_getSample(s, qsa, thread, num);
+	
+	phi = s[0]*2.f*M_PI;	
+	sqr = s[1]*sqrt(2-s[1]*s[1]);
+
+	vec[0] = cos(phi)*sqr;
+	vec[1] = sin(phi)*sqr;
+	vec[2] = 1.f - s[1]*s[1];
+
+}
+
 /* called from convertBlenderScene.c */
 /* samples don't change per pixel, so build the samples in advance for efficiency */
 void init_lamp_hammersley(LampRen *lar)
@@ -861,6 +878,20 @@
 		return 0;
 }
 
+static float get_avg_speed(ShadeInput *shi)
+{
+	float pre_x, pre_y, post_x, post_y, speedavg;
+	
+	pre_x = (shi->winspeed[0] == PASS_VECTOR_MAX)?0.0:shi->winspeed[0];
+	pre_y = (shi->winspeed[1] == PASS_VECTOR_MAX)?0.0:shi->winspeed[1];
+	post_x = (shi->winspeed[2] == PASS_VECTOR_MAX)?0.0:shi->winspeed[2];
+	post_y = (shi->winspeed[3] == PASS_VECTOR_MAX)?0.0:shi->winspeed[3];
+	
+	speedavg = (sqrt(pre_x*pre_x + pre_y*pre_y) + sqrt(post_x*post_x + post_y*post_y)) / 2.0;
+	
+	return speedavg;
+}
+
 /* ***************** main calls ************** */
 
 
@@ -1407,6 +1438,7 @@
 	float maxdist = R.wrld.aodist;
 	float fac=0.0f, prev=0.0f;
 	float adapt_thresh = G.scene->world->ao_adapt_thresh;
+	float adapt_speed_fac = G.scene->world->ao_adapt_speed_fac;
 	float bias = G.scene->world->aobias;
 	
 	int samples=0;
@@ -1447,18 +1479,29 @@
 	VecOrthoBasisf(nrm, up, side);
 	
 	/* sampling init */
-	if (R.wrld.ao_samp_method==WO_AOSAMP_HALTON) 
+	if (R.wrld.ao_samp_method==WO_AOSAMP_HALTON) {
+		float speedfac;
+		
+		speedfac = get_avg_speed(shi) * adapt_speed_fac;
+		CLAMP(speedfac, 1.0, 1000.0);
+		max_samples /= speedfac;
+		if (max_samples < 5) max_samples = 5;
+		
 		qsa = QMC_initSampler(SAMP_TYPE_HALTON, max_samples);
-	else if (R.wrld.ao_samp_method==WO_AOSAMP_HAMMERSLEY)
+	} else if (R.wrld.ao_samp_method==WO_AOSAMP_HAMMERSLEY)
 		qsa = R.qsa;
 
 	QMC_initPixel(qsa, shi->thread);
 	
 	while (samples < max_samples) {
 
-		/* sampling, returns quasi-random vector in unit hemisphere */
-		QMC_sampleHemi(samp3d, qsa, shi->thread, samples);
-		
+		if (G.rt==0) {
+			/* sampling, returns quasi-random vector in unit hemisphere */
+			QMC_sampleHemi(samp3d, qsa, shi->thread, samples);
+		} else {
+			/* sampling, returns quasi-random vector in unit hemisphere */
+			QMC_sampleHemiCosine(samp3d, qsa, shi->thread, samples);
+		}
 		dir[0] = (samp3d[0]*up[0] + samp3d[1]*side[0] + samp3d[2]*nrm[0]);
 		dir[1] = (samp3d[0]*up[1] + samp3d[1]*side[1] + samp3d[2]*nrm[1]);
 		dir[2] = (samp3d[0]*up[2] + samp3d[1]*side[2] + samp3d[2]*nrm[2]);

Modified: trunk/blender/source/blender/src/buttons_shading.c
===================================================================
--- trunk/blender/source/blender/src/buttons_shading.c	2007-10-24 11:16:48 UTC (rev 12374)
+++ trunk/blender/source/blender/src/buttons_shading.c	2007-10-24 12:42:08 UTC (rev 12375)
@@ -1923,8 +1923,8 @@
 			scrarea_queue_winredraw(curarea);
 		}
 		break;
-	case B_AO_DISTANCES:
-		/* distances option only supports plain */
+	case B_AO_FALLOFF:
+		/* falloff distances option only supports plain */
 		wrld= G.buts->lockpoin;
 		if(wrld)
 			wrld->aocolor= WO_AOPLAIN;
@@ -2124,54 +2124,88 @@
 static void world_panel_amb_occ(World *wrld)
 {
 	uiBlock *block;
+	short yco=PANEL_YMAX;
 	
 	block= uiNewBlock(&curarea->uiblocks, "world_panel_amb_oc", UI_EMBOSS, UI_HELV, curarea->win);
 	uiNewPanelTabbed("Mist / Stars / Physics", "World");
-	if(uiNewPanel(curarea, block, "Amb Occ", "World", 320, 0, 318, 204)==0) return;
+	if(uiNewPanel(curarea, block, "Amb Occ", "World", PANELX, PANELY, PANELW, PANELH)==0) return;
 
 	uiBlockSetCol(block, TH_BUT_SETTING1);
-	uiDefButBitS(block, TOG, WO_AMB_OCC, B_REDR,	"Ambient Occlusion",10,150,300,19, &wrld->mode, 0, 0, 0, 0, "Toggles ambient occlusion (soft shadows)");
+	uiDefButBitS(block, TOG, WO_AMB_OCC, B_REDR, "Ambient Occlusion",
+		X2CLM1, yco-=BUTH, BUTW1, BUTH, &wrld->mode, 0, 0, 0, 0, "Toggles ambient occlusion (soft shadows)");
 	uiBlockSetCol(block, TH_AUTO);
+	
+	if(!(wrld->mode & WO_AMB_OCC)) return;
+	
+	yco -= YSPACE;
 
-	if(wrld->mode & WO_AMB_OCC) {
+	uiDefButS(block, NUM, B_REDR, "Samples:",
+		X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aosamp, 1.0, 32.0, 100, 0, "Sets the number of samples used for AO  (actual number: squared)");
+	
+	yco -= YSPACE;
+	
+	uiDefButF(block, NUM, B_REDR, "Max Dist:",
+		X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aodist, 0.001, 5000.0, 100, 0, "Sets length of AO rays, defines how far away other faces give occlusion effect");
 
-		/* aolight: samples */
-		uiDefButS(block, MENU, B_REDR, "Constant QMC %x2|Adaptive QMC %x1|Constant Jittered %x0",
-				10, 120, 145, 19, &wrld->ao_samp_method, 0, 0, 0, 0, "Method for generating shadow samples: Constant QMC: best quality, Adaptive QMC: fast in high contrast areas");
-		uiDefButS(block, NUM, B_REDR, "Samples:",
-				165, 120, 145, 19, &wrld->aosamp, 1.0, 32.0, 100, 0, "Sets the number of samples used for AO  (actual number: squared)");
-		
-		if (wrld->ao_samp_method == WO_AOSAMP_HALTON) {
-			uiDefButF(block, NUM, B_REDR, "Threshold:",
-				10, 95, 145, 19, &wrld->ao_adapt_thresh, 0.0, 1.0, 100, 0, "Samples below this threshold will be considered fully shadowed/unshadowed and skipped");
-		}
-		uiDefButF(block, NUM, B_REDR, "Dist:",
-			165, 95, 145, 19, &wrld->aodist, 0.001, 5000.0, 100, 0, "Sets length of AO rays, defines how far away other faces give occlusion effect");
-
+	yco -= YSPACE;
+	
+	uiBlockBeginAlign(block);
+	uiDefButBitS(block, TOG, WO_AODIST, B_AO_FALLOFF, "Use Falloff",
+		X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aomode, 0, 0, 0, 0, "When enabled, distances to objects will be used to attenuate shadows. Only for Plain AO.");
+	if (wrld->aomode & WO_AODIST)
+		uiDefButF(block, NUM, B_REDR, "Strength:",
+			X2CLM1, yco-=BUTH, BUTW2, BUTH, &wrld->aodistfac, 0.00001, 10.0, 100, 0, "Distance attenuation factor, the higher, the 'shorter' the shadows");
+	uiBlockEndAlign(block);
+	
+	/* column 2 */
+	yco = PANEL_YMAX - BUTH - YSPACE;
+	
+	uiDefButS(block, MENU, B_REDR, "Constant QMC %x2|Adaptive QMC %x1|Constant Jittered %x0",
+		X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_samp_method, 0, 0, 0, 0, "Method for generating shadow samples: Constant QMC: best quality, Adaptive QMC: fast in high contrast areas");
+	
+	yco -= YSPACE;
+	
+	if (wrld->ao_samp_method == WO_AOSAMP_HALTON) {	
 		uiBlockBeginAlign(block);
-		uiDefButBitS(block, TOG, WO_AODIST, B_AO_DISTANCES, "Use Distances", 10, 70, 150, 19, &wrld->aomode, 0, 0, 0, 0, "When enabled, distances to objects will be used to attenuate shadows. Only for Plain AO.");
-		/* distance attenuation factor */
-		if (wrld->aomode & WO_AODIST)
-			uiDefButF(block, NUM, B_REDR, "DistF:", 160, 70, 150, 19, &wrld->aodistfac, 0.00001, 10.0, 100, 0, "Distance factor, the higher, the 'shorter' the shadows");
+		uiDefButF(block, NUM, B_REDR, "Threshold:",
+			X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_adapt_thresh, 0.0, 1.0, 100, 0, "Samples below this threshold will be considered fully shadowed/unshadowed and skipped");
+		uiDefButF(block, NUMSLI, B_REDR, "Adapt Vec:",
+			X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->ao_adapt_speed_fac, 0.0, 1.0, 100, 0, "Use the speed vector pass to reduce AO samples in fast moving pixels. The higher the value, the more aggressive the sample reduction. Requires Vec pass enabled.");
+		uiBlockEndAlign(block);
+	} else if (wrld->ao_samp_method == WO_AOSAMP_CONSTANT) {
+		uiDefButF(block, NUMSLI, B_REDR, "Bias:",
+			X2CLM2, yco-=BUTH, BUTW2, BUTH, &wrld->aobias, 0.0, 0.5, 10, 0, "Sets bias to prevent smoothed faces to show banding (in radians)");
+	}
 
-		/* result mix modes */
-		uiBlockBeginAlign(block);
-		uiDefButS(block, ROW, B_REDR, "Add", 10, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOADD, 0, 0, "adds light/shadows");
-		uiDefButS(block, ROW, B_REDR, "Sub", 110, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOSUB, 0, 0, "subtracts light/shadows (needs at least one normal light to make anything visible)");
-		uiDefButS(block, ROW, B_REDR, "Both", 210, 45, 100, 20, &wrld->aomix, 1.0, (float)WO_AOADDSUB, 0, 0, "both lightens & darkens");
 
-		/* color treatment */
-		uiBlockBeginAlign(block);
-		uiDefButS(block, ROW, B_REDR, "Plain", 10, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOPLAIN, 0, 0, "Plain diffuse energy (white)");
-		uiDefButS(block, ROW, B_REDR, "Sky Color", 110, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOSKYCOL, 0, 0, "Use horizon and zenith color for diffuse energy");
-		uiDefButS(block, ROW, B_REDR, "Sky Texture", 210, 25, 100, 20, &wrld->aocolor, 2.0, (float)WO_AOSKYTEX, 0, 0, "Does full Sky texture render for diffuse energy");
-		
-		uiBlockBeginAlign(block);
-		uiDefButF(block, NUMSLI, B_REDR, "Energy:", 10, 0, 150, 19, &wrld->aoenergy, 0.01, 3.0, 100, 0, "Sets global energy scale for AO");
-		if (wrld->ao_samp_method == WO_AOSAMP_CONSTANT)

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list