diff options
author | Ton Roosendaal <ton@blender.org> | 2004-05-15 22:07:09 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2004-05-15 22:07:09 +0400 |
commit | a4861c37bee39d201423dd9d44a116b60bdd3298 (patch) | |
tree | 64461d36f5a37fb8dcad06324d6afbb34547495c /source/blender | |
parent | b4ecf7d973d2a89162fea1571cbc0fbd565cf946 (diff) |
Assuming the freeze is over and we can head towards 2.34: this is the
first commit for review and improvements on OSA (anti aliasing) in
Blender.
http://www.blender3d.org/cms/Rendering_engine.320.0.html
Most relevant changes:
- full check on subpixel sample locations
- all subpixels are fully rendered (gives spec AA, procedural texture AA)
- also unified render uses it
- removed double-used code for unified render
Whether or not this will be optional (better pics, but in some cases slow)
is to further evaluate. For raytracing - for example - this cannot be simply
done, since the new sampling system made raytrace code much simpler.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/render/intern/source/initrender.c | 65 | ||||
-rw-r--r-- | source/blender/render/intern/source/jitter.c | 10 | ||||
-rw-r--r-- | source/blender/render/intern/source/ray.c | 374 | ||||
-rw-r--r-- | source/blender/render/intern/source/rendercore.c | 107 | ||||
-rw-r--r-- | source/blender/render/intern/source/vanillaRenderPipe.c | 17 | ||||
-rw-r--r-- | source/blender/render/intern/source/zbuf.c | 104 | ||||
-rw-r--r-- | source/blender/render/intern/source/zbufferdatastruct.c | 2 |
7 files changed, 251 insertions, 428 deletions
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 1b61a28af20..dc5bb340340 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -94,7 +94,7 @@ #include "zbuf.h" #include "rendercore.h" /* part handler for the old renderer, shading functions */ #include "renderPreAndPost.h" -#include "outerRenderLoop.h" +#include "vanillaRenderPipe.h" #include "renderHelp.h" #include "jitter.h" @@ -178,8 +178,8 @@ float calc_weight(float *weight, int i, int j) fac*= fac; for(a=0; a<R.osa; a++) { - x= jit[a][0]-0.5+ i; - y= jit[a][1]-0.5+ j; + x= jit[a][0] + i; + y= jit[a][1] + j; dist= sqrt(x*x+y*y); weight[a]= 0.0; @@ -410,9 +410,11 @@ void RE_init_filt_mask(void) for(a= (1<<R.osa)-1; a>0; a--) { val= count_mask(a); - i= (15.9*(fpy1[a & 255]+fpy2[a>>8])/val); - i<<=4; - i+= (15.9*(fpx1[a & 255]+fpx2[a>>8])/val); + i= 8+(15.9*(fpy1[a & 255]+fpy2[a>>8])/val); + CLAMP(i, 0, 15); + j= 8+(15.9*(fpx1[a & 255]+fpx2[a>>8])/val); + CLAMP(j, 0, 15); + i= j + (i<<4); centmask[a]= i; } @@ -527,22 +529,15 @@ void RE_setwindowclip(int mode, int jmode) } - /* I think these offsets are wrong. They do not coincide with shadow */ - /* calculations, btw. */ - minx= R.xstart+.5; - miny= R.ycor*(R.ystart+.5); - maxx= R.xend+.4999; - maxy= R.ycor*(R.yend+.4999); - /* My guess: (or rather, what should be) */ - /* minx= R.xstart - 0.5; */ - /* miny= R.ycor * (R.ystart - 0.5); */ - /* Since the SCS-s map directly to the pixel center coordinates, we need */ - /* to stretch the clip area a bit, not just shift it. However, this gives*/ - /* nasty problems for parts... */ - - /* Dunno who wrote previous comment, but I found an error with uncorrected - blur offset in shadepixel(). Now solved with 2 globals, seems to work. - The whole method how to retrieve the correct coordinate needs revision. (ton) */ + /* revision / simplification of subpixel offsets: + - the matrix will go without offset from start (e.g. -100) to end (e.g. +99). + - filling in with zbuffer will set offset of 0.5. to make sure clipped faces fill in too + - in shadepixel() again that 0.5 offset is corrected + */ + minx= R.xstart; + miny= R.ycor*(R.ystart); + maxx= R.xend; + maxy= R.ycor*(R.yend); if(R.flag & R_SEC_FIELD) { if(R.r.mode & R_ODDFIELD) { @@ -766,11 +761,11 @@ void render() { yafrayRender(); else { /* not too neat... should improve... */ - if(R.r.mode & R_UNIFIED) { - unifiedRenderingLoop(); - } else { + //if(R.r.mode & R_UNIFIED) { + // unifiedRenderingLoop(); + //} else { oldRenderLoop(); - } + //} } } @@ -856,21 +851,25 @@ void oldRenderLoop(void) /* here the PART and FIELD loops */ if(RE_local_test_break()) break; - /* ZBUFFER & SHADE: zbuffer stores integer distances, and integer face indices */ + /* rectot is for result and integer face indices */ R.rectot= (unsigned int *)MEM_callocN(sizeof(int)*R.rectx*R.recty, "rectot"); - R.rectz = (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz"); - + if(R.r.mode & R_MBLUR) { RE_local_printrenderinfo(0.0, R.osa - blur); if(G.background && blur<R.osa) printf("\n"); // newline for percentage print } else RE_local_printrenderinfo(0.0, -1); - /* choose render pipeline type, and whether or not to use the */ - /* delta accumulation buffer. 3 choices. */ - if(R.r.mode & R_OSA) zbufshadeDA(); - else zbufshade(); + if(R.r.mode & R_UNIFIED) { + zBufShadeAdvanced(); + } + else { + R.rectz = (unsigned int *)MEM_mallocN(sizeof(int)*R.rectx*R.recty, "rectz"); + if(R.r.mode & R_OSA) zbufshadeDA(); + else zbufshade(); + } + if(RE_local_test_break()) break; /* exception */ diff --git a/source/blender/render/intern/source/jitter.c b/source/blender/render/intern/source/jitter.c index 0254b82bed4..50f465f4932 100644 --- a/source/blender/render/intern/source/jitter.c +++ b/source/blender/render/intern/source/jitter.c @@ -178,19 +178,25 @@ void initjit(float *jitarr, int num) } MEM_freeN(jit2); + + /* finally, move jittertab to be centered around (0,0) */ + for(i=0; i<2*num; i+=2) { + jitarr[i] -= 0.5; + jitarr[i+1] -= 0.5; + } + } void init_render_jit(int nr) { static int lastjit= 0; - + if(lastjit==nr) return; memset(jit, 0, 64*2*4); initjit(jit[0], nr); lastjit= nr; - } /* eof */ diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c index 040c4a00caa..694f27faeb8 100644 --- a/source/blender/render/intern/source/ray.c +++ b/source/blender/render/intern/source/ray.c @@ -1381,40 +1381,6 @@ static void refraction(float *refract, float *n, float *view, float index) refract[2]= index*view[2] + fac*n[2]; } -static void calc_dx_dy_refract(float *ref, float *n, float *view, float index, int smooth) -{ - float dref[3], dview[3], dnor[3]; - - refraction(ref, n, view, index); - - dview[0]= view[0]+ O.dxview; - dview[1]= view[1]; - dview[2]= view[2]; - - if(smooth) { - VECADD(dnor, n, O.dxno); - refraction(dref, dnor, dview, index); - } - else { - refraction(dref, n, dview, index); - } - VECSUB(O.dxrefract, ref, dref); - - dview[0]= view[0]; - dview[1]= view[1]+ O.dyview; - - if(smooth) { - VECADD(dnor, n, O.dyno); - refraction(dref, dnor, dview, index); - } - else { - refraction(dref, n, dview, index); - } - VECSUB(O.dyrefract, ref, dref); - -} - - /* orn = original face normal */ static void reflection(float *ref, float *n, float *view, float *orn) { @@ -1655,9 +1621,13 @@ static float *jitter_plane(LampRen *lar, int xs, int ys) } if(lar->ray_samp_type & LA_SAMP_JITTER) { - static float jitter[2*256]; - jitter_plane_offset(lar->jitter, jitter, tot, lar->area_size, lar->area_sizey, BLI_frand(), BLI_frand()); - return jitter; + static int xold=0, yold=0; + /* new OSA allows to enter this function many times for 1 pixel */ + if(xold!=xs || yold!=ys) { + jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, BLI_frand(), BLI_frand()); + xold= xs; yold= ys; + } + return lar->jitter+2*tot; } if(lar->ray_samp_type & LA_SAMP_DITHER) { return lar->jitter + 2*tot*((xs & 1)+2*(ys & 1)); @@ -1683,128 +1653,42 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr) coh_test= 0; // reset coherence optimize - if(R.r.mode & R_OSA) { - float accum[3], rco[3], ref[3]; - float accur[3], refract[3], divr=0.0, div= 0.0; - int j; - - if(do_tra) calc_dx_dy_refract(refract, shi->vn, shi->view, shi->matren->ang, vlr->flag & R_SMOOTH); - if(do_mir) { - if(vlr->flag & R_SMOOTH) - reflection(ref, shi->vn, shi->view, vlr->n); - else - reflection(ref, shi->vn, shi->view, NULL); - } - - accum[0]= accum[1]= accum[2]= 0.0; - accur[0]= accur[1]= accur[2]= 0.0; - - for(j=0; j<R.osa; j++) { - if(shi->mask & 1<<j) { - - rco[0]= shi->co[0] + (jit[j][0]-0.5)*O.dxco[0] + (jit[j][1]-0.5)*O.dyco[0]; - rco[1]= shi->co[1] + (jit[j][0]-0.5)*O.dxco[1] + (jit[j][1]-0.5)*O.dyco[1]; - rco[2]= shi->co[2] + (jit[j][0]-0.5)*O.dxco[2] + (jit[j][1]-0.5)*O.dyco[2]; - - if(do_tra) { - vec[0]= refract[0] + (jit[j][0]-0.5)*O.dxrefract[0] + (jit[j][1]-0.5)*O.dyrefract[0] ; - vec[1]= refract[1] + (jit[j][0]-0.5)*O.dxrefract[1] + (jit[j][1]-0.5)*O.dyrefract[1] ; - vec[2]= refract[2] + (jit[j][0]-0.5)*O.dxrefract[2] + (jit[j][1]-0.5)*O.dyrefract[2] ; - - traceray(shi->matren->ray_depth_tra, rco, vec, tracol, shi->vlr, shi->mask); - - VECADD(accur, accur, tracol); - divr+= 1.0; - } - - if(do_mir) { - vec[0]= ref[0] + 2.0*(jit[j][0]-0.5)*O.dxref[0] + 2.0*(jit[j][1]-0.5)*O.dyref[0] ; - vec[1]= ref[1] + 2.0*(jit[j][0]-0.5)*O.dxref[1] + 2.0*(jit[j][1]-0.5)*O.dyref[1] ; - vec[2]= ref[2] + 2.0*(jit[j][0]-0.5)*O.dxref[2] + 2.0*(jit[j][1]-0.5)*O.dyref[2] ; - - /* prevent normal go to backside */ - i= vec[0]*vlr->n[0]+ vec[1]*vlr->n[1]+ vec[2]*vlr->n[2]; - if(i>0.0) { - i+= .01; - vec[0]-= i*vlr->n[0]; - vec[1]-= i*vlr->n[1]; - vec[2]-= i*vlr->n[2]; - } - - /* we use a new mask here, only shadow uses it */ - /* result in accum, this is copied to shade_lamp_loop */ - traceray(shi->matren->ray_depth, rco, vec, mircol, shi->vlr, 1<<j); - - VECADD(accum, accum, mircol); - div+= 1.0; - } - } - } + if(do_tra) { + float refract[3]; - if(divr!=0.0) { - f= shr->alpha; f1= 1.0-f; f1/= divr; - shr->diff[0]= f*shr->diff[0] + f1*accur[0]; - shr->diff[1]= f*shr->diff[1] + f1*accur[1]; - shr->diff[2]= f*shr->diff[2] + f1*accur[2]; - shr->alpha= 1.0; - } + refraction(refract, shi->vn, shi->view, shi->matren->ang); + traceray(shi->matren->ray_depth_tra, shi->co, refract, tracol, shi->vlr, shi->mask); - if(div!=0.0) { - i= shi->matren->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->matren->fresnel_mir_i, shi->matren->fresnel_mir); + f= shr->alpha; f1= 1.0-f; + shr->diff[0]= f*shr->diff[0] + f1*tracol[0]; + shr->diff[1]= f*shr->diff[1] + f1*tracol[1]; + shr->diff[2]= f*shr->diff[2] + f1*tracol[2]; + shr->alpha= 1.0; + } + + if(do_mir) { + + i= shi->matren->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->matren->fresnel_mir_i, shi->matren->fresnel_mir); + if(i!=0.0) { fr= shi->matren->mirr; fg= shi->matren->mirg; fb= shi->matren->mirb; + + if(vlr->flag & R_SMOOTH) + reflection(vec, shi->vn, shi->view, vlr->n); + else + reflection(vec, shi->vn, shi->view, NULL); - /* result */ - f= i*fr*(1.0-shr->spec[0]); f1= 1.0-i; f/= div; - shr->diff[0]= f*accum[0] + f1*shr->diff[0]; - - f= i*fg*(1.0-shr->spec[1]); f1= 1.0-i; f/= div; - shr->diff[1]= f*accum[1] + f1*shr->diff[1]; + traceray(shi->matren->ray_depth, shi->co, vec, mircol, shi->vlr, shi->mask); - f= i*fb*(1.0-shr->spec[2]); f1= 1.0-i; f/= div; - shr->diff[2]= f*accum[2] + f1*shr->diff[2]; - } - } - else { - - if(do_tra) { - float refract[3]; + f= i*fr*(1.0-shr->spec[0]); f1= 1.0-i; + shr->diff[0]= f*mircol[0] + f1*shr->diff[0]; - refraction(refract, shi->vn, shi->view, shi->matren->ang); - traceray(shi->matren->ray_depth_tra, shi->co, refract, tracol, shi->vlr, shi->mask); + f= i*fg*(1.0-shr->spec[1]); f1= 1.0-i; + shr->diff[1]= f*mircol[1] + f1*shr->diff[1]; - f= shr->alpha; f1= 1.0-f; - shr->diff[0]= f*shr->diff[0] + f1*tracol[0]; - shr->diff[1]= f*shr->diff[1] + f1*tracol[1]; - shr->diff[2]= f*shr->diff[2] + f1*tracol[2]; - shr->alpha= 1.0; - } - - if(do_mir) { - - i= shi->matren->ray_mirror*fresnel_fac(shi->view, shi->vn, shi->matren->fresnel_mir_i, shi->matren->fresnel_mir); - if(i!=0.0) { - fr= shi->matren->mirr; - fg= shi->matren->mirg; - fb= shi->matren->mirb; - - if(vlr->flag & R_SMOOTH) - reflection(vec, shi->vn, shi->view, vlr->n); - else - reflection(vec, shi->vn, shi->view, NULL); - - traceray(shi->matren->ray_depth, shi->co, vec, mircol, shi->vlr, shi->mask); - - f= i*fr*(1.0-shr->spec[0]); f1= 1.0-i; - shr->diff[0]= f*mircol[0] + f1*shr->diff[0]; - - f= i*fg*(1.0-shr->spec[1]); f1= 1.0-i; - shr->diff[1]= f*mircol[1] + f1*shr->diff[1]; - - f= i*fb*(1.0-shr->spec[2]); f1= 1.0-i; - shr->diff[2]= f*mircol[2] + f1*shr->diff[2]; - } + f= i*fb*(1.0-shr->spec[2]); f1= 1.0-i; + shr->diff[2]= f*mircol[2] + f1*shr->diff[2]; } } } @@ -1971,10 +1855,10 @@ static void DistributedSpherical(float *sphere, int tot, int iter) } } -static float *sphere_sampler(int type, int resol, float *nrm) +static float *sphere_sampler(int type, int resol, int xs, int ys) { static float sphere[2*3*256], sphere1[2*3*256]; - static int last_distr= 0, tot; + int tot; float *vec; if(resol>16) return sphere; @@ -1991,6 +1875,7 @@ static float *sphere_sampler(int type, int resol, float *nrm) } } else { + static int last_distr= 0, xold=0xffff, yold=0; float cosf, sinf, cost, sint; float ang, *vec1; int a; @@ -1998,67 +1883,25 @@ static float *sphere_sampler(int type, int resol, float *nrm) if(last_distr!=resol) DistributedSpherical(sphere, tot, 16); last_distr= resol; - // random rotation - ang= BLI_frand(); - sinf= sin(ang); cosf= cos(ang); - ang= BLI_frand(); - sint= sin(ang); cost= cos(ang); - - vec= sphere; - vec1= sphere1; - for (a=0; a<tot; a++, vec+=3, vec1+=3) { - vec1[0]= cost*cosf*vec[0] - sinf*vec[1] + sint*cosf*vec[2]; - vec1[1]= cost*sinf*vec[0] + cosf*vec[1] + sint*sinf*vec[2]; - vec1[2]= -sint*vec[0] + cost*vec[2]; - } - return sphere1; - } -#if 0 - { /* stratified uniform sampling */ - float gdiv = 1.0/resol; - float gdiv2p = gdiv*2.0*M_PI; - float d, z1, z2, sqz1, sz2, cz2; - float ru[3], rv[3]; - int x, y; - - last_distr= 0; - - - /* calculate the two perpendicular vectors */ - if ((nrm[0]==0.0) && (nrm[1]==0.0)) { - if (nrm[2]<0) ru[0]=-1; else ru[0]=1; - ru[1] = ru[2] = 0; - rv[0] = rv[2] = 0; - rv[1] = 1; - } - else { - ru[0] = nrm[1]; - ru[1] = -nrm[0]; - ru[2] = 0.0; - d = ru[0]*ru[0] + ru[1]*ru[1]; - if (d!=0) { - d = 1.0/sqrt(d); - ru[0] *= d; - ru[1] *= d; - } - Crossf(rv, nrm, ru); - } - - vec= sphere; - for (x=0; x<resol; x++) { - for (y=0; y<resol; y++, vec+=3) { - z1 = (x + BLI_frand()) * gdiv; - z2 = (y + BLI_frand()) * gdiv2p; - if ((sqz1 = 1.0-z1*z1)<0) sqz1=0; else sqz1=sqrt(sqz1); - sz2 = sin(z2); - cz2 = cos(z2); - vec[0] = sqz1*(cz2*ru[0] + sz2*rv[0]) + nrm[0]*z1; - vec[1] = sqz1*(cz2*ru[1] + sz2*rv[1]) + nrm[1]*z1; - vec[2] = sqz1*(cz2*ru[2] + sz2*rv[2]) + nrm[2]*z1; + if(xold!=xs || yold!=ys) { + xold=xs; yold=ys; + + // random rotation + ang= BLI_frand(); + sinf= sin(ang); cosf= cos(ang); + ang= BLI_frand(); + sint= sin(ang); cost= cos(ang); + + vec= sphere; + vec1= sphere1; + for (a=0; a<tot; a++, vec+=3, vec1+=3) { + vec1[0]= cost*cosf*vec[0] - sinf*vec[1] + sint*cosf*vec[2]; + vec1[1]= cost*sinf*vec[0] + cosf*vec[1] + sint*sinf*vec[2]; + vec1[2]= -sint*vec[0] + cost*vec[2]; } } + return sphere1; } -#endif return sphere; } @@ -2097,7 +1940,7 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac) nrm= shi->vlr->n; } - vec= sphere_sampler(wrld->aomode, wrld->aosamp, nrm); + vec= sphere_sampler(wrld->aomode, wrld->aosamp, floor(shi->xs+0.5), floor(shi->ys+0.5) ); // warning: since we use full sphere now, and dotproduct is below, we do twice as much tot= 2*wrld->aosamp*wrld->aosamp; @@ -2117,6 +1960,7 @@ void ray_ao(ShadeInput *shi, World *wrld, float *shadfac) actual++; + /* always set start/end, 3dda clips it */ VECCOPY(isec.start, shi->co); isec.end[0] = shi->co[0] - maxdist*vec[0]; isec.end[1] = shi->co[1] - maxdist*vec[1]; @@ -2171,7 +2015,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) { Isect isec; Material stored; - float fac, div=0.0, lampco[3]; + float lampco[3]; if(shi->matren->mode & MA_SHADOW_TRA) { isec.mode= DDA_SHADOW_TRA; @@ -2194,108 +2038,76 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac) /* shadow and soft not implemented yet */ if(lar->ray_totsamp<2 || isec.mode == DDA_SHADOW_TRA) { - if(R.r.mode & R_OSA) { - float accum[4]={0.0, 0.0, 0.0, 0.0}; - int j; - - fac= 0.0; - - for(j=0; j<R.osa; j++) { - if(shi->mask & 1<<j) { - /* set up isec */ - isec.start[0]= shi->co[0] + (jit[j][0]-0.5)*O.dxco[0] + (jit[j][1]-0.5)*O.dyco[0] ; - isec.start[1]= shi->co[1] + (jit[j][0]-0.5)*O.dxco[1] + (jit[j][1]-0.5)*O.dyco[1] ; - isec.start[2]= shi->co[2] + (jit[j][0]-0.5)*O.dxco[2] + (jit[j][1]-0.5)*O.dyco[2] ; - VECCOPY(isec.end, lampco); - isec.vlrorig= shi->vlr; - - if(isec.mode==DDA_SHADOW_TRA) { - isec.col[0]= isec.col[1]= isec.col[2]= 1.0; - isec.col[3]= 0.0; //alpha - - ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA); - - accum[0]+= isec.col[0]; accum[1]+= isec.col[1]; - accum[2]+= isec.col[2]; accum[3]+= isec.col[3]; - } - else if( d3dda(&isec) ) fac+= 1.0; - div+= 1.0; - } - } - if(isec.mode==DDA_SHADOW_TRA) { - // alpha to 'light' - accum[3]/= div; - shadfac[3]= 1.0-accum[3]; - shadfac[0]= shadfac[3]+accum[0]*accum[3]/div; - shadfac[1]= shadfac[3]+accum[1]*accum[3]/div; - shadfac[2]= shadfac[3]+accum[2]*accum[3]/div; - } - else shadfac[3]= 1.0-fac/div; - } - else { - /* set up isec */ - VECCOPY(isec.start, shi->co); - VECCOPY(isec.end, lampco); - isec.vlrorig= shi->vlr; + /* set up isec */ + VECCOPY(isec.start, shi->co); + VECCOPY(isec.end, lampco); + isec.vlrorig= shi->vlr; - if(isec.mode==DDA_SHADOW_TRA) { - isec.col[0]= isec.col[1]= isec.col[2]= 1.0; - isec.col[3]= 0.0; //alpha + if(isec.mode==DDA_SHADOW_TRA) { + isec.col[0]= isec.col[1]= isec.col[2]= 1.0; + isec.col[3]= 0.0; //alpha - ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA); + ray_trace_shadow_tra(&isec, DEPTH_SHADOW_TRA); - VECCOPY(shadfac, isec.col); - // alpha to 'light' - shadfac[3]= 1.0-isec.col[3]; - shadfac[0]= shadfac[3]+shadfac[0]*isec.col[3]; - shadfac[1]= shadfac[3]+shadfac[1]*isec.col[3]; - shadfac[2]= shadfac[3]+shadfac[2]*isec.col[3]; - } - else if( d3dda(&isec)) shadfac[3]= 0.0; + VECCOPY(shadfac, isec.col); + // alpha to 'light' + shadfac[3]= 1.0-isec.col[3]; + shadfac[0]= shadfac[3]+shadfac[0]*isec.col[3]; + shadfac[1]= shadfac[3]+shadfac[1]*isec.col[3]; + shadfac[2]= shadfac[3]+shadfac[2]*isec.col[3]; } + else if( d3dda(&isec)) shadfac[3]= 0.0; } else { /* area soft shadow */ float *jitlamp; - float vec[3]; - int a, j=0; + float fac=0.0, div=0.0, vec[3]; + int a, j= -1, mask; isec.vlrorig= shi->vlr; fac= 0.0; - jitlamp= jitter_plane(lar, floor(shi->xs), floor(shi->ys)); + jitlamp= jitter_plane(lar, floor(shi->xs+0.5), floor(shi->ys+0.5)); a= lar->ray_totsamp; + /* this correction to make sure we always take at least 1 sample */ + mask= shi->mask; + if(a==4) mask |= (mask>>4)|(mask>>8); + else if(a==9) mask |= (mask>>9); + while(a--) { + if(R.r.mode & R_OSA) { + j++; + if(j>=R.osa) j= 0; + if(!(mask & (1<<j))) { + jitlamp+= 2; + continue; + } + } + vec[0]= jitlamp[0]; vec[1]= jitlamp[1]; vec[2]= 0.0; Mat3MulVecfl(lar->mat, vec); + /* set start and end, d3dda clips it */ VECCOPY(isec.start, shi->co); isec.end[0]= lampco[0]+vec[0]; isec.end[1]= lampco[1]+vec[1]; isec.end[2]= lampco[2]+vec[2]; - if(R.r.mode & R_OSA) { - isec.start[0]= shi->co[0] + (jit[j][0]-0.5)*O.dxco[0] + (jit[j][1]-0.5)*O.dyco[0] ; - isec.start[1]= shi->co[1] + (jit[j][0]-0.5)*O.dxco[1] + (jit[j][1]-0.5)*O.dyco[1] ; - isec.start[2]= shi->co[2] + (jit[j][0]-0.5)*O.dxco[2] + (jit[j][1]-0.5)*O.dyco[2] ; - j++; - if(j>=R.osa) j= 0; - } - if( d3dda(&isec) ) fac+= 1.0; - + div+= 1.0; jitlamp+= 2; } + // sqrt makes nice umbra effect if(lar->ray_samp_type & LA_SAMP_UMBRA) - shadfac[3]= sqrt(1.0-fac/((float)lar->ray_totsamp)); + shadfac[3]= sqrt(1.0-fac/div); else - shadfac[3]= 1.0-fac/((float)lar->ray_totsamp); + shadfac[3]= 1.0-fac/div; } if(shi->matren->mode & MA_SHADOW_TRA) { diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 24ef5d6dd0c..854a32e0fbc 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -349,13 +349,13 @@ void scanlinesky(char *rect, int y) view[2]= 0.0; } else { - view[0]= (x+(R.xstart)+1.0); + view[0]= (x+(R.xstart)+0.5); if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart+0.5)*R.ycor; - else view[1]= (y+R.ystart+1.5)*R.ycor; + if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor; + else view[1]= (y+R.ystart+1.0)*R.ycor; } - else view[1]= (y+R.ystart+1.0)*R.ycor; + else view[1]= (y+R.ystart+0.5)*R.ycor; view[2]= -R.viewfac; @@ -2392,13 +2392,13 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col) dvlak= v1->co[0]*vlr->n[0]+v1->co[1]*vlr->n[1]+v1->co[2]*vlr->n[2]; /* COXYZ AND VIEW VECTOR */ - shi.view[0]= (x+(R.xstart)+1.0+bluroffsx); + shi.view[0]= (x+(R.xstart)+bluroffsx +0.5); if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_ODDFIELD) shi.view[1]= (y+R.ystart+0.5)*R.ycor; - else shi.view[1]= (y+R.ystart+1.5)*R.ycor; + if(R.r.mode & R_ODDFIELD) shi.view[1]= (y+R.ystart)*R.ycor; + else shi.view[1]= (y+R.ystart+1.0)*R.ycor; } - else shi.view[1]= (y+R.ystart+1.0+bluroffsy)*R.ycor; + else shi.view[1]= (y+R.ystart+bluroffsy+0.5)*R.ycor; shi.view[2]= -R.viewfac; @@ -2565,13 +2565,13 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col) if(R.flag & R_LAMPHALO) { if(vlaknr<=0) { /* calc view vector and put shi.co at far */ - shi.view[0]= (x+(R.xstart)+1.0); + shi.view[0]= (x+(R.xstart)+0.5); if(R.flag & R_SEC_FIELD) { - if(R.r.mode & R_ODDFIELD) shi.view[1]= (y+R.ystart+0.5)*R.ycor; - else shi.view[1]= (y+R.ystart+1.5)*R.ycor; + if(R.r.mode & R_ODDFIELD) shi.view[1]= (y+R.ystart)*R.ycor; + else shi.view[1]= (y+R.ystart+1.0)*R.ycor; } - else shi.view[1]= (y+R.ystart+1.0)*R.ycor; + else shi.view[1]= (y+R.ystart+0.5)*R.ycor; shi.view[2]= -R.viewfac; @@ -2599,7 +2599,7 @@ void shadepixel_short(float x, float y, int vlaknr, int mask, unsigned short *sh float colf[4]; shadepixel(x, y, vlaknr, mask, colf); - + if(colf[0]<=0.0) shortcol[0]= 0; else if(colf[0]>=1.0) shortcol[0]= 65535; else shortcol[0]= 65535.0*colf[0]; if(colf[1]<=0.0) shortcol[1]= 0; else if(colf[1]>=1.0) shortcol[1]= 65535; @@ -2660,16 +2660,14 @@ void addps(long *rd, int vlak, unsigned int z, short ronde) { static PixStr *prev; PixStr *ps, *last = NULL; - int vlakand; if( IS_A_POINTER_CODE(*rd)) { ps= (PixStr *) POINTER_FROM_CODE(*rd); - vlakand= (vlak & 0x7FFFFF); - if( (ps->vlak0 & 0x7FFFFF) == vlakand ) return; + if(ps->vlak0==vlak) return; while(ps) { - if( (ps->vlak & 0x7FFFFF) == vlakand ) { + if( ps->vlak == vlak ) { ps->mask |= (1<<ronde); return; } @@ -2871,8 +2869,8 @@ void zbufshadeDA(void) /* Delta Accum Pixel Struct */ xd= jit[v][0]; yd= jit[v][1]; - Zjitx= -xd; - Zjity= -yd; + Zjitx= -xd -0.5; + Zjity= -yd -0.5; if((R.r.mode & R_MBLUR)==0) RE_local_printrenderinfo(0.0, v); @@ -2911,8 +2909,8 @@ void zbufshadeDA(void) /* Delta Accum Pixel Struct */ if(R.flag & (R_ZTRA+R_HALO) ) { /* to get back correct values of zbuffer Z for transp and halos */ xd= jit[0][0]; yd= jit[0][1]; - Zjitx= -xd; - Zjity= -yd; + Zjitx= -xd -0.5; + Zjity= -yd -0.5; RE_setwindowclip(0, -1); if((R.r.mode & R_MBLUR)==0) RE_local_printrenderinfo(0.0, v); zbufferall(); @@ -2937,9 +2935,39 @@ void zbufshadeDA(void) /* Delta Accum Pixel Struct */ if(y<R.recty) { for(x=0; x<R.rectx; x++, rd++) { - - if( IS_A_POINTER_CODE(*rd)) { + int samp, curmask, face; + + if( IS_A_POINTER_CODE(*rd)) ps= (PixStr *) POINTER_FROM_CODE(*rd); + else ps= NULL; + + /* do all subpixels? */ + if(TRUE) { + for(samp=0; samp<R.osa; samp++) { + curmask= 1<<samp; + + if(ps) { + PixStr *ps1= ps; + while(ps1) { + if(ps1->mask & curmask) break; + ps1= ps1->next; + } + if(ps1) face= ps1->vlak; + else face= ps->vlak0; + } + else face= (int)*rd; + + xs= (float)x + jit[samp][0]; + ys= (float)y + jit[samp][1]; + shadepixel_short(xs, ys, face, curmask, shortcol); + + if(shortcol[3]) add_filt_mask(curmask, shortcol, rb1, rb2, rb3); + } + } + else { /* do collected faces together */ + + if(ps) face= ps->vlak0; + else face= (int)*rd; mask= 0; while(ps) { @@ -2947,32 +2975,23 @@ void zbufshadeDA(void) /* Delta Accum Pixel Struct */ xs= (float)x+centLut[b & 15]; ys= (float)y+centLut[b>>4]; - shadepixel_short(xs, ys, ps->vlak, ps->mask, shortcol); + shadepixel_short(xs, ys, ps->vlak, curmask, shortcol); - if(shortcol[3]) { - add_filt_mask(ps->mask, shortcol, rb1, rb2, rb3); - } - mask |= ps->mask; + if(shortcol[3]) add_filt_mask(curmask, shortcol, rb1, rb2, rb3); + mask |= ps->mask; ps= ps->next; } - ps= (PixStr *) POINTER_FROM_CODE(*rd); - mask= (~mask) & fullmask; - - b= centmask[mask]; - xs= (float)x+centLut[b & 15]; - ys= (float)y+centLut[b>>4]; - shadepixel_short(xs, ys, ps->vlak0, mask, shortcol); + mask= (~mask) & fullmask; + if(mask) { + b= centmask[ps->mask]; + xs= (float)x+centLut[b & 15]; + ys= (float)y+centLut[b>>4]; - if(shortcol[3]) { - add_filt_mask(mask, shortcol, rb1, rb2, rb3); - } - } - else { - shadepixel_short((float)x, (float)y, (int)*rd, fullmask, shortcol); - if(shortcol[3]) { - add_filt_mask(fullmask, shortcol, rb1, rb2, rb3); + shadepixel_short(xs, ys, face, mask, shortcol); + + if(shortcol[3]) add_filt_mask(curmask, shortcol, rb1, rb2, rb3); } } @@ -3066,7 +3085,7 @@ void zbufshade(void) unsigned short *acol, shortcol[4]; char *charcol, *rt; - Zjitx=Zjity= -.5; + Zjitx=Zjity= -0.5; zbufferall(); diff --git a/source/blender/render/intern/source/vanillaRenderPipe.c b/source/blender/render/intern/source/vanillaRenderPipe.c index d39f1fbac01..07ee01a9cbd 100644 --- a/source/blender/render/intern/source/vanillaRenderPipe.c +++ b/source/blender/render/intern/source/vanillaRenderPipe.c @@ -175,7 +175,7 @@ void zBufShadeAdvanced() int y, keepLooping = 1; float xjit = 0.0, yjit = 0.0; - Zjitx=Zjity= -0.5; /* jitter preset: 0.5 pixel */ + Zjitx=Zjity= -0.5; /* jitter preset: -0.5 pixel */ /* EDGE: for edge rendering we should compute a larger buffer, but this */ /* may require modifications at a deeper level. For now, we just */ @@ -198,8 +198,8 @@ void zBufShadeAdvanced() osaNr = 1; xjit = jit[0][0]; yjit = jit[0][1]; - jit[0][0] = 0.45; - jit[0][1] = 0.45; + jit[0][0] = 0.0; + jit[0][1] = 0.0; } RE_setwindowclip(0, -1); /* just to be sure, reset the view matrix */ @@ -328,8 +328,8 @@ void calcZBufLine(int y) /* They are added in zbufclip() */ /* Negative: these offsets are added to the vertex coordinates */ /* so it equals translating viewpoint over the positive vector. */ - Zjitx= -jit[Zsample][0]; - Zjity= -jit[Zsample][1]; + Zjitx= -jit[Zsample][0]-0.5; + Zjity= -jit[Zsample][1]-0.5; keepLooping = fillZBufDistances(); @@ -1482,12 +1482,13 @@ int calcDepth(float x, float y, void *data, int type) /* jitter has been added to x, y ! */ /* view vector view: screen coords */ - view[0]= (x+(R.xstart) + 0.5 ); + view[0]= (x+(R.xstart)+0.5); if(R.flag & R_SEC_FIELD) { if(R.r.mode & R_ODDFIELD) view[1]= (y + R.ystart)*R.ycor; - else view[1]= (y+R.ystart + 1.0)*R.ycor; - } else view[1]= (y+R.ystart + 0.5 )*R.ycor; + else view[1]= (y + R.ystart + 1.0)*R.ycor; + } + else view[1]= (y + R.ystart + 0.5)*R.ycor; /* for pano, another rotation in the xz plane is needed.... */ diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index df34757adeb..a6c50ed6d5d 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -1041,35 +1041,23 @@ void zbufinvulGL(float *v1, float *v2, float *v3) /* fills in R.rectot the valu { double x0,y0,z0; double x1,y1,z1,x2,y2,z2,xx1; - double zxd,zyd,zy0,tmp; + double zxd,zyd,zy0,tmp, zverg, zd; float *minv,*maxv,*midv; unsigned int *rectpofs,*rp; - int *rz,zverg,zvlak,x; - int my0,my2,sn1,sn2,rectx,zd,*rectzofs; + int *rz,zvlak,x; + int my0,my2,sn1,sn2,rectx,*rectzofs; int y,omsl,xs0,xs1,xs2,xs3, dx0,dx1,dx2; /* MIN MAX */ if(v1[1]<v2[1]) { - if(v2[1]<v3[1]) { - minv=v1; midv=v2; maxv=v3; - } - else if(v1[1]<v3[1]) { - minv=v1; midv=v3; maxv=v2; - } - else { - minv=v3; midv=v1; maxv=v2; - } + if(v2[1]<v3[1]) { minv=v1; midv=v2; maxv=v3; } + else if(v1[1]<v3[1]) { minv=v1; midv=v3; maxv=v2; } + else { minv=v3; midv=v1; maxv=v2; } } else { - if(v1[1]<v3[1]) { - minv=v2; midv=v1; maxv=v3; - } - else if(v2[1]<v3[1]) { - minv=v2; midv=v3; maxv=v1; - } - else { - minv=v3; midv=v2; maxv=v1; - } + if(v1[1]<v3[1]) { minv=v2; midv=v1; maxv=v3; } + else if(v2[1]<v3[1]) { minv=v2; midv=v3; maxv=v1; } + else { minv=v3; midv=v2; maxv=v1; } } if(minv[1] == maxv[1]) return; /* no zero sized faces */ @@ -1084,7 +1072,7 @@ void zbufinvulGL(float *v1, float *v2, float *v3) /* fills in R.rectot the valu /* EDGES : THE LONGEST */ xx1= maxv[1]-minv[1]; - if(xx1!=0.0) { + if(xx1>2.0/65536.0) { z0= (maxv[0]-minv[0])/xx1; tmp= -65536.0*z0; @@ -1099,7 +1087,7 @@ void zbufinvulGL(float *v1, float *v2, float *v3) /* fills in R.rectot the valu } /* EDGES : THE TOP ONE */ xx1= maxv[1]-midv[1]; - if(xx1!=0.0) { + if(xx1>2.0/65536.0) { z0= (maxv[0]-midv[0])/xx1; tmp= -65536.0*z0; @@ -1114,7 +1102,7 @@ void zbufinvulGL(float *v1, float *v2, float *v3) /* fills in R.rectot the valu } /* EDGES : BOTTOM ONE */ xx1= midv[1]-minv[1]; - if(xx1!=0.0) { + if(xx1>2.0/65536.0) { z0= (midv[0]-minv[0])/xx1; tmp= -65536.0*z0; @@ -1160,7 +1148,7 @@ void zbufinvulGL(float *v1, float *v2, float *v3) /* fills in R.rectot the valu zxd= -x0/z0; zyd= -y0/z0; zy0= my2*zyd+xx1; - zd= (int)CLAMPIS(zxd, INT_MIN, INT_MAX); + zd= zxd; /* start-offset in rect */ rectx= R.rectx; @@ -1193,14 +1181,14 @@ void zbufinvulGL(float *v1, float *v2, float *v3) /* fills in R.rectot the valu if(sn2>=rectx) sn2= rectx-1; if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); + zverg= sn1*zxd+zy0; rz= rectzofs+sn1; rp= rectpofs+sn1; x= sn2-sn1; while(x>=0) { if(zverg< *rz) { - *rz= zverg; + *rz= floor(zverg); *rp= zvlak; } zverg+= zd; @@ -1238,13 +1226,13 @@ void zbufinvulGL(float *v1, float *v2, float *v3) /* fills in R.rectot the valu if(sn2>=rectx) sn2= rectx-1; if(sn1<0) sn1= 0; - zverg= (int) CLAMPIS((sn1*zxd+zy0), INT_MIN, INT_MAX); + zverg= sn1*zxd+zy0; rz= rectzofs+sn1; rp= rectpofs+sn1; x= sn2-sn1; while(x>=0) { if(zverg< *rz) { - *rz= zverg; + *rz= floor(zverg); *rp= zvlak; } zverg+= zd; @@ -1993,7 +1981,7 @@ void zbuffershad(LampRen *lar) Zmulx= ((float)R.rectx)/2.0; Zmuly= ((float)R.recty)/2.0; - Zjitx= Zjity= -.5; + Zjitx= Zjity= -0.5; fillrect(R.rectz,R.rectx,R.recty,0x7FFFFFFE); @@ -2093,7 +2081,7 @@ void zbuffer_abuf() Material *ma=0; int v, len; - Zjitx= Zjity= -.5; + Zjitx= Zjity= -0.5; Zmulx= ((float)R.rectx)/2.0; Zmuly= ((float)R.recty)/2.0; @@ -2109,8 +2097,8 @@ void zbuffer_abuf() copyto_abufz(Zsample); /* init zbuffer */ if(R.r.mode & R_OSA) { - Zjitx= -jit[Zsample][0]; - Zjity= -jit[Zsample][1]; + Zjitx= -jit[Zsample][0]-0.5; + Zjity= -jit[Zsample][1]-0.5; } for(v=0; v<R.totvlak; v++) { @@ -2172,12 +2160,31 @@ int vergzvlak(const void *a1, const void *a2) void shadetrapixel(float x, float y, int vlak, int mask, unsigned short *shortcol) { + if( (vlak & 0x7FFFFF) > R.totvlak) { printf("error in shadetrapixel nr: %d\n", (vlak & 0x7FFFFF)); return; } - - shadepixel_short(x, y, vlak, mask, shortcol); + if(R.r.mode & R_OSA) { + int intcol[4]={0,0,0,0}; + int a, tot=0; + + for(a=0; a<R.osa; a++) { + if(mask & (1<<a)) { + shadepixel_short(x+jit[a][0], y+jit[a][1], vlak, 1<<a, shortcol); + intcol[0]+= shortcol[0]; + intcol[1]+= shortcol[1]; + intcol[2]+= shortcol[2]; + intcol[3]+= shortcol[3]; + tot++; + } + } + shortcol[0]= intcol[0]/tot; + shortcol[1]= intcol[1]/tot; + shortcol[2]= intcol[2]/tot; + shortcol[3]= intcol[3]/tot; + } + else shadepixel_short(x, y, vlak, mask, shortcol); } extern unsigned short usegamtab; @@ -2244,15 +2251,7 @@ void abufsetrow(int y) } if(totvlak==1) { - if(R.r.mode & R_OSA ) { - b= centmask[ ap->mask[0] ]; - xs= (float)x+centLut[b & 15]; - ys= (float)y+centLut[b>>4]; - } - else { - xs= x; ys= y; - } - shadetrapixel(xs, ys, ap->p[0], ap->mask[0], shortcol); + shadetrapixel((float)x, (float)y, ap->p[0], ap->mask[0], shortcol); nr= count_mask(ap->mask[0]); if( (R.r.mode & R_OSA) && nr<R.osa) { @@ -2288,15 +2287,7 @@ void abufsetrow(int y) while(totvlak>0) { totvlak--; - if(R.r.mode & R_OSA) { - b= centmask[ zrow[totvlak][2] ]; - xs= (float)x+centLut[b & 15]; - ys= (float)y+centLut[b>>4]; - } - else { - xs= x; ys= y; - } - shadetrapixel(xs, ys, zrow[totvlak][1], 0xFFFF, shortcol); + shadetrapixel((float)x, (float)y, zrow[totvlak][1], 0xFFFF, shortcol); a= count_mask(zrow[totvlak][2]); if( (R.r.mode & R_OSA ) && a<R.osa) { @@ -2310,12 +2301,7 @@ void abufsetrow(int y) if(a==R.osa) break; totvlak--; - b= centmask[ zrow[totvlak][2] ]; - - xs= (float)x+centLut[b & 15]; - ys= (float)y+centLut[b>>4]; - - shadetrapixel(xs, ys, zrow[totvlak][1], zrow[totvlak][2], shortcol); + shadetrapixel((float)x, (float)y, zrow[totvlak][1], zrow[totvlak][2], shortcol); sval= addtosampcol(sampcol, shortcol, zrow[totvlak][2]); } scol= sampcol; diff --git a/source/blender/render/intern/source/zbufferdatastruct.c b/source/blender/render/intern/source/zbufferdatastruct.c index 7406854df66..79f4d854616 100644 --- a/source/blender/render/intern/source/zbufferdatastruct.c +++ b/source/blender/render/intern/source/zbufferdatastruct.c @@ -70,7 +70,7 @@ /* if defined: all jittersamples are stored individually. _very_ serious */ /* performance hit ! also gives some buffer size problems in big scenes */ -/* #define RE_INDIVIDUAL_SUBPIXELS */ +#define RE_INDIVIDUAL_SUBPIXELS /* ------------------------------------------------------------------------- */ |