Revision: 16230
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16230
Author:   unclezeiv
Date:     2008-08-22 15:49:27 +0200 (Fri, 22 Aug 2008)

Log Message:
-----------
Added indirect lighting generation for directional lights and environment maps 
(several issues remaining)

Also:
- added API to retrieve bounding box of RE_ray_tree
- fixed subtle bug: bounce colour was erroneously computed as black for 
surfaces facing away from camera; fixed by temporarily setting R_NOPUNOFLIP 
before issuing shading call

Modified Paths:
--------------
    
branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h
    branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
    branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c

Modified: 
branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h
===================================================================
--- 
branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h  
    2008-08-22 12:48:12 UTC (rev 16229)
+++ 
branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h  
    2008-08-22 13:49:27 UTC (rev 16230)
@@ -110,5 +110,8 @@
    end distance */
 float RE_ray_tree_max_size(RayTree *tree);
 
+/* get the tree's axis aligned bounding box */
+void RE_ray_tree_aabb(RayTree *tree, float *min, float *max);
+
 #endif /*__RE_RAYTRACE_H__*/
 

Modified: 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-08-22 12:48:12 UTC (rev 16229)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-08-22 13:49:27 UTC (rev 16230)
@@ -175,6 +175,7 @@
        int stat_discard_black;
        int stat_discard_nan;
        float scene_diag;
+       float scene_min[3], scene_max[3];
        float indir_fac;
        int do_indir;
        int options;
@@ -210,6 +211,8 @@
 #define IS_LEAF(node) (!(node)->child1 && !(node)->child2)
 #define LC_LUMINOSITY_LIMIT (0.0001f)
 
