Revision: 16985
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16985
Author:   unclezeiv
Date:     2008-10-09 00:50:43 +0200 (Thu, 09 Oct 2008)

Log Message:
-----------
Refactored some redundant code for "multiple representatives"; also fixed a bug 
that would make "noisy" images brighter than the original ones.

Modified Paths:
--------------
    branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c

Modified: 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-10-08 20:54:19 UTC (rev 16984)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-10-08 22:50:43 UTC (rev 16985)
@@ -131,6 +131,7 @@
 {
        LampRen *lar;
        float intensity;
+       
 } ClusRep;
 
 /* node of the lightcuts tree */
@@ -141,15 +142,12 @@
        int id; /* must be able to accommodate millions of lights */
        int child1;
        int child2;
-       float intensity;
        float min[3];
        float max[3];
-       float col[3];
        /* cone_* variables only for oriented lights */
        float cone_dir[3]; /* store normalized */
        float cone_angle;
        float luminance;
-       LampRen * lar;
        short falloff_type, sphere;
        float falloff_dist;
        float sphere_dist;
@@ -368,25 +366,7 @@
        /* if LA_SPOT, compute new bounding cone */
        if (one->type == CLUSTER_SPOT)
                dest->cone_angle= get_bounding_cone(one, two, dest->cone_dir);
-
-       if (lcd->options & LC_OPT_NO_RAND_CLS)
-               use_one_as_repr= one->luminance > two->luminance;
-       else
-               use_one_as_repr= BLI_frand() * (one->luminance + 
two->luminance) < one->luminance;
        
-       /* the representative light is chosen randomly among children */
-       if (use_one_as_repr) {
-               dest->lar= one->lar;
-               VECCOPY(dest->col, one->col);
-               rep= 0;
-       }
-       else {
-               dest->lar= two->lar;
-               VECCOPY(dest->col, two->col);
-               rep= 1;
-       }
-       dest->intensity= dest->luminance / INPR(lcd->colw, dest->col);
-       
        /* worst case falloff type/dist for conservative error estimation */
        dest->falloff_type= falloff_merge[one->falloff_type][two->falloff_type];
        dest->falloff_dist= MAX2(one->falloff_dist, two->falloff_dist);
