[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [26737] trunk/blender/source/blender/ render/intern/source: Shadow Buffers:

Brecht Van Lommel brecht at blender.org
Tue Feb 9 14:58:07 CET 2010


Revision: 26737
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=26737
Author:   blendix
Date:     2010-02-09 14:58:07 +0100 (Tue, 09 Feb 2010)

Log Message:
-----------
Shadow Buffers:

* Bugfix, rasterization was shifted half a pixel.
* Remove scaling of bias by render size, there is something to be
  said for doing to compensate for lower shadow buffer xy resolution,
  however the z-resolution does not change and this seems to have a
  larger effect.
* Remove clamping of filter size by soft factor. Now it is clamped to
  1 pixel instead to ensure there is some AA. Why this was done this
  way is not clear to me, however on decreasing shadow buffer resolution
  this would change the softness by increasing the filter size.

Modified Paths:
--------------
    trunk/blender/source/blender/render/intern/source/convertblender.c
    trunk/blender/source/blender/render/intern/source/shadbuf.c
    trunk/blender/source/blender/render/intern/source/zbuf.c

Modified: trunk/blender/source/blender/render/intern/source/convertblender.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/convertblender.c	2010-02-09 12:06:04 UTC (rev 26736)
+++ trunk/blender/source/blender/render/intern/source/convertblender.c	2010-02-09 13:58:07 UTC (rev 26737)
@@ -3407,7 +3407,7 @@
 	/* bias is percentage, made 2x larger because of correction for angle of incidence */
 	/* when a ray is closer to parallel of a face, bias value is increased during render */
 	shb->bias= (0.02*lar->bias)*0x7FFFFFFF;
-	shb->bias= shb->bias*(100/re->r.size);
+	shb->bias= shb->bias;
 	
 	/* halfway method (average of first and 2nd z) reduces bias issues */
 	if(ELEM(lar->buftype, LA_SHADBUF_HALFWAY, LA_SHADBUF_DEEP))

Modified: trunk/blender/source/blender/render/intern/source/shadbuf.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/shadbuf.c	2010-02-09 12:06:04 UTC (rev 26736)
+++ trunk/blender/source/blender/render/intern/source/shadbuf.c	2010-02-09 13:58:07 UTC (rev 26737)
@@ -1086,13 +1086,27 @@
 	}
 }
 
+static void shadowbuf_project_co(float *x, float *y, float *z, ShadBuf *shb, float co[3])
+{
+	float hco[4], size= 0.5f*(float)shb->size;
+
+	copy_v3_v3(hco, co);
+	hco[3]= 1.0f;
+
+	mul_m4_v4(shb->persmat, hco);
+
+	*x= size*(1.0f+hco[0]/hco[3]);
+	*y= size*(1.0f+hco[1]/hco[3]);
+	if(z) *z= (hco[2]/hco[3]);
+}
+
 /* the externally called shadow testing (reading) function */
 /* return 1.0: no shadow at all */