+static void add_virtual_point_light(Render * re, LightcutsData *lcd, LampRen 
*orig, float *col, int lev);
+
 /* XXX: this function looks really slow! */
 static float get_bounding_cone(LightcutsCluster * one, LightcutsCluster * two, 
float *vec)
 {
@@ -853,7 +856,7 @@
 {
        GroupObject *gonew;
        LampRen *lar;
-       int k, kk;
+       int k, kk, i;
        float t, p, phi, phirad, st;
        float maxc;
        
@@ -934,7 +937,18 @@
                        /* so that bright lights don't get excluded when n is 
large */
                        lar->energy *= maxc;
                }
+               
+               /* indirect lighting */
+               for (i= 0; i < lcd->do_indir; i++) {
+                       int lev= (lcd->options & LC_OPT_2ND_BOUNCE) ? 1 : 0;
+                       add_virtual_point_light(re, lcd, lar, col, lev);
+               }
 
+               if (lcd->do_indir > 0 && (lcd->options & LC_OPT_ONLY_INDIR)) {
+                       lamp_delete(lar);
+                       continue;
+               }
+
                BLI_addtail(&re->lampren, lar);
                /* check deallocation */
                gonew->lampren= lar;
@@ -1068,6 +1082,7 @@
        GroupObject go;
        float savecol[3], energy, max_col;
        int max_idx;
+       int old_vlr_flag;
        
        /* hack: increase current color/energy in order to avoid too dark 
results */
        energy= lar->energy;
@@ -1079,6 +1094,10 @@
        lar->b /= lar->energy;
        lar->energy= 1.0f;
        
+       /* don't do normal flipping in this phase */
+       old_vlr_flag= vla->flag;
+       vla->flag |= R_NOPUNOFLIP;
+       
        /* fake group object in order to use "light override" */
        go.lampren= lar;
        go.next= go.prev= 0x0;
@@ -1170,8 +1189,11 @@
        lar->g= savecol[1];
        lar->b= savecol[2];
        
+       /* restore VlakRen flags */
+       vla->flag= old_vlr_flag;
+       
        max_col= MAX3(shr.col[0], shr.col[1], shr.col[2]);
-       
+
        if (max_col==0.0f) {
                lcd->stat_discard_black+= 10000;
                return 0.0f;
@@ -1195,19 +1217,39 @@
        isec.mode= RE_RAY_MIRROR;
        isec.faceorig= NULL;
        isec.oborig= 0;
-       VECCOPY(isec.start, orig->co);
-       if (!(lcd->options & LC_OPT_FIXED_DIRS))
-               get_cosine_weighted_random_direction(isec.vec);
-       else {
-               isec.vec[0]= 0.0f;
-               isec.vec[1]= 0.0f;
-               isec.vec[2]= 1.0f;
+       switch (orig->type) {
+       case LA_SPOT:
+               VECCOPY(isec.start, orig->co);
+               if (!(lcd->options & LC_OPT_FIXED_DIRS))
+                       get_cosine_weighted_random_direction(isec.vec);
+               else {
+                       isec.vec[0]= 0.0f;
+                       isec.vec[1]= 0.0f;
+                       isec.vec[2]= 1.0f;
+               }
+               Mat3MulVecfl(orig->mat, isec.vec);
+               VECNEG(isec.vec);
+               VECADDFAC(isec.end, isec.start, isec.vec, lcd->scene_diag);
+               break;
+       case LA_SUN:
+               {
+                       /* generate random point in bounding box */
+                       float r[3];
+                       r[0]= BLI_frand() * 
(lcd->scene_max[0]-lcd->scene_min[0]) + lcd->scene_min[0];
+                       r[1]= BLI_frand() * 
(lcd->scene_max[1]-lcd->scene_min[1]) + lcd->scene_min[1];
+                       r[2]= BLI_frand() * 
(lcd->scene_max[2]-lcd->scene_min[2]) + lcd->scene_min[2];
+                       
+                       /* trace ray in given direction passing from that point 
*/
+                       VECCOPY(isec.vec, orig->vec);
+                       VECADDFAC(isec.start, r, isec.vec, -lcd->scene_diag);
+                       VECADDFAC(isec.end, isec.start, isec.vec, 
lcd->scene_diag * 2);
+               }
+               break;
+       case LA_LOCAL:
+               /* TODO: indirect lighting for omnidirectional lamps */
+               return;
        }
-       Mat3MulVecfl(orig->mat, isec.vec);
-       VECNEG(isec.vec);
        
-       VECADDFAC(isec.end, isec.start, isec.vec, lcd->scene_diag);
-       
        if (!RE_ray_tree_intersect(re->raytree, &isec)) {
                lcd->stat_discard_nohit++;
                return;
@@ -1220,7 +1262,7 @@
        VECADDFAC(co, isec.start, isec.vec, isec.labda - 0.01);
        
        fac= get_bounce_color(lcd, isec.ob, vla, co, orig, scol, isec.isect);
-       
+
        if (fac == 0.0f) {
                lcd->stat_discard_black++;
                return;
@@ -1232,11 +1274,6 @@
                return;
        }
 #endif
-
-#ifdef LIGHTCUTS_DEBUG_INDIR
-       printf("PYDBG %d: %f %f %f - %f %f %f\n",
-                       lev, co[0], co[1], co[2], scol[0], scol[1], scol[2]);
-#endif
        
        lar= (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
        lamp_init(re, lar);
@@ -1266,6 +1303,11 @@
        lar->g= lar->energy * scol[1];
        lar->b= lar->energy * scol[2];
        
+#ifdef LIGHTCUTS_DEBUG_INDIR
+       printf("PYDBG %d: %f %f %f - %f %f %f - %f %f %f\n",
+                       lev, co[0], co[1], co[2], scol[0], scol[1], scol[2], 
isec.vec[0], isec.vec[1], isec.vec[2]);
+#endif
+       
        /* XXX: see remarks on similar code in convert_environment_map */
        go= MEM_callocN(sizeof(GroupObject), "groupobject");
        BLI_addtail(&lcd->pointlights, go);
@@ -1411,6 +1453,7 @@
        lcd->options= re->r.lightcuts_options;
        lcd->error_rate= re->r.lightcuts_max_error;
        lcd->scene_diag= RE_ray_tree_max_size(re->raytree);
+       RE_ray_tree_aabb(re->raytree, lcd->scene_min, lcd->scene_max);
        
        if (lcd->options & LC_OPT_2ND_BOUNCE)
                lcd->indir_fac /= 2.0f;
@@ -1462,6 +1505,22 @@
                        convert_area_light(re, lcd, lar);
                        continue;
                }
+               
+               if (!ELEM3(lar->type, LA_LOCAL, LA_SUN, LA_SPOT))
+                       continue;
+               
+               /* indirect lighting */
+               if (lcd->do_indir > 0) {
+                       int i;
+                       for (i= 0; i < lcd->do_indir; i++) {
+                               int lev= (lcd->options & LC_OPT_2ND_BOUNCE) ? 1 
: 0;
+                               float col[3] = {lar->r, lar->g, lar->b};
+                               add_virtual_point_light(re, lcd, lar, col, lev);
+                       }
+               
+                       if (lcd->options & LC_OPT_ONLY_INDIR)
+                               continue;
+               }
 
                /* first copy the initial light */
                gonew= MEM_callocN(sizeof(GroupObject), "groupobject");

Modified: 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c  
2008-08-22 12:48:12 UTC (rev 16229)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c  
2008-08-22 13:49:27 UTC (rev 16230)
@@ -1440,3 +1440,8 @@
        return ((Octree*)tree)->ocsize;
 }
 
+void RE_ray_tree_aabb(RayTree *tree, float *min, float *max)
+{
+       VECCOPY(min, ((Octree*)tree)->min);
+       VECCOPY(max, ((Octree*)tree)->max);
+}


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to