experiences with memory organization (store the vertexs coords on RayFace)
[blender.git] / source / blender / render / intern / source / rayshade.c
index be7b2665bdb2e5e1267b6571809e35fa63622038..685b82d9da2aeb584ea90ef0f0e490ac74403f26 100644 (file)
 extern struct Render R;
 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
+RayObject *  RE_rayobject_tree_create(int type, int size) __attribute__((noinline));
+
+RayObject *  RE_rayobject_tree_create(int type, int size)
+{
+//     if(type == R_RAYTRACE_TREE_BIH)
+       return RE_rayobject_vbvh_create(size);
+
+       if(type == R_RAYTRACE_TREE_BVH)
+               return RE_rayobject_bvh_create(size);
+       if(type == R_RAYTRACE_TREE_BIH)
+               return RE_rayobject_bih_create(size);
+       if(type == R_RAYTRACE_TREE_BLIBVH)
+               return RE_rayobject_blibvh_create(size);
+
+}
+
+#ifdef RE_RAYCOUNTER
+RayCounter re_rc_counter[BLENDER_MAX_THREADS] = {};
+#endif
+
 #if 0
 static int vlr_check_intersect(Isect *is, int ob, RayFace *face)
 {
@@ -123,12 +143,22 @@ void freeraytree(Render *re)
                        obi->raytree = NULL;
                }
        }
+       
+#ifdef RE_RAYCOUNTER
+       {
+               RayCounter sum = {};
+               int i;
+               for(i=0; i<BLENDER_MAX_THREADS; i++)
+                       RE_RC_MERGE(&sum, re_rc_counter+i);
+               RE_RC_INFO(&sum);
+       }
+#endif
 }
 
 static int is_raytraceable_vlr(Render *re, VlakRen *vlr)
 {
        if((re->flag & R_BAKE_TRACE) || (vlr->mat->mode & MA_TRACEBLE))
-       if((vlr->mat->mode & MA_WIRE)==0)
+       if(vlr->mat->material_type != MA_TYPE_WIRE)
                return 1;
        return 0;
 }
@@ -175,10 +205,13 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
                assert( faces > 0 );
 
                //Create Ray cast accelaration structure
-
+               
                //TODO dynamic ocres
-//             raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces );
-               raytree = obr->raytree = RE_rayobject_bvh_create( faces );
+               if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE)
+                       raytree = obr->raytree = RE_rayobject_octree_create( re->r.ocres, faces );
+               else //if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_BVH)
+                       raytree = obr->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, faces );
+                       
                face = obr->rayfaces = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "ObjectRen faces");
                obr->rayobi = obi;
                
@@ -187,15 +220,9 @@ RayObject* makeraytree_object(Render *re, ObjectInstanceRen *obi)
                        VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
                        if(is_raytraceable_vlr(re, vlr))
                        {
-                               face->v1 = vlr->v1->co;
-                               face->v2 = vlr->v2->co;
-                               face->v3 = vlr->v3->co;
-                               face->v4 = vlr->v4 ? vlr->v4->co : NULL;
-                               
-                               face->ob   = obi;
-                               face->face = vlr;
-                               
-                               RE_rayobject_add( raytree, (RayObject*)face++ );
+                               RE_rayface_from_vlak( face, obi, vlr );                         
+                               RE_rayobject_add( raytree, RayObject_unalignRayFace(face) );
+                               face++;
                        }
                }
                RE_rayobject_done( raytree );
@@ -235,7 +262,7 @@ static void makeraytree_hier(Render *re)
                num_objects++;
 
        //Create raytree
-       re->raytree = RE_rayobject_bvh_create( num_objects );
+       re->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, num_objects );
        
        for(obi=re->instancetable.first; obi; obi=obi->next)
        if(is_raytraceable(re, obi))
@@ -273,39 +300,52 @@ static void makeraytree_single(Render *re)
                ObjectRen *obr = obi->obr;
                obs++;
                
