diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadbuf.c | 96 | ||||
-rw-r--r-- | source/blender/render/intern/source/zbuf.c | 13 |
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 */ |