-float testshadowbuf(Render *re, ShadBuf *shb, float *rco, float *dxco, float *dyco, float inp, float mat_bias)
+float testshadowbuf(Render *re, ShadBuf *shb, float *co, float *dxco, float *dyco, float inp, float mat_bias)
 {
 	ShadSampleBuf *shsample;
-	float fac, co[4], dx[3], dy[3], shadfac=0.0f;
-	float xs1,ys1, siz, *jit, *weight, xres, yres, biasf;
+	float fac, dco[3], dx[3], dy[3], shadfac=0.0f;
+	float xs1, ys1, zs1, *jit, *weight, xres, yres, biasf;
 	int xs, ys, zs, bias, *rz;
 	short a, num;
 	
@@ -1100,42 +1114,35 @@
 	if(shb->buffers.first==NULL)
 		return 1.0f;
 	
-	if(inp <= 0.0f) return 0.0f;
+	/* when facing away, assume fully in shadow */
+	if(inp <= 0.0f)
+		return 0.0f;
 
-	/* rotate renderco en osaco */
-	siz= 0.5f*(float)shb->size;
-	VECCOPY(co, rco);
-	co[3]= 1.0f;
+	/* project coordinate to pixel space */
+	shadowbuf_project_co(&xs1, &ys1, &zs1, shb, co);
 
-	mul_m4_v4(shb->persmat, co);	/* rational hom co */
-
-	xs1= siz*(1.0f+co[0]/co[3]);
-	ys1= siz*(1.0f+co[1]/co[3]);
-
-	/* Clip for z: clipsta and clipend clip values of the shadow buffer. We
-		* can test for -1.0/1.0 because of the properties of the
-		* coordinate transformations. */
-	fac= (co[2]/co[3]);
-
-	if(fac>=1.0f) {
+	/* clip z coordinate, z is projected so that (-1.0, 1.0) matches
+	   (clipstart, clipend), so we can do this simple test */
+	if(zs1>=1.0f)
 		return 0.0f;
-	} else if(fac<= -1.0f) {
+	else if(zs1<= -1.0f)
 		return 1.0f;
-	}
 
-	zs= ((float)0x7FFFFFFF)*fac;
+	zs= ((float)0x7FFFFFFF)*zs1;
 
 	/* take num*num samples, increase area with fac */
 	num= get_render_shadow_samples(&re->r, shb->samp);
 	num= num*num;
 	fac= shb->soft;
 	
+	/* compute z bias */
 	if(mat_bias!=0.0f) biasf= shb->bias*mat_bias;
 	else biasf= shb->bias;
 	/* with inp==1.0, bias is half the size. correction value was 1.1, giving errors 
 	   on cube edges, with one side being almost frontal lighted (ton)  */
 	bias= (1.5f-inp*inp)*biasf;
 	
+	/* in case of no filtering we can do things simpler */
 	if(num==1) {
 		for(shsample= shb->buffers.first; shsample; shsample= shsample->next)
 			shadfac += readshadowbuf(shb, shsample, bias, (int)xs1, (int)ys1, zs);
@@ -1144,30 +1151,26 @@
 	}
 
 	/* calculate filter size */
-	co[0]= rco[0]+dxco[0];
-	co[1]= rco[1]+dxco[1];
-	co[2]= rco[2]+dxco[2];
-	co[3]= 1.0;
-	mul_m4_v4(shb->persmat,co);     /* rational hom co */
-	dx[0]= xs1- siz*(1.0+co[0]/co[3]);
-	dx[1]= ys1- siz*(1.0+co[1]/co[3]);
+	add_v3_v3v3(dco, co, dxco);
+	shadowbuf_project_co(&dx[0], &dx[1], NULL, shb, dco);
+	dx[0]= xs1 - dx[0];
+	dx[1]= ys1 - dx[1];
+
+	add_v3_v3v3(dco, co, dyco);
+	shadowbuf_project_co(&dy[0], &dy[1], NULL, shb, dco);
+	dy[0]= xs1 - dy[0];
+	dy[1]= ys1 - dy[1];
 	
-	co[0]= rco[0]+dyco[0];
-	co[1]= rco[1]+dyco[1];
-	co[2]= rco[2]+dyco[2];
-	co[3]= 1.0;
-	mul_m4_v4(shb->persmat,co);     /* rational hom co */
-	dy[0]= xs1- siz*(1.0+co[0]/co[3]);
-	dy[1]= ys1- siz*(1.0+co[1]/co[3]);
+	xres= fac*(fabs(dx[0]) + fabs(dy[0]));
+	yres= fac*(fabs(dx[1]) + fabs(dy[1]));
+	if(xres<1.0f) xres= 1.0f;
+	if(yres<1.0f) yres= 1.0f;
 	
-	xres= fac*( fabs(dx[0])+fabs(dy[0]) );
-	yres= fac*( fabs(dx[1])+fabs(dy[1]) );
-	if(xres<fac) xres= fac;
-	if(yres<fac) yres= fac;
-	
-	xs1-= (xres)/2;
-	ys1-= (yres)/2;
+	/* make xs1/xs1 corner of sample area */
+	xs1 -= xres*0.5f;
+	ys1 -= yres*0.5f;
 
+	/* in case we have a constant value in a tile, we can do quicker lookup */
 	if(xres<16.0f && yres<16.0f) {
 		shsample= shb->buffers.first;
 	    if(firstreadshadbuf(shb, shsample, &rz, (int)xs1, (int)ys1, 0)) {
@@ -1181,6 +1184,7 @@
 	    }
 	}
 	
+	/* full jittered shadow buffer lookup */
 	for(shsample= shb->buffers.first; shsample; shsample= shsample->next) {
 		jit= shb->jit;
 		weight= shb->weight;

Modified: trunk/blender/source/blender/render/intern/source/zbuf.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/zbuf.c	2010-02-09 12:06:04 UTC (rev 26736)
+++ trunk/blender/source/blender/render/intern/source/zbuf.c	2010-02-09 13:58:07 UTC (rev 26737)
@@ -2288,8 +2288,9 @@
 	zbuf_alloc_span(&zspan, size, size, 1.0f);
 	zspan.zmulx=  ((float)size)/2.0;
 	zspan.zmuly=  ((float)size)/2.0;
-	zspan.zofsx= jitx;
-	zspan.zofsy= jity;
+	/* -0.5f to center the sample position */
+	zspan.zofsx= jitx - 0.5f;
+	zspan.zofsy= jity - 0.5f;
 	
 	/* the buffers */
 	zspan.rectz= rectz;
@@ -3280,11 +3281,9 @@
 			zspan->zofsy= -pa->disprect.ymin;
 		}
 
-		if(!shadow) {
-			/* to center the sample position */
-			zspan->zofsx -= 0.5f;
-			zspan->zofsy -= 0.5f;
-		}
+		/* to center the sample position */
+		zspan->zofsx -= 0.5f;
+		zspan->zofsy -= 0.5f;
 	}
 	
 	/* we use this to test if nothing was filled in */





More information about the Bf-blender-cvs mailing list