-               assert((obi->flag & R_TRANSFORMED) == 0); //Not suported
-       
-               for(v=0;v<obr->totvlak;v++)
+               if(obi->flag & R_TRANSFORMED)
                {
-                       VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
-                       if(is_raytraceable_vlr(re, vlr))
-                               faces++;
+                       faces++;
+               }
+               else
+               {
+                       for(v=0;v<obr->totvlak;v++)
+                       {
+                               VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
+                               if(is_raytraceable_vlr(re, vlr))
+                                       faces++;
+                       }
                }
        }
        
        //Create raytree
-//     raytree = re->raytree   = RE_rayobject_octree_create(re->r.ocres, faces);
-       raytree = re->raytree   = RE_rayobject_bvh_create(faces);
+       if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE)
+               raytree = re->raytree = RE_rayobject_octree_create( re->r.ocres, faces );
+       else //if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH)
+               raytree = re->raytree = RE_rayobject_tree_create( re->r.raytrace_tree_type, faces );
+
        face    = re->rayfaces  = (RayFace*)MEM_callocN(faces*sizeof(RayFace), "Render ray faces");
        
        for(obi=re->instancetable.first; obi; obi=obi->next)
        if(is_raytraceable(re, obi))
        {
-               int v;
-               ObjectRen *obr = obi->obr;
-
-               for(v=0;v<obr->totvlak;v++)
+               if(obi->flag & R_TRANSFORMED)
                {
-                       VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
-                       face->v1 = vlr->v1->co;
-                       face->v2 = vlr->v2->co;
-                       face->v3 = vlr->v3->co;
-                       face->v4 = vlr->v4 ? vlr->v4->co : NULL;
-                       
-                       face->ob   = obi;
-                       face->face = vlr;
-                       
-                       RE_rayobject_add( raytree, (RayObject*)face++ );
+                       RayObject *obj = makeraytree_object(re, obi);
+                       RE_rayobject_add( re->raytree, obj );
+               }
+               else
+               {
+                       int v;
+                       ObjectRen *obr = obi->obr;
+
+                       for(v=0;v<obr->totvlak;v++)
+                       {
+                               VlakRen *vlr = obr->vlaknodes[v>>8].vlak + (v&255);
+                               if(is_raytraceable_vlr(re, vlr))
+                               {
+                                       RE_rayface_from_vlak(face, obi, vlr);
+                                       RE_rayobject_add( raytree, RayObject_unalignRayFace(face) );
+                                       face++;
+                               }
+                       }
                }
        }
        RE_rayobject_done( raytree );   
@@ -313,10 +353,45 @@ static void makeraytree_single(Render *re)
 
 void makeraytree(Render *re)
 {
-       if(1)
-               makeraytree_hier(re);
+       float min[3], max[3], sub[3];
+       int i;
+       const char *tree_type = "Tree(unknown)";
+
+       re->r.raystructure = R_RAYSTRUCTURE_SINGLE_BVH;
+#ifdef RE_RAYCOUNTER
+       if(re->r.raytrace_tree_type == R_RAYTRACE_TREE_BVH)
+               tree_type = "BVH";
+       if(re->r.raytrace_tree_type == R_RAYTRACE_TREE_BIH)
+               tree_type = "BIH";
+       if(re->r.raytrace_tree_type == R_RAYTRACE_TREE_BLIBVH)
+               tree_type = "BLIBVH";
+
+       if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_OCTREE)
+               printf("Building single octree\n");
+       else if(re->r.raystructure == R_RAYSTRUCTURE_SINGLE_BVH)
+               printf("Building single tree(%s)\n", tree_type);
+       else if(re->r.raystructure == R_RAYSTRUCTURE_HIER_BVH_OCTREE)
+               printf("Building tree(%s) of octrees\n", tree_type);
+       else
+               printf("Building tree(%s) of trees(%s)\n", tree_type, tree_type);
+#endif
+
+       if(ELEM(re->r.raystructure, R_RAYSTRUCTURE_SINGLE_BVH, R_RAYSTRUCTURE_SINGLE_OCTREE))
+               BENCH(makeraytree_single(re), tree_build);
        else
