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:
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user