Revision: 16066
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16066
Author:   unclezeiv
Date:     2008-08-12 17:06:49 +0200 (Tue, 12 Aug 2008)

Log Message:
-----------
- preliminary stuff to support "instant radiosity"-like indirect illumination. 
This is a work in progress: in particular, it currently works only for area 
lights and it does not take the surface color into account (=no color bleeding 
yet)
- raytrace.c: don't test for self intersection if the ray was not originated 
from a face (maybe there's another way to do this, the API is a bit obscure)
- shadeoutput.c: minor readability change

Modified Paths:
--------------
    branches/soc-2008-unclezeiv/source/blender/makesdna/DNA_scene_types.h
    branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
    branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c
    
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c
    branches/soc-2008-unclezeiv/source/blender/src/buttons_scene.c

Modified: branches/soc-2008-unclezeiv/source/blender/makesdna/DNA_scene_types.h
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/makesdna/DNA_scene_types.h       
2008-08-12 13:30:17 UTC (rev 16065)
+++ branches/soc-2008-unclezeiv/source/blender/makesdna/DNA_scene_types.h       
2008-08-12 15:06:49 UTC (rev 16066)
@@ -318,7 +318,9 @@
        int lightcuts_max_cut;
        int lightcuts_area_density;
        int lightcuts_env_map;
-       int pad4;
+       float lightcuts_indir_fac;
+       int lightcuts_indirect;
+       int lightcuts_random_dirs;
 } RenderData;
 
 /* control render convert and shading engine */

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-12 13:30:17 UTC (rev 16065)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-08-12 15:06:49 UTC (rev 16066)
@@ -49,6 +49,7 @@
 #include "blendef.h"
 #include "pixelshading.h"
 #include "render_types.h"
+#include "shading.h"
 
 /* #define LIGHTCUTS_DEBUG */
 
@@ -149,6 +150,7 @@
        LightcutsTree trees[_TREES_SIZE];
 
        int light_counter;
+       int vpl_counter;
 
        float error_rate;
        int max_lights;
@@ -159,7 +161,10 @@
        int stat_samples;
        int stat_cut_size;
        int stat_rays_shot;
-       float bb_diag_sq;
+       float scene_diag;
+       float indir_fac;
+       int do_indir;
+       int random_dirs;
        
        double start_time;
        double tree_creation_time;
@@ -299,6 +304,7 @@
        return rep;
 }
 
+#if 0
 static void find_and_insert_new_min(Heap * heap, LightcutsCluster * array, int 
size, LightcutsClusterPair * pair, int id, int from, float c)
 {
        LightcutsCluster * el = &array[id];
@@ -336,6 +342,7 @@
                BLI_heap_insert(heap, metric, pair);
        }
 }
+#endif
 
 static void cb_update_metric_max_dist(void *data, int index, float *val, float 
*dist)
 {
@@ -505,6 +512,7 @@
 }
 #endif
 
+#if 0
 static void lightcuts_build_tree(LightcutsTree *tree, float c)
 {
        int i, cluster_id = 0;
@@ -563,6 +571,7 @@
 
        MEM_freeN(pair_array);
 }
+#endif
 
 /* this one uses kdtree */
 static void lightcuts_build_tree2(LightcutsTree *tree, float c)
@@ -1004,6 +1013,94 @@
        }
 }
 