@@ -425,7 +405,7 @@
                        for (j= 0; j< one->mrep_len; j++) {
                                if (used[j])
                                        continue;
-                               lum= one->mrep_list[j].intensity;
+                               lum= one->mrep_list[j].intensity * 
dest->luminance / one->luminance;
                                if (x <= lum) {
                                        dest->mrep_list[i].lar= 
one->mrep_list[j].lar;
                                        dest->mrep_list[i].intensity= lum;
@@ -444,7 +424,7 @@
                        for (j= 0; j< two->mrep_len; j++) {
                                if (used[one->mrep_len + j])
                                        continue;
-                               lum= two->mrep_list[j].intensity;
+                               lum= two->mrep_list[j].intensity * 
dest->luminance / two->luminance;
                                if (x <= lum) {
                                        dest->mrep_list[i].lar= 
two->mrep_list[j].lar;
                                        dest->mrep_list[i].intensity= lum;
@@ -464,6 +444,27 @@
                /* sort list and allocate list */
                qsort(dest->mrep_list, dest->mrep_len, sizeof(ClusRep), 
cmp_clusrep);
        }
+       else {
+               if (lcd->options & LC_OPT_NO_RAND_CLS)
+                       use_one_as_repr= one->luminance > two->luminance;
+               else
+                       use_one_as_repr= BLI_frand() * (one->luminance + 
two->luminance) < one->luminance;
+               
+               dest->mrep_list= MEM_callocN(sizeof(ClusRep), "lc mrep single");
+               dest->mrep_len= 1;
+               
+               /* the representative light is chosen randomly among children */
+               if (use_one_as_repr) {
+                       dest->mrep_list[0].lar= one->mrep_list[0].lar;
+                       dest->mrep_intensity= dest->mrep_list[0].intensity= 
dest->luminance / one->mrep_list[0].lar->energy;
+                       rep= 0;
+               }
+               else {
+                       dest->mrep_list[0].lar= two->mrep_list[0].lar;
+                       dest->mrep_intensity= dest->mrep_list[0].intensity= 
dest->luminance / two->mrep_list[0].lar->energy;
+                       rep= 1;
+               }
+       }
 
        (*root)++;
        
@@ -538,7 +539,7 @@
 #ifdef LIGHTCUTS_DEBUG
        printf("id %d, type %d, energy %10.7f, intensity %10.7f, luminance 
%10.7f ", one->id, one->type, one->lar->energy, one->intensity, one->luminance);
 #endif
-       other= BLI_kdtree_find_callback(tree, one->lar->co, NULL, one->id, 
cb_update_metric_max_dist, data, nearest);
+       other= BLI_kdtree_find_callback(tree, one->mrep_list[0].lar->co, NULL, 
one->id, cb_update_metric_max_dist, data, nearest);
        
        if (other != -1)
        {
@@ -574,7 +575,6 @@
                clus->type = LA_TYPE_TO_CLUSTER_TYPE(cur_type);
                clus->in_tree = 0;
                clus->id = tree->free;
-               clus->intensity = lar->energy;
 
                switch (lar->type) {
                case LA_LOCAL:
@@ -598,14 +598,10 @@
                        clus->cone_angle= 0.0f;
                        break;
                }
-               clus->lar = lar;
 
                /* we need the original lamp color, not the premultiplied one */
                /* TODO: maybe we could directly preserve this value when 
creating the render database? */
-               clus->col[0]= lar->r / lar->energy;
-               clus->col[1]= lar->g / lar->energy;
-               clus->col[2]= lar->b / lar->energy;
-               clus->luminance= INPR(colw, clus->col) * lar->energy;
+               clus->luminance= lar->r * colw[0] + lar->g * colw[1] + lar->b * 
colw[2];
                
                switch (lar->falloff_type) {
                case LA_FALLOFF_CONSTANT:
@@ -651,12 +647,10 @@
                        clus->sphere_dist = lar->dist;
                }
                
-               if (lcd->options & LC_OPT_MULT_REPR) {
-                       clus->mrep_len= 1;
-                       clus->mrep_list= MEM_callocN(sizeof(ClusRep), 
"clusrep");
-                       clus->mrep_list[0].lar= clus->lar;
-                       clus->mrep_list[0].intensity= clus->mrep_intensity= 
INPR(colw, clus->col); 
-               }
+               clus->mrep_len= 1;
+               clus->mrep_list= MEM_callocN(sizeof(ClusRep), "clusrep");
+               clus->mrep_list[0].lar= lar;
+               clus->mrep_list[0].intensity= clus->mrep_intensity= 
clus->luminance / lar->energy;
 
                clus++;
                tree->free++;
@@ -792,7 +786,7 @@
        
        /* kdtree construction */
        for (i= 0; i < tree->counter; i++)
-               BLI_kdtree_insert(kdtree, i, array[i].lar->co, NULL);
+               BLI_kdtree_insert(kdtree, i, array[i].mrep_list[0].lar->co, 
NULL);
 
 #ifdef LIGHTCUTS_DEBUG
        if (print_times) {              
@@ -2235,8 +2229,10 @@
        dbg_convert[tree->node]= 0;
 #endif
        if (node->error_bound > FLT_EPSILON) {
-               float intensity= clus->intensity;
-               node->used_lar= clus->lar;
+               float intensity;
+               float col[3];
+               node->used_lar= clus->mrep_list[0].lar;
+               intensity= clus->luminance / clus->mrep_list[0].intensity;
                if (lcd->options & LC_OPT_MULT_REPR && clus->mrep_len > 1) {
                        int i;
                        float rand= BLI_frand() * clus->mrep_intensity;
@@ -2251,20 +2247,24 @@
                                rand -= lum;
                        }
                }
+               col[0]= node->used_lar->r / node->used_lar->energy; 
+               col[1]= node->used_lar->g / node->used_lar->energy; 
+               col[2]= node->used_lar->b / node->used_lar->energy;
+               
                single_light_contrib(node->used_lar, si->shi, &i, &i_noshad, 
&t);
                lcd->stat_rays_shot++;
                node->contr_factor= MAX2(i, 0.0f);
                node->contr_factor_spec= MAX2(t, 0.0f);
                node->f_clus= node->contr_factor * intensity;
                node->f_clus_spec= node->contr_factor_spec * intensity;
-               VECADDFAC(si->totest_shad, si->totest_shad, clus->col, 
node->f_clus);
-               VECADDFAC(si->totest_spec, si->totest_spec, clus->col, 
node->f_clus_spec);
+               VECADDFAC(si->totest_shad, si->totest_shad, col, node->f_clus);
+               VECADDFAC(si->totest_spec, si->totest_spec, col, 
node->f_clus_spec);
 
                /* XXX this part only for root ? */
                if(si->shi->passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
                        node->contr_factor_noshad= MAX2(i_noshad, 0.0f);
                        node->f_clus_noshad= node->contr_factor_noshad * 
intensity;
-                       VECADDFAC(si->totest_noshad, si->totest_noshad, 
clus->col, node->f_clus_noshad);
+                       VECADDFAC(si->totest_noshad, si->totest_noshad, col, 
node->f_clus_noshad);
                }
                
 #ifdef LIGHTCUTS_DEBUG
@@ -2434,6 +2434,7 @@
                        LightcutsCluster *unrep= &array[hinode->child2];
                        CutNode *cn_rep= &si.cut_nodes[si.free_node];
                        CutNode *cn_unrep= &si.cut_nodes[si.free_node + 1];
+                       float hicol[3];
 
                        if (lcd->options & LC_OPT_MULT_REPR) {
                                int i;
@@ -2443,7 +2444,7 @@
                                if (i == rep->mrep_len)
                                        SWAP(LightcutsCluster*, rep, unrep);
                        }
-                       else if (hinode->lar != rep->lar)
+                       else if (hinode->mrep_list[0].lar != 
rep->mrep_list[0].lar)
                                SWAP(LightcutsCluster*, rep, unrep);
 
 #ifdef LIGHTCUTS_DEBUG
@@ -2458,33 +2459,34 @@
                         * but please note that it's the same quantity
                         * we are not calculating it in different ways
                         */
-                       VECADDFAC(si.totest_shad, si.totest_shad, hinode->col, 
-cn_hinode->f_clus);
-                       VECADDFAC(si.totest_spec, si.totest_spec, hinode->col, 
-cn_hinode->f_clus_spec);
+                       hicol[0]= cn_hinode->used_lar->r / 
cn_hinode->used_lar->energy;
+                       hicol[1]= cn_hinode->used_lar->g / 
cn_hinode->used_lar->energy;
+                       hicol[2]= cn_hinode->used_lar->b / 
cn_hinode->used_lar->energy;
+                       VECADDFAC(si.totest_shad, si.totest_shad, hicol, 
-cn_hinode->f_clus);
+                       VECADDFAC(si.totest_spec, si.totest_spec, hicol, 
-cn_hinode->f_clus_spec);
                        
                        if(si.shi->passflag & 
(SCE_PASS_DIFFUSE|SCE_PASS_SHADOW))
-                               VECADDFAC(si.totest_noshad, si.totest_noshad, 
rep->col, -cn_hinode->f_clus_noshad);
+                               VECADDFAC(si.totest_noshad, si.totest_noshad, 
hicol, -cn_hinode->f_clus_noshad);
                                                        
 #ifdef LIGHTCUTS_DEBUG
                        dbg_totlum-= cn_hinode->contr_factor * 
hinode->luminance;
 #endif
                        
-                       /* TODO: check if we can save some calculations with MR 
*/
-                       //if (lcd->options & LC_OPT_MULT_REPR)
-                       //      fill_cut_node(lcd, cn_rep, rep, &si);
-                       //else
+                       /* for the represented light we can reuse most 
calculations */
                        {
-                               /* for the represented light we can reuse most 
calculations */
+                               float intensity= rep->luminance / 
INPR(lcd->colw, hicol);
                                cn_rep->id= rep->id;
                                cn_rep->type= rep->type;
                                cn_rep->error_bound= calc_geometric_eb(lcd, 
rep, si.shi->co) * calc_material_eb(rep, si.shi, &si.sci);
+                               cn_rep->used_lar= cn_hinode->used_lar;
 
                                if (cn_rep->error_bound > FLT_EPSILON) {
                                        cn_rep->contr_factor= 
cn_hinode->contr_factor;
                                        cn_rep->contr_factor_spec= 
cn_hinode->contr_factor_spec;
-                                       cn_rep->f_clus= cn_hinode->contr_factor 
* rep->intensity;
-                                       cn_rep->f_clus_spec= 
cn_hinode->contr_factor_spec * rep->intensity;
-                                       VECADDFAC(si.totest_shad, 
si.totest_shad, rep->col, cn_rep->f_clus);
-                                       VECADDFAC(si.totest_spec, 
si.totest_spec, rep->col, cn_rep->f_clus_spec);
+                                       cn_rep->f_clus= cn_hinode->contr_factor 
* intensity;
+                                       cn_rep->f_clus_spec= 
cn_hinode->contr_factor_spec * intensity;
+                                       VECADDFAC(si.totest_shad, 
si.totest_shad, hicol, cn_rep->f_clus);
+                                       VECADDFAC(si.totest_spec, 
si.totest_spec, hicol, cn_rep->f_clus_spec);
 #ifdef LIGHTCUTS_DEBUG
                                        dbg_totlum+= rep->luminance * 
cn_rep->contr_factor;
 #endif
@@ -2494,7 +2496,7 @@
                                        else {
                                                si.used++;
 
-                                               if (rep->lar->lightcuts_options 
& LC_LAR_INDIRECT) {
+                                               if 
(cn_hinode->used_lar->lightcuts_options & LC_LAR_INDIRECT) {
                                                        
si.vpl_queue[si.vpl_to_cap]= cn_rep - si.cut_nodes;
                                                        si.vpl_to_cap++;
                                                }
@@ -2513,8 +2515,8 @@
                                
                                if(si.shi->passflag & 
(SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
                                        cn_rep->contr_factor_noshad= 
cn_hinode->contr_factor_noshad;
-                                       cn_rep->f_clus_noshad= 
cn_hinode->contr_factor_noshad * rep->intensity;

@@ 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