Bug fix #1988, ray-transparency render.
authorTon Roosendaal <ton@blender.org>
Thu, 9 Dec 2004 12:06:37 +0000 (12:06 +0000)
committerTon Roosendaal <ton@blender.org>
Thu, 9 Dec 2004 12:06:37 +0000 (12:06 +0000)
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.

source/blender/render/intern/source/ray.c
source/blender/render/intern/source/rendercore.c
source/blender/renderconverter/intern/convertBlenderScene.c
source/blender/src/renderwin.c

index 87dfbe3731dee67af9dbc574b03252502d0d234b..1638bf8743556fce30163c372fb9fab3f023a972 100644 (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];
index 4c4098f735f3e45aea148d622f953eb8644c55aa..098444b18b2724ac879bef08e12c140af972301e 100644 (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);
                        }
                }
index 5acb9d280f97491dc3dbbfdfa1b2af34fd54a825..927f1b8bca1a0a316208bba9c3b0c71b28c0f9c2 100644 (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;
index ad1161f76db16e0948fa5c7c317ef2f91a6fa5ec..5fbe58523cb4f983d923c140d99c4d6d91de1f04 100644 (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);