+static void get_cosine_weighted_random_direction(float *dir)
+{
+       float theta, phi, rvar;
+       float sin_th;
+       
+       /* cosine weighted angle to axis Z */
+       do {
+               rvar= BLI_frand();
+               theta= BLI_frand() * 0.5 * M_PI;
+               sin_th= sinf(theta);
+       } while (rvar < sin_th);
+       
+       dir[2]= sqrtf(1 - sin_th * sin_th);
+       
+       /* uniformly weighted angle around axis Z */
+       phi= BLI_frand() * M_PI;
+       dir[0]= cosf(phi) * sin_th;
+       dir[1]= sinf(phi) * sin_th;
+}
+
+static void add_virtual_point_light(Render * re, LightcutsData *lcd, LampRen 
*orig, float *col)
+{
+       GroupObject *gonew;
+       LampRen *lar;
+       VlakRen *vla;
+       Isect isec;
+       float tmp[3], dist;
+       
+       isec.mode= RE_RAY_MIRROR; /* TODO: check */
+       isec.faceorig= NULL;
+       isec.oborig= 0;
+       VECCOPY(isec.start, orig->co);
+       if (lcd->random_dirs) {
+               get_cosine_weighted_random_direction(isec.vec);
+               Mat3MulVecfl(orig->mat, isec.vec);
+               VECNEG(isec.vec);
+       }
+       else
+               VECCOPY(isec.vec, orig->vec);
+       VECADDFAC(isec.end, isec.start, isec.vec, lcd->scene_diag);
+       
+       if (!RE_ray_tree_intersect(re->raytree, &isec))
+               return;
+       
+       vla= (VlakRen*)isec.face;
+       
+       lar= (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
+       init_lamp(re, lar);
+       /* XXX: fixed distance or proportional to orig->dist? */
+       lar->dist= orig->dist / 2;
+       lar->distkw= lar->dist * lar->dist;
+       lar->lay= orig->lay;
+       VECCOPY(lar->vec, vla->n);
+       VECNEG(lar->vec);
+       VECCOPY(lar->mat[2], vla->n);
+       VecOrthoBasisf(lar->mat[2], lar->mat[0], lar->mat[1]);
+       Mat3Inv(lar->imat, lar->mat);
+       lar->type = LA_SPOT;
+
+       /* XXX: err... something better than 0.01? */
+       VECADDFAC(lar->co, isec.start, isec.vec, isec.labda - 0.01);
+
+       /* TODO: read color */
+       lar->energy= lamp_get_visibility(orig, lar->co, tmp, &dist);
+       lar->energy*= 1.0 / (lcd->indir_fac * lcd->do_indir);
+       lar->r= lar->energy * col[0];// * isec.col[0];
+       lar->g= lar->energy * col[1];// * isec.col[1];
+       lar->b= lar->energy * col[2];// * isec.col[2];
+
+#ifdef LIGHTCUTS_DEBUG
+       //printf("coordinates: %4f %4f %4f\n", lar->co[0], lar->co[1], 
lar->co[2]);
+#endif
+
+       gonew= MEM_callocN(sizeof(GroupObject), "groupobject");
+       BLI_addtail(&lcd->pointlights, gonew);
+       /* XXX: see remarks on similar code in convert_environment_map */
+       gonew->ob= 0;
+       
+       BLI_addtail(&re->lampren, lar);
+       /* check deallocation */
+       gonew->lampren= lar;
+
+       lcd->trees[TREE_SPOT].counter++;
+       lcd->light_counter++;
+       lcd->vpl_counter++;
+       lar->ray_samp_method = LA_SAMP_CONSTANT;
+}
+
 static void convert_area_light(Render * re, LightcutsData *lcd, LampRen *orig)
 {
        GroupObject *gonew;
@@ -1012,7 +1109,7 @@
        float xdir[3], ydir[3], col[3];
        float stepx, stepy, texvec[2];
        float p, u, v;
-       int k, kk, pos, n;
+       int k, kk, pos, n, i;
        int use_texture= 0;
        int tex_nr;
        
@@ -1028,7 +1125,7 @@
        factor= 2.0 * M_PI * orig->dist / (4.0 * realw * realh * n);
 
        /* XXX: TODO: temporary check just to avoid freezing on undue densities 
*/
-       if (lcd->light_counter + n > re->r.lightcuts_max_lights) {
+       if (lcd->light_counter + n * (1 + lcd->do_indir) > 
re->r.lightcuts_max_lights) {
                printf("Err: required light density would violate light 
limit\n");
                return;
        }
@@ -1107,6 +1204,10 @@
                lcd->trees[TREE_SPOT].counter++;
                lcd->light_counter++;
                lar->ray_samp_method = LA_SAMP_CONSTANT;
+               
+               /* indirect lighting */
+               for (i= 0; i < lcd->do_indir; i++)
+                       add_virtual_point_light(re, lcd, lar, col);
        }
 }
 
@@ -1126,6 +1227,11 @@
        re->lcdata = lcd = MEM_callocN(sizeof(LightcutsData), "LightcutsData");
        pointlights= &lcd->pointlights;
        lcd->light_counter= 0;
+       lcd->indir_fac= re->r.lightcuts_indir_fac;
+       lcd->do_indir= re->r.lightcuts_indirect;
+       lcd->random_dirs= re->r.lightcuts_random_dirs;
+       lcd->error_rate= re->r.lightcuts_max_error;
+       lcd->scene_diag= RE_ray_tree_max_size(re->raytree);
        
        if (re->r.lightcuts_env_map > 0)
                convert_environment_map(re, lcd, re->r.lightcuts_env_map);
@@ -1173,15 +1279,9 @@
 
        /* XXX: this should be equal to re->r.lightcuts_max_lights when light 
generation is in place */
        lcd->max_lights= lcd->light_counter;
-       lcd->error_rate= re->r.lightcuts_max_error;
        lcd->max_cut= MIN2(re->r.lightcuts_max_cut, lcd->light_counter);
        lcd->start_time= PIL_check_seconds_timer();
        
-       /* we need the scene's diagonal squared */
-       lcd->bb_diag_sq= RE_ray_tree_max_size(re->raytree);
-       printf("Scene diagonal %f\n", lcd->bb_diag_sq);
-       lcd->bb_diag_sq*= lcd->bb_diag_sq;
-       
        re->i.infostr= "Building light trees";
        re->stats_draw(&re->i);
 
@@ -1190,7 +1290,7 @@
                if (lcd->trees[i].counter > 0) {
                        lightcuts_fill_array(pointlights, &lcd->trees[i], i);
                        printf("Lightcuts: building %s tree - ", tree_names[i]);
-                       lightcuts_build_tree2(&lcd->trees[i], lcd->bb_diag_sq);
+                       lightcuts_build_tree2(&lcd->trees[i], lcd->scene_diag * 
lcd->scene_diag);
                }
        }
        
