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.
This commit is contained in:
2004-05-15 18:07:09 +00:00
parent b4ecf7d973
commit a4861c37be
7 changed files with 253 additions and 430 deletions

View File

@@ -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 */

View File

@@ -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 */

View File

@@ -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) {
float refract[3];
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;
refraction(refract, shi->vn, shi->view, shi->matren->ang);
traceray(shi->matren->ray_depth_tra, shi->co, refract, tracol, shi->vlr, shi->mask);
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(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;
}
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];
traceray(shi->matren->ray_depth, shi->co, vec, mircol, shi->vlr, shi->mask);
f= i*fg*(1.0-shr->spec[1]); f1= 1.0-i; f/= div;
shr->diff[1]= f*accum[1] + f1*shr->diff[1];
f= i*fr*(1.0-shr->spec[0]); f1= 1.0-i;
shr->diff[0]= f*mircol[0] + f1*shr->diff[0];
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*fg*(1.0-shr->spec[1]); f1= 1.0-i;
shr->diff[1]= f*mircol[1] + f1*shr->diff[1];
refraction(refract, shi->vn, shi->view, shi->matren->ang);
traceray(shi->matren->ray_depth_tra, shi->co, refract, tracol, shi->vlr, shi->mask);
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];
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;
}
#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;
}
}
}
#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
/* set up isec */
VECCOPY(isec.start, shi->co);
VECCOPY(isec.end, lampco);
isec.vlrorig= shi->vlr;
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;
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);
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;
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);
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) {

View File

@@ -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(curmask, shortcol, rb1, rb2, rb3);
if(shortcol[3]) {
add_filt_mask(ps->mask, shortcol, rb1, rb2, rb3);
}
mask |= ps->mask;
ps= ps->next;
}
ps= (PixStr *) POINTER_FROM_CODE(*rd);
mask= (~mask) & fullmask;
if(mask) {
b= centmask[ps->mask];
xs= (float)x+centLut[b & 15];
ys= (float)y+centLut[b>>4];
b= centmask[mask];
xs= (float)x+centLut[b & 15];
ys= (float)y+centLut[b>>4];
shadepixel_short(xs, ys, ps->vlak0, mask, shortcol);
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();

View File

@@ -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.... */

View File

@@ -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;

View File

@@ -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
/* ------------------------------------------------------------------------- */