Bug fix #1988, ray-transparency render.

Five fixes in this commit...

- the normals for nurbs surfaces still were calculated pointing wrong in some occasions
- recoded ray-transp rendering to accept normals pointing any direction; it just counts how many times it passes a "glass" layer, and flips normals appropriate then. This means rendering will go fine on models without manually setting the normals. You can also move a camera inside a 'glass' object.
- rendering of the inside part of glass now uses correct normal too... specularity happen on a solid glass inside now.
- And an inside reflected mirror ray will keep bouncing inside glass

Related to rendering localview: old convention to render localview, but with the lamps in the normal layers, has been restored.
Please note; render happens based on active window. You *only* get a localview or 'unlocked layer' render when that 3d window is active = mouse in window.
This commit is contained in:
Ton Roosendaal
2004-12-09 12:06:37 +00:00
parent d8797f36f7
commit eae5d39899
4 changed files with 72 additions and 60 deletions

View File

@@ -55,6 +55,9 @@
#define DDA_MIRROR 1
#define DDA_SHADOW_TRA 2
#define RAY_TRA 1
#define RAY_TRAFLIP 2
#define DEPTH_SHADOW_TRA 10
/* from float.h */
#define FLT_EPSILON 1.19209290e-07F
@@ -1324,6 +1327,7 @@ static int d3dda(Isect *is)
static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
{
VlakRen *vlr= is->vlr;
float l;
int osatex= 0, flip= 0;
/* set up view vector */
@@ -1341,16 +1345,14 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
shi->matren= shi->mat->ren;
/* face normal, check for flip */
if((shi->matren->mode & (MA_RAYTRANSP|MA_ZTRA))==0) {
float l= vlr->n[0]*shi->view[0]+vlr->n[1]*shi->view[1]+vlr->n[2]*shi->view[2];
if(l<0.0) {
flip= 1;
vlr->n[0]= -vlr->n[0];
vlr->n[1]= -vlr->n[1];
vlr->n[2]= -vlr->n[2];
// only flip lower 4 bits
vlr->puno= vlr->puno ^ 15;
}
l= vlr->n[0]*shi->view[0]+vlr->n[1]*shi->view[1]+vlr->n[2]*shi->view[2];
if(l<0.0) {
flip= 1;
vlr->n[0]= -vlr->n[0];
vlr->n[1]= -vlr->n[1];
vlr->n[2]= -vlr->n[2];
// only flip lower 4 bits
vlr->puno= vlr->puno ^ 15;
}
// Osa structs we leave unchanged now
@@ -1472,7 +1474,7 @@ static void color_combine(float *result, float fac1, float fac2, float *col1, fl
#endif
/* the main recursive tracer itself */
static void traceray(short depth, float *start, float *vec, float *col, VlakRen *vlr, int mask, int osatex)
static void traceray(short depth, float *start, float *vec, float *col, VlakRen *vlr, int mask, int osatex, int traflag)
{
ShadeInput shi;
ShadeResult shr;
@@ -1501,11 +1503,22 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
float f, f1, refract[3], tracol[3];
if(shi.matren->mode & MA_RAYTRANSP) {
refraction(refract, shi.vn, shi.view, shi.matren->ang);
traceray(depth-1, shi.co, refract, tracol, shi.vlr, shi.mask, osatex);
/* odd depths: use normal facing viewer, otherwise flip */
if(traflag & RAY_TRAFLIP) {
float norm[3];
norm[0]= - shi.vn[0];
norm[1]= - shi.vn[1];
norm[2]= - shi.vn[2];
refraction(refract, norm, shi.view, shi.matren->ang);
}
else {
refraction(refract, shi.vn, shi.view, shi.matren->ang);
}
traflag |= RAY_TRA;
traceray(depth-1, shi.co, refract, tracol, shi.vlr, shi.mask, osatex, traflag ^ RAY_TRAFLIP);
}
else
traceray(depth-1, shi.co, shi.view, tracol, shi.vlr, shi.mask, osatex);
traceray(depth-1, shi.co, shi.view, tracol, shi.vlr, shi.mask, osatex, 0);
f= shr.alpha; f1= 1.0-f;
shr.diff[0]= f*shr.diff[0] + f1*tracol[0];
@@ -1528,7 +1541,7 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
if(f!=0.0) {
reflection(ref, shi.vn, shi.view, NULL);
traceray(depth-1, shi.co, ref, col, shi.vlr, shi.mask, osatex);
traceray(depth-1, shi.co, ref, col, shi.vlr, shi.mask, osatex, 0);
f1= 1.0-f;
@@ -1710,10 +1723,10 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
if(shi->matren->mode & MA_RAYTRANSP) {
refraction(refract, shi->vn, shi->view, shi->matren->ang);
traceray(shi->matren->ray_depth_tra, shi->co, refract, tracol, shi->vlr, shi->mask, 0);
traceray(shi->matren->ray_depth_tra, shi->co, refract, tracol, shi->vlr, shi->mask, 0, RAY_TRA|RAY_TRAFLIP);
}
else
traceray(shi->matren->ray_depth_tra, shi->co, shi->view, tracol, shi->vlr, shi->mask, 0);
traceray(shi->matren->ray_depth_tra, shi->co, shi->view, tracol, shi->vlr, shi->mask, 0, 0);
f= shr->alpha; f1= 1.0-f;
shr->diff[0]= f*shr->diff[0] + f1*tracol[0];
@@ -1735,7 +1748,7 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
else
reflection(vec, shi->vn, shi->view, NULL);
traceray(shi->matren->ray_depth, shi->co, vec, mircol, shi->vlr, shi->mask, shi->osatex);
traceray(shi->matren->ray_depth, shi->co, vec, mircol, shi->vlr, shi->mask, shi->osatex, 0);
f= i*fr*(1.0-shr->spec[0]); f1= 1.0-i;
shr->diff[0]= f*mircol[0] + f1*shr->diff[0];

View File

@@ -2804,7 +2804,7 @@ void *shadepixel(float x, float y, int vlaknr, int mask, float *col)
}
if(R.r.mode & R_RAYTRACE) {
if(shi.matren->ray_mirror!=0.0 || (shi.mat->mode & MA_RAYTRANSP && shr.alpha!=1.0)) {
if(shi.matren->ray_mirror!=0.0 || ((shi.mat->mode & MA_RAYTRANSP) && shr.alpha!=1.0)) {
ray_trace(&shi, &shr);
}
}

View File

@@ -159,7 +159,6 @@ static void displace_render_vert(ShadeInput *shi, VertRen *vr, float *scale);
/* ------------------------------------------------------------------------- */
#define UVTOINDEX(u,v) (startvlak + (u) * sizev + (v))
#define GETNORMAL(face,normal) CalcNormFloat4(face->v1->co, face->v2->co, face->v3->co, face->v4->co, normal)
/*
NOTE THAT U/V COORDINATES ARE SOMETIMES SWAPPED !!
@@ -1505,7 +1504,7 @@ static void init_render_mesh(Object *ob)
vlr->mat= ma;
vlr->flag= flag;
if((me->flag & ME_NOPUNOFLIP) || (ma->mode & MA_RAYTRANSP)) {
if((me->flag & ME_NOPUNOFLIP) ) {
vlr->flag |= R_NOPUNOFLIP;
}
vlr->ec= edcode;
@@ -1993,25 +1992,26 @@ static void init_render_surf(Object *ob)
v3= RE_findOrAddVert(p3);
v4= RE_findOrAddVert(p4);
flen= CalcNormFloat4(v4->co, v3->co, v2->co, v1->co, n1);
/* flen can be 0 if there are double nurbs control vertices
/* normal len can be 0 if there are double nurbs control vertices
so zero area faces can be generated
->> there is at the moment no proper way to fix this except
generating empty render faces */
// if(flen!=0.0) {
vlr= RE_findOrAddVlak(R.totvlak++);
vlr->ob= ob;
vlr->v1= v4; vlr->v2= v3; vlr->v3= v2; vlr->v4= v1; // note, displists for nurbs are again opposite, tsk tsk
VECCOPY(vlr->n, n1);
vlr->lay= ob->lay;
vlr->mat= matar[ dl->col];
vlr->ec= ME_V1V2+ME_V2V3;
vlr->flag= dl->rt;
if( (cu->flag & CU_NOPUNOFLIP) || (vlr->mat->mode & MA_RAYTRANSP)) {
vlr->flag |= R_NOPUNOFLIP;
}
// }
vlr= RE_findOrAddVlak(R.totvlak++);
vlr->ob= ob;
vlr->v1= v1; vlr->v2= v2; vlr->v3= v3; vlr->v4= v4;
flen= CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, n1);
VECCOPY(vlr->n, n1);
vlr->lay= ob->lay;
vlr->mat= matar[ dl->col];
vlr->ec= ME_V1V2+ME_V2V3;
vlr->flag= dl->rt;
if( (cu->flag & CU_NOPUNOFLIP) ) {
vlr->flag |= R_NOPUNOFLIP;
}
VecAddf(v1->n, v1->n, n1);
VecAddf(v2->n, v2->n, n1);
@@ -2029,13 +2029,11 @@ static void init_render_surf(Object *ob)
{
/* optimize! :*/
vlr= RE_findOrAddVlak(UVTOINDEX(sizeu - 1, v));
GETNORMAL(vlr, n1);
vlr1= RE_findOrAddVlak(UVTOINDEX(0, v));
GETNORMAL(vlr1, n2);
VecAddf(vlr1->v1->n, vlr1->v1->n, n1);
VecAddf(vlr1->v2->n, vlr1->v2->n, n1);
VecAddf(vlr->v3->n, vlr->v3->n, n2);
VecAddf(vlr->v4->n, vlr->v4->n, n2);
VecAddf(vlr1->v1->n, vlr1->v1->n, vlr->n);
VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
VecAddf(vlr->v3->n, vlr->v3->n, vlr1->n);
VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
}
}
if (dl->flag & DL_CYCLIC_V) {
@@ -2044,13 +2042,11 @@ static void init_render_surf(Object *ob)
{
/* optimize! :*/
vlr= RE_findOrAddVlak(UVTOINDEX(u, 0));
GETNORMAL(vlr, n1);
vlr1= RE_findOrAddVlak(UVTOINDEX(u, sizev-1));
GETNORMAL(vlr1, n2);
VecAddf(vlr1->v2->n, vlr1->v2->n, n1);
VecAddf(vlr1->v3->n, vlr1->v3->n, n1);
VecAddf(vlr->v1->n, vlr->v1->n, n2);
VecAddf(vlr->v4->n, vlr->v4->n, n2);
VecAddf(vlr1->v2->n, vlr1->v2->n, vlr->n);
VecAddf(vlr1->v3->n, vlr1->v3->n, vlr->n);
VecAddf(vlr->v1->n, vlr->v1->n, vlr1->n);
VecAddf(vlr->v4->n, vlr->v4->n, vlr1->n);
}
}
/* last vertex is an extra case:
@@ -2073,16 +2069,12 @@ static void init_render_surf(Object *ob)
if ((dl->flag & DL_CYCLIC_U) && (dl->flag & DL_CYCLIC_V))
{
vlr= RE_findOrAddVlak(UVTOINDEX(sizeu - 1, sizev - 1)); /* (m,n) */
GETNORMAL(vlr, n1);
vlr1= RE_findOrAddVlak(UVTOINDEX(0,0)); /* (0,0) */
GETNORMAL(vlr1, vn);
VecAddf(vn, vn, n1);
VecAddf(vn, vlr->n, vlr1->n);
vlr2= RE_findOrAddVlak(UVTOINDEX(0, sizev-1)); /* (0,n) */
GETNORMAL(vlr2, n1);
VecAddf(vn, vn, n1);
VecAddf(vn, vn, vlr2->n);
vlr3= RE_findOrAddVlak(UVTOINDEX(sizeu-1, 0)); /* (m,0) */
GETNORMAL(vlr3, n1);
VecAddf(vn, vn, n1);
VecAddf(vn, vn, vlr3->n);
VECCOPY(vlr->v3->n, vn);
VECCOPY(vlr1->v1->n, vn);
VECCOPY(vlr2->v2->n, vn);
@@ -2141,7 +2133,7 @@ static void init_render_surf(Object *ob)
vlr->mat= matar[ dl->col];
vlr->ec= ME_V1V2+ME_V2V3;
vlr->flag= dl->rt;
if( (cu->flag & CU_NOPUNOFLIP) || (vlr->mat->mode & MA_RAYTRANSP)) {
if( (cu->flag & CU_NOPUNOFLIP) ) {
vlr->flag |= R_NOPUNOFLIP;
}
}
@@ -2500,7 +2492,7 @@ static void init_render_curve(Object *ob)
vlr->mat= matar[ dl->col ];
vlr->flag= 0;
if( (cu->flag & CU_NOPUNOFLIP) || (vlr->mat->mode & MA_RAYTRANSP)) {
if( (cu->flag & CU_NOPUNOFLIP) ) {
vlr->flag |= R_NOPUNOFLIP;
}
vlr->ec= 0;
@@ -2969,8 +2961,11 @@ void RE_rotateBlenderScene(void)
ob->flag &= ~OB_DONE;
ob= ob->id.next;
}
lay= G.scene->lay;
/* in localview, lamps are using normal layers, objects only local bits */
if(G.scene->lay & 0xFF000000) lay= G.scene->lay & 0xFF000000;
else lay= G.scene->lay;
sce= G.scene;
base= G.scene->base.first;

View File

@@ -967,8 +967,12 @@ void BIF_do_render(int anim)
/* if start render in 3d win, use layer from window (e.g also local view) */
if(curarea && curarea->spacetype==SPACE_VIEW3D) {
int lay= G.scene->lay;
G.scene->lay= G.vd->lay;
if(G.vd->lay & 0xFF000000) // localview
G.scene->lay |= G.vd->lay;
else G.scene->lay= G.vd->lay;
do_render(NULL, anim, 0);
G.scene->lay= lay;
}
else do_render(NULL, anim, 0);