@@ -1824,7 +1924,7 @@
        printf("Lightcuts stats\n"
               "---------------\n"
               "Computed samples: %d\n"
-              "Number of (point) lights: %d (%dl + %ds + %do)\n"
+              "Number of (point) lights: %d (%dl + %ds + %do) (%dd + %di)\n"
               "Requested error rate: %.3f\n"
               "Max cut: %d\n"
               "Average cut size: %.2f\n"
@@ -1832,6 +1932,7 @@
               "---------------\n",
                lcd->stat_samples, lcd->light_counter,
                lcd->trees[TREE_LOCAL].counter, lcd->trees[TREE_SUN].counter, 
lcd->trees[TREE_SPOT].counter,
+               lcd->light_counter - lcd->vpl_counter, lcd->vpl_counter,
                lcd->error_rate,
                lcd->max_cut,
                (float)lcd->stat_cut_size / (float)lcd->stat_samples,

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-12 13:30:17 UTC (rev 16065)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c  
2008-08-12 15:06:49 UTC (rev 16066)
@@ -931,7 +931,7 @@
                intersection to be detected in its neighbour face */
                
                if(is->facecontr && is->faceisect);     // optimizing, the 
tests below are not needed
-               else if(is->labda< .1) {
+               else if(is->labda< .1 && is->faceorig) {
                        RayFace *face= is->faceorig;
                        float *origv1, *origv2, *origv3, *origv4;
                        short de= 0;

Modified: 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c
===================================================================
--- 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c   
    2008-08-12 13:30:17 UTC (rev 16065)
+++ 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c   
    2008-08-12 15:06:49 UTC (rev 16066)
@@ -1072,7 +1072,7 @@
                float visifac= 1.0f, t;
                
                VECSUB(lv, co, lar->co);
-               *dist= sqrt( INPR(lv, lv));
+               *dist= sqrt(INPR(lv, lv));
                t= 1.0f/dist[0];
                VECMUL(lv, t);
                
@@ -1115,42 +1115,39 @@
                                        visifac*= t/lar->dist;
                        }
                        
-                       if(visifac > 0.0f) {
-                               if(lar->type==LA_SPOT) {
-                                       float inpr;
-                                       
-                                       if(lar->mode & LA_SQUARE) {
-                                               
if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0f) {
-                                                       float lvrot[3], x;
-                                                       
-                                                       /* rotate view to 
lampspace */
-                                                       VECCOPY(lvrot, lv);
-                                                       
MTC_Mat3MulVecfl(lar->imat, lvrot);
-                                                       
-                                                       x= 
MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2]));
-                                                       /* 1.0f/(sqrt(1+x*x)) 
is equivalent to cos(atan(x)) */
-                                                       
-                                                       inpr= 
1.0f/(sqrt(1.0f+x*x));
-                                               }
-                                               else inpr= 0.0f;
+                       if(lar->type==LA_SPOT && visifac > 0.0f) {
+                               float inpr;
+                               
+                               inpr= INPR(lv, lar->vec);
+                               
+                               if(lar->mode & LA_SQUARE) {
+                                       if(inpr>0.0f) {
+                                               float lvrot[3], x;
+                                               
+                                               /* rotate view to lampspace */
+                                               VECCOPY(lvrot, lv);
+                                               MTC_Mat3MulVecfl(lar->imat, 
lvrot);
+                                               
+                                               x= MAX2(fabs(lvrot[0]/lvrot[2]) 
, fabs(lvrot[1]/lvrot[2]));
+                                               /* 1.0f/(sqrt(1+x*x)) is 
equivalent to cos(atan(x)) */
+                                               
+                                               inpr= 1.0f/(sqrt(1.0f+x*x));
                                        }
-                                       else {
-                                               inpr= 
lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
+                                       else inpr= 0.0f;
+                               }
+                               
+                               t= lar->spotsi;
+                               if(inpr<=t) 
+                                       visifac= 0.0f;
+                               else {
+                                       t= inpr-t;
+                                       if(t<lar->spotbl && lar->spotbl!=0.0f) {
+                                               /* soft area */
+                                               float i= t/lar->spotbl;
+                                               t= i*i;
+                                               inpr*= (3.0f*t-2.0f*t*i);
                                        }
-                                       
-                                       t= lar->spotsi;
-                                       if(inpr<=t) 
-                                               visifac= 0.0f;
-                                       else {

@@ Diff output truncated at 10240 characters. @@

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

Reply via email to