-               makeraytree_single(re);
+               BENCH(makeraytree_hier(re), tree_build);
+               
+               
+       //Calculate raytree max_size
+       //This is ONLY needed to kept a bogus behaviour of SUN and HEMI lights
+       RE_rayobject_merge_bb( re->raytree, min, max );
+       for(i=0; i<3; i++)
+       {
+               min[i] += 0.01f;
+               max[i] += 0.01f;
+               sub[i] = max[i]-min[i];
+       }
+       re->maxdist = sqrt( sub[0]*sub[0] + sub[1]*sub[1] + sub[2]*sub[2] );
 }
 
 
@@ -341,8 +416,7 @@ static void shade_ray(Isect *is, ShadeInput *shi, ShadeResult *shr)
        shi->obr= obi->obr;
        shi->vlr= vlr;
        shi->mat= vlr->mat;
-       memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));        // note, keep this synced with render_types.h
-       shi->har= shi->mat->har;
+       shade_input_init_material(shi);
        
        // Osa structs we leave unchanged now
        SWAP(int, osatex, shi->osatex);
@@ -551,9 +625,11 @@ static void traceray(ShadeInput *origshi, ShadeResult *origshr, short depth, flo
        isec.labda = dist_mir > 0 ? dist_mir : RE_RAYTRACE_MAXDIST;
        isec.mode= RE_RAY_MIRROR;
        isec.skip = RE_SKIP_VLR_NEIGHBOUR;
+       isec.hint = 0;
 
        isec.orig.ob   = obi;
        isec.orig.face = vlr;
+       RE_RC_INIT(isec, shi);
 
        if(RE_rayobject_raycast(R.raytree, &isec)) {
                float d= 1.0f;
@@ -1297,7 +1373,6 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
        
        do_tra= ((shi->mat->mode & (MA_RAYTRANSP)) && shr->alpha!=1.0f);
        do_mir= ((shi->mat->mode & MA_RAYMIRROR) && shi->ray_mirror!=0.0f);
-
        
        /* raytrace mirror amd refract like to separate the spec color */
        if(shi->combinedflag & SCE_PASS_SPEC)
@@ -1456,6 +1531,11 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr)
        isec.mode= RE_RAY_MIRROR;
        isec.orig.ob   = ship->obi;
        isec.orig.face = ship->vlr;
+       isec.hint = 0;
+
+       VECCOPY(isec.start, ship->co);
+       
+       RE_RC_INIT(isec, shi);
        
        for(a=0; a<8*8; a++) {
                
@@ -1468,7 +1548,6 @@ int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr)
                        vec[2]-= vec[2];
                }
 
-               VECCOPY(isec.start, ship->co);
                VECCOPY(isec.vec, vec );
                isec.labda = RE_RAYTRACE_MAXDIST;
 
