Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2010-02-09 16:58:07 +0300
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2010-02-09 16:58:07 +0300
commitce38137449790daa5395045b06d029bf4fd71cf7 (patch)
tree7bccd5c524b644990a42a468ef5c33b10f5490a2 /source/blender/render
parent7d2d5c990f594fc4cd96b3ae34c8acca5b960a93 (diff)
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.
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/intern/source/convertblender.c2
-rw-r--r--source/blender/render/intern/source/shadbuf.c96
-rw-r--r--source/blender/render/intern/source/zbuf.c13
3 files changed, 57 insertions, 54 deletions
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 0b818ca761e..d05d88266c7 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -3407,7 +3407,7 @@ static void initshadowbuf(Render *re, LampRen *lar, float mat[][4])
/* 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))
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index f8428680135..a0f305ae609 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -1086,13 +1086,27 @@ static float readshadowbuf(ShadBuf *shb, ShadSampleBuf *shsample, int bias, int
}
}
+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 @@ float testshadowbuf(Render *re, ShadBuf *shb, float *rco, float *dxco, float *dy
if(shb->buffers.first==NULL)
return 1.0f;
- if(inp <= 0.0f) return 0.0f;
-
- /* rotate renderco en osaco */
- siz= 0.5f*(float)shb->size;
- VECCOPY(co, rco);
- co[3]= 1.0f;
-
- 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]);
+ /* when facing away, assume fully in shadow */
+ if(inp <= 0.0f)
+ return 0.0f;
- /* 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]);
+ /* project coordinate to pixel space */
+ shadowbuf_project_co(&xs1, &ys1, &zs1, shb, co);
- 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 @@ float testshadowbuf(Render *re, ShadBuf *shb, float *rco, float *dxco, float *dy
}
/* 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]);
-
- 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<fac) xres= fac;
- if(yres<fac) yres= fac;
-
- xs1-= (xres)/2;
- ys1-= (yres)/2;
-
+ 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];
+
+ 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;
+
+ /* 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 @@ float testshadowbuf(Render *re, ShadBuf *shb, float *rco, float *dxco, float *dy
}
}
+ /* full jittered shadow buffer lookup */
for(shsample= shb->buffers.first; shsample; shsample= shsample->next) {
jit= shb->jit;
weight= shb->weight;
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 612c5660f68..8753126fd72 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -2288,8 +2288,9 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
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 @@ static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *
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 */