Revision: 15107
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15107
Author:   unclezeiv
Date:     2008-06-03 23:05:37 +0200 (Tue, 03 Jun 2008)

Log Message:
-----------
Nodes candidates for the cut were not ordered correctly: now also cluster 
intensity and cluster luminosity are taken into account. This bug would 
previously surface in some scenes producing incorrect renderings (compared to 
"plain" ones). It's actually pretty surprising that most scenes rendered 
correctly!

Other fixes:
- cluster contribution was wrongly dividing by lar->energy, despite not being 
influenced by it
- on the other hand, when using lar->r,g,b I was not dividing by lar->energy as 
I should have (blender premultiplies lamp color by lamp energy while creating 
the render database)
- max cut is now never more than the actual number of lights (even though 
having that few lights doesn't make much sense)

Other changes:
- green channel in false colour now shows leaf nodes to cut nodes ratio

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-06-03 19:56:19 UTC (rev 15106)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-06-03 21:05:37 UTC (rev 15107)
@@ -76,6 +76,7 @@
        float contr_factor_noshad;
        float f_clus;
        float f_clus_noshad;
+       float luminosity;
 } CutNode;
 
 typedef struct LightcutsData {
@@ -98,7 +99,10 @@
 
 #define VEC_LEN_SQ(v) (v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
 /* TODO: tentative calculation, will look better into it */
-#define LC_LUMINOSITY(c) (0.299*c[0] + 0.587*c[1] + 0.114*c[2])
+#define LC_LUMINOSITY_3(r,g,b) (0.299*(r) + 0.587*(g) + 0.114*(b))
+#define LC_LUMINOSITY(c) (LC_LUMINOSITY_3((c)[0],(c)[1],(c)[2]))
+#define LC_LUMINOSITY_LAMP(lar) (LC_LUMINOSITY_3((lar)->r,(lar)->g,(lar)->b))
+/* #define LC_LUMINOSITY(c) (0.316*c[0] + 0.460*c[1] + 0.224*c[2]) */
 #define VECCOPYMUL(v1,v2,aS) {*(v1)= *(v2)*aS; *(v1+1)= *(v2+1)*aS; *(v1+2)= 
*(v2+2)*aS;}
 
 static float lightcuts_compute_metric(LightcutsCluster * one, LightcutsCluster 
* two)
@@ -428,7 +432,7 @@
        /* XXX: whis 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= re->r.lightcuts_max_cut;
+       lcd->max_cut= MIN2(re->r.lightcuts_max_cut, lcd->light_counter);
        
        /* TODO: look for a better error condition in case we have no lights */
        if (pointlights->first) {
@@ -493,23 +497,25 @@
        
        {
                CutNode *root= &cut_nodes[0];
-               LampRen *lar= lcd->array_local[lcd->root_local].lar;
+               LightcutsCluster *clus= &lcd->array_local[lcd->root_local];
+               LampRen *lar= clus->lar;
                
                root->id= lcd->root_local;
                root->error_bound= calc_geometric_eb(lcd, lcd->root_local, 
shi->co);
+               root->luminosity= LC_LUMINOSITY_LAMP(lar) / lar->energy;
                
                get_contrib(lar, shi, &i, &i_noshad);
                root->contr_factor= i;
-               root->f_clus= i * lcd->array_local[lcd->root_local].intensity / 
lar->energy;
-               ADDCONTR(totest, lar, root->f_clus);
+               root->f_clus= i * clus->intensity;
+               ADDCONTR(totest, lar, root->f_clus / lar->energy);
                
                if(shi->passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
                        root->contr_factor_noshad= i_noshad;
-                       root->f_clus_noshad= i_noshad * 
lcd->array_local[lcd->root_local].intensity / lar->energy;
-                       ADDCONTR(totest_noshad, lar, root->f_clus_noshad);
+                       root->f_clus_noshad= i_noshad * clus->intensity;
+                       ADDCONTR(totest_noshad, lar, root->f_clus_noshad / 
lar->energy);
                }
                
-               BLI_heap_insert(cut, -root->error_bound, root);
+               BLI_heap_insert(cut, -root->error_bound * clus->intensity * 
root->luminosity, root);
        }
        
        /* at each iteration the heap grows by one, but we have a maximum size 
*/
@@ -518,7 +524,7 @@
                LightcutsCluster *parent;
                
                node= BLI_heap_popmin(cut);
-               if (node < cut_nodes || node >= cut_nodes + (lcd->max_lights * 
2 + 1)) {
+               if (node < cut_nodes || node >= (cut_nodes + 
lcd->cut_nodes_size)) {
                        printf("tricky node! at %d, %d (it=%d)\n", shi->xs, 
shi->ys, it);
                        break;
                }
@@ -530,7 +536,7 @@
                        continue;
                }
                
-               if (LC_LUMINOSITY(totest) * lcd->error_rate > node->error_bound 
* parent->intensity) {
+               if (LC_LUMINOSITY(totest) * lcd->error_rate > node->error_bound 
* parent->intensity * node->luminosity) {
                        break;
                } else {
                        LightcutsCluster *rep= 
&lcd->array_local[parent->child1];
@@ -548,7 +554,7 @@
                         * but please note that it's the same quantity
                         * we are not calculating it in different ways
                         */
-                       ADDCONTR(totest, rep->lar, -node->f_clus);
+                       ADDCONTR(totest, rep->lar, -node->f_clus / 
rep->lar->energy);
                        
                        /* this is a strong assumption on linearity of 
intensity contribution... is it strong indeed?
                         * and numerically questionable again */
@@ -558,31 +564,33 @@
                        c_rep->id= rep->id;
                        c_rep->error_bound= calc_geometric_eb(lcd, rep->id, 
shi->co);
                        c_rep->contr_factor= node->contr_factor;
-                       c_rep->f_clus= node->contr_factor * rep->intensity / 
rep->lar->energy;
-                       ADDCONTR(totest, rep->lar, c_rep->f_clus);
+                       c_rep->f_clus= node->contr_factor * rep->intensity;
+                       c_rep->luminosity= node->luminosity;
+                       ADDCONTR(totest, rep->lar, c_rep->f_clus / 
rep->lar->energy);
                                                
-                       BLI_heap_insert(cut, -c_rep->error_bound, c_rep);
+                       BLI_heap_insert(cut, -c_rep->error_bound * 
rep->intensity * c_rep->luminosity, c_rep);
                        
                        /* for the "unrepresented" light we have to compute 
stuff from scratch */
                        c_unrep->id= unrep->id;
                        c_unrep->error_bound= calc_geometric_eb(lcd, unrep->id, 
shi->co);
                        get_contrib(unrep->lar, shi, &i, &i_noshad);
                        c_unrep->contr_factor= i;
-                       c_unrep->f_clus= i * unrep->intensity / 
unrep->lar->energy;
-                       ADDCONTR(totest, unrep->lar, c_unrep->f_clus);
+                       c_unrep->f_clus= i * unrep->intensity;
+                       c_unrep->luminosity= LC_LUMINOSITY_LAMP(unrep->lar) / 
unrep->lar->energy;
+                       ADDCONTR(totest, unrep->lar, c_unrep->f_clus / 
unrep->lar->energy);
                        
-                       BLI_heap_insert(cut, -c_unrep->error_bound, c_unrep);
+                       BLI_heap_insert(cut, -c_unrep->error_bound * 
unrep->intensity * c_unrep->luminosity, c_unrep);
                        
                        if(shi->passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
-                               ADDCONTR(totest_noshad, rep->lar, 
-node->f_clus_noshad);
+                               ADDCONTR(totest_noshad, rep->lar, 
-node->f_clus_noshad / rep->lar->energy);
                                
                                c_rep->contr_factor_noshad= 
node->contr_factor_noshad;
-                               c_rep->f_clus_noshad= node->contr_factor_noshad 
* rep->intensity / rep->lar->energy;
-                               ADDCONTR(totest_noshad, rep->lar, 
c_rep->f_clus_noshad);
+                               c_rep->f_clus_noshad= node->contr_factor_noshad 
* rep->intensity;
+                               ADDCONTR(totest_noshad, rep->lar, 
c_rep->f_clus_noshad / rep->lar->energy);
                                
                                c_unrep->contr_factor_noshad= i_noshad;
-                               c_unrep->f_clus_noshad= i_noshad * 
unrep->intensity / unrep->lar->energy;
-                               ADDCONTR(totest_noshad, unrep->lar, 
c_unrep->f_clus_noshad);
+                               c_unrep->f_clus_noshad= i_noshad * 
unrep->intensity;
+                               ADDCONTR(totest_noshad, unrep->lar, 
c_unrep->f_clus_noshad / unrep->lar->energy);
                        }
                }
        }
@@ -605,8 +613,8 @@
                VECCOPY(shr->diff, shr->shad);
        
        if (shi->passflag & SCE_PASS_LCFAUX) {
-               shr->faux[0]= (float)(used + BLI_heap_size(cut)) / 
(float)(MIN2(lcd->max_cut, lcd->light_counter));
-               shr->faux[1]= 0.5;
+               shr->faux[0]= (float)(used + BLI_heap_size(cut)) / lcd->max_cut;
+               shr->faux[1]= (float)used/(float)lcd->max_cut;
                shr->faux[2]= 0.5;
                shr->faux[3]= (float)((used + BLI_heap_size(cut)) > 0.0);
        }


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

Reply via email to