@@ -1645,6 +1724,7 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys)
 static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
 {
        Isect isec;
+       RayHint point_hint;
        QMCSampler *qsa=NULL;
        float samp3d[3];
        float up[3], side[3], dir[3], nrm[3];
@@ -1660,8 +1740,11 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
        float dxyview[3], skyadded=0, div;
        int aocolor;
        
+       RE_RC_INIT(isec, *shi);
        isec.orig.ob   = shi->obi;
        isec.orig.face = shi->vlr;
+       isec.skip = RE_SKIP_VLR_NEIGHBOUR;
+       isec.hint = 0;
 
        isec.hit.ob   = 0;
        isec.hit.face = 0;
@@ -1671,6 +1754,11 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
        isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;
        isec.lay= -1;
        
+       VECCOPY(isec.start, shi->co);           
+       RE_rayobject_hint_bb( R.raytree, &point_hint, isec.start, isec.start );
+       isec.hint = &point_hint;
+
+       
        shadfac[0]= shadfac[1]= shadfac[2]= 0.0f;
        
        /* prevent sky colors to be added for only shadow (shadow becomes alpha) */
@@ -1708,6 +1796,7 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
 
        QMC_initPixel(qsa, shi->thread);
        
+       
        while (samples < max_samples) {
 
                /* sampling, returns quasi-random vector in unit hemisphere */
@@ -1719,7 +1808,6 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
                
                Normalize(dir);
                        
-               VECCOPY(isec.start, shi->co);
                isec.vec[0] = -dir[0];
                isec.vec[1] = -dir[1];
                isec.vec[2] = -dir[2];
@@ -1787,13 +1875,17 @@ static void ray_ao_qmc(ShadeInput *shi, float *shadfac)
 static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
 {
        Isect isec;
+       RayHint point_hint;
        float *vec, *nrm, div, bias, sh=0.0f;
        float maxdist = R.wrld.aodist;
        float dxyview[3];
        int j= -1, tot, actual=0, skyadded=0, aocolor, resol= R.wrld.aosamp;
        
+       RE_RC_INIT(isec, *shi);
        isec.orig.ob   = shi->obi;
        isec.orig.face = shi->vlr;
+       isec.skip = RE_SKIP_VLR_NEIGHBOUR;
+       isec.hint = 0;
 
        isec.hit.ob   = 0;
        isec.hit.face = 0;
@@ -1803,6 +1895,9 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
        isec.mode= (R.wrld.aomode & WO_AODIST)?RE_RAY_SHADOW_TRA:RE_RAY_SHADOW;
        isec.lay= -1;
 
+       VECCOPY(isec.start, shi->co);           
+       RE_rayobject_hint_bb( R.raytree, &point_hint, isec.start, isec.start );
+       isec.hint = &point_hint;
 
        shadfac[0]= shadfac[1]= shadfac[2]= 0.0f;
 
@@ -1850,7 +1945,6 @@ static void ray_ao_spheresamp(ShadeInput *shi, float *shadfac)
                        actual++;
                        
                        /* always set start/vec/labda */
-                       VECCOPY(isec.start, shi->co);
                        isec.vec[0] = -vec[0];
                        isec.vec[1] = -vec[1];
                        isec.vec[2] = -vec[2];
@@ -1957,7 +2051,7 @@ static void ray_shadow_jittered_coords(ShadeInput *shi, int max, float jitco[RE_
        }
 }
 
-static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lampvec, float *shadfac, Isect *isec)
+static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec)
 {
        QMCSampler *qsa=NULL;
        int samples=0;
@@ -1968,7 +2062,10 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lam
        float adapt_thresh = lar->adapt_thresh;
        int min_adapt_samples=4, max_samples = lar->ray_totsamp;
        float *co;
-       int do_soft=1, full_osa=0;
+       int do_soft=1, full_osa=0, i;
+
+       float min[3], max[3];
+       RayHint bb_hint;
 
        float jitco[RE_MAX_OSA][3];
        int totjitco;
@@ -1999,10 +2096,18 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lam
                qsa = get_thread_qmcsampler(&R, shi->thread, SAMP_TYPE_HAMMERSLEY, max_samples);
        
        QMC_initPixel(qsa, shi->thread);
+
+       INIT_MINMAX(min, max);
+       for(i=0; i<totjitco; i++)
+       {
+               DO_MINMAX(jitco[i], min, max);
+       }
+       RE_rayobject_hint_bb( R.raytree, &bb_hint, min, max);
        
+       isec->hint = &bb_hint;
+       isec->skip = RE_SKIP_VLR_NEIGHBOUR;
        VECCOPY(vec, lampco);
        
-       isec->skip = RE_SKIP_VLR_NEIGHBOUR;
        while (samples < max_samples) {
 
                isec->orig.ob   = shi->obi;
@@ -2018,8 +2123,6 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lam
                        if (lar->type == LA_LOCAL) {
                                float ru[3], rv[3], v[3], s[3];
                                
-                               assert(lampvec == 0);
-                               
                                /* calc tangent plane vectors */
                                v[0] = co[0] - lampco[0];
                                v[1] = co[1] - lampco[1];
@@ -2038,7 +2141,6 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lam
                                VECCOPY(samp3d, s);
                        }
                        else {
-                               assert(lampvec);
                                /* sampling, returns quasi-random vector in [sizex,sizey]^2 plane */
                                QMC_sampleRect(samp3d, qsa, shi->thread, samples, lar->area_size, lar->area_sizey);
                                                                
@@ -2066,20 +2168,10 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lam
                }
 
                VECCOPY(isec->start, co);
-               if(lampvec)
-               {
-                       isec->vec[0] = end[0];
-                       isec->vec[1] = end[1];
-                       isec->vec[2] = end[2];
-                       isec->labda = RE_RAYTRACE_MAXDIST;
-               }
-               else
-               {
-                       isec->vec[0] = end[0]-isec->start[0];
-                       isec->vec[1] = end[1]-isec->start[1];
-                       isec->vec[2] = end[2]-isec->start[2];
-                       isec->labda = 1.0f; // * Normalize(isec->vec);
-               }
+               isec->vec[0] = end[0]-isec->start[0];
+               isec->vec[1] = end[1]-isec->start[1];
+               isec->vec[2] = end[2]-isec->start[2];
+               isec->labda = 1.0f; // * Normalize(isec->vec);
                
                /* trace the ray */
                if(isec->mode==RE_RAY_SHADOW_TRA) {
@@ -2132,12 +2224,13 @@ static void ray_shadow_qmc(ShadeInput *shi, LampRen *lar, float *lampco, int lam
                release_thread_qmcsampler(&R, shi->thread, qsa);
 }
 
-static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, int lampvec, float *shadfac, Isect *isec)
+static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, float *shadfac, Isect *isec)
 {
        /* area soft shadow */
        float *jitlamp;
        float fac=0.0f, div=0.0f, vec[3];
        int a, j= -1, mask;
+       RayHint point_hint;
        
        if(isec->mode==RE_RAY_SHADOW_TRA) {
                shadfac[0]= shadfac[1]= shadfac[2]= shadfac[3]= 0.0f;
@@ -2154,6 +2247,12 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, int
        if(a==4) mask |= (mask>>4)|(mask>>8);
        else if(a==9) mask |= (mask>>9);
        
+       VECCOPY(isec->start, shi->co);          
+       isec->orig.ob   = shi->obi;
+       isec->orig.face = shi->vlr;
+       RE_rayobject_hint_bb( R.raytree, &point_hint, isec->start, isec->start );
+       isec->hint = &point_hint;
+       
        while(a--) {
                
                if(R.r.mode & R_OSA) {
@@ -2165,30 +2264,16 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, float *lampco, int
                        }
                }
                
-               isec->orig.ob   = shi->obi;
-               isec->orig.face = shi->vlr;
-               
                vec[0]= jitlamp[0];
                vec[1]= jitlamp[1];
                vec[2]= 0.0f;
                Mat3MulVecfl(lar->mat, vec);
                
                /* set start and vec */
-               VECCOPY(isec->start, shi->co);
-               if(lampvec)
-               {
-                       isec->vec[0] = vec[0]+lampco[0];
-                       isec->vec[1] = vec[1]+lampco[1];
-                       isec->vec[2] = vec[2]+lampco[2];
-                       isec->labda = RE_RAYTRACE_MAXDIST;
-               }
-               else
-               {
-                       isec->vec[0] = vec[0]+lampco[0]-shi->co[0];
-                       isec->vec[1] = vec[1]+lampco[1]-shi->co[1];
-                       isec->vec[2] = vec[2]+lampco[2]-shi->co[2];
-                       isec->labda = 1.0f;
-               }
+               isec->vec[0] = vec[0]+lampco[0]-isec->start[0];
+               isec->vec[1] = vec[1]+lampco[1]-isec->start[1];
+               isec->vec[2] = vec[2]+lampco[2]-isec->start[2];
+               isec->labda = 1.0f;
                isec->skip = RE_SKIP_VLR_NEIGHBOUR;
                
                if(isec->mode==RE_RAY_SHADOW_TRA) {
@@ -2227,11 +2312,12 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
 {
        Isect isec;
        float lampco[3];
-       int lampvec; /* indicates if lampco is a vector lamp */
 
        /* setup isec */
+       RE_RC_INIT(isec, *shi);
        if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA;
        else isec.mode= RE_RAY_SHADOW;
+       isec.hint = 0;
        
        if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW))
                isec.lay= lar->lay;
@@ -2247,19 +2333,30 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
        }
        
        if(lar->type==LA_SUN || lar->type==LA_HEMI) {
-               lampco[0]= -lar->vec[0];
-               lampco[1]= -lar->vec[1];
-               lampco[2]= -lar->vec[2];
-               lampvec = 1;
+               /* jitter and QMC sampling add a displace vector to the lamp position
+                * that's incorrect because a SUN lamp does not has an exact position
+                * and the displace should be done at the ray vector instead of the
+                * lamp position.
+                * This is easily verified by noticing that shadows of SUN lights change
+                * with the scene BB.
+                * 
+                * This was detected during SoC 2009 - Raytrace Optimization, but to keep
+                * consistency with older render code it wasn't removed.
+                * 
+                * If the render code goes through some recode/serious bug-fix then this
+                * is something to consider!
+                */
+               lampco[0]= shi->co[0] - R.maxdist*lar->vec[0];
+               lampco[1]= shi->co[1] - R.maxdist*lar->vec[1];
+               lampco[2]= shi->co[2] - R.maxdist*lar->vec[2];
        }
        else {
                VECCOPY(lampco, lar->co);
-               lampvec = 0;
        }
        
        if (ELEM(lar->ray_samp_method, LA_SAMP_HALTON, LA_SAMP_HAMMERSLEY)) {
                
-               ray_shadow_qmc(shi, lar, lampco, lampvec, shadfac, &isec);
+               ray_shadow_qmc(shi, lar, lampco, shadfac, &isec);
                
        } else {
                if(lar->ray_totsamp<2) {
@@ -2271,16 +2368,8 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
                        
                        /* set up isec vec */
                        VECCOPY(isec.start, shi->co);
-                       if(lampvec)
-                       {
-                               VECCOPY(isec.vec, lampco);
-                               isec.labda = RE_RAYTRACE_MAXDIST;
-                       }
-                       else
-                       {
-                               VECSUB(isec.vec, lampco, isec.start);
-                               isec.labda = 1.0f;
-                       }
+                       VECSUB(isec.vec, lampco, isec.start);
+                       isec.labda = 1.0f;
 
                        if(isec.mode==RE_RAY_SHADOW_TRA) {
                                /* isec.col is like shadfac, so defines amount of light (0.0 is full shadow) */
@@ -2294,7 +2383,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
                                shadfac[3]= 0.0f;
                }
                else {
-                       ray_shadow_jitter(shi, lar, lampco, lampvec, shadfac, &isec);
+                       ray_shadow_jitter(shi, lar, lampco, shadfac, &isec);
                }
        }
                
@@ -2315,7 +2404,9 @@ static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float
        assert(0);
        
        /* setup isec */
+       RE_RC_INIT(isec, *shi);
        isec.mode= RE_RAY_SHADOW_TRA;
+       isec.hint = 0;
        
        if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1;