Revision: 15111
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15111
Author:   unclezeiv
Date:     2008-06-04 01:40:56 +0200 (Wed, 04 Jun 2008)

Log Message:
-----------
- luminosity, as added in revision 15107, should not be taken into account when 
computing the error as it is not a bound for the subtree: reverted. It may be 
possible to add it back later if computing a suitable bound during tree 
building.
- each cluster now saves its own lamp's absolute color (i.e. not premultiplied 
by its energy). This allowed to simplify per-pixel code considerably.

Revision Links:
--------------
    
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15107

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 22:54:24 UTC (rev 15110)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-06-03 23:40:56 UTC (rev 15111)
@@ -60,6 +60,7 @@
        float intensity;
        float min[3];
        float max[3];
+       float col[3];
        LampRen * lar;
 } LightcutsCluster;
 
@@ -76,7 +77,6 @@
        float contr_factor_noshad;
        float f_clus;
        float f_clus_noshad;
-       float luminosity;
 } CutNode;
 
 typedef struct LightcutsData {
@@ -99,9 +99,7 @@
 
 #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_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.299*(c)[0] + 0.587*(c)[1] + 0.114*(c)[2])
 /* #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;}
 
@@ -121,11 +119,6 @@
        return (one->intensity + two->intensity) * VEC_LEN_SQ(diff);
 }
 
-static LampRen * random_select(LampRen * one, float ione, LampRen * two, float 
itwo)
-{
-       return (BLI_frand() * (ione + itwo)) < ione ? one : two;
-}
-
 static void add_new_cluster(LightcutsCluster * array, LightcutsClusterPair * 
minpair, int * root)
 {
        LightcutsCluster *one = &array[minpair->first];
@@ -150,7 +143,14 @@
        DO_MINMAX(two->max, dest->min, dest->max);
        
        /* the representative light is chosen randomly among children */
-       dest->lar = random_select(one->lar, one->intensity, two->lar, 
two->intensity);
+       if (BLI_frand() * (one->intensity + two->intensity) < one->intensity) {
+               dest->lar= one->lar;
+               VECCOPY(dest->col, one->col);
+       }
+       else {
+               dest->lar= two->lar;
+               VECCOPY(dest->col, two->col);
+       }
        
        (*root)++;
 }
@@ -220,6 +220,12 @@
                VECCOPY(clus->max, lar->co);
                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++;
                lcd->free_local++;
        }
@@ -472,8 +478,6 @@
  * RESOLUTION: the one of the lamp, then adjusted
  */
 
-#define ADDCONTR(t, lar, f) {t[0]+= (lar)->r*(f); t[1]+= (lar)->g*(f); t[2]+= 
(lar)->b*(f);}
-
 void lightcuts_do_lights(LightcutsData *lcd, LightContribFunc get_contrib, 
ShadeInput *shi, ShadeResult *shr)
 {
        /* TODO: show that this size is always sufficient */
@@ -498,24 +502,22 @@
        {
                CutNode *root= &cut_nodes[0];
                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);
+               get_contrib(clus->lar, shi, &i, &i_noshad);
                root->contr_factor= i;
                root->f_clus= i * clus->intensity;
-               ADDCONTR(totest, lar, root->f_clus / lar->energy);
+               VECADDFAC(totest, totest, clus->col, root->f_clus);
                
                if(shi->passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
                        root->contr_factor_noshad= i_noshad;
                        root->f_clus_noshad= i_noshad * clus->intensity;
-                       ADDCONTR(totest_noshad, lar, root->f_clus_noshad / 
lar->energy);
+                       VECADDFAC(totest_noshad, totest_noshad, clus->col, 
root->f_clus_noshad);
                }
                
-               BLI_heap_insert(cut, -root->error_bound * clus->intensity * 
root->luminosity, root);
+               BLI_heap_insert(cut, -root->error_bound * clus->intensity, 
root);
        }
        
        /* at each iteration the heap grows by one, but we have a maximum size 
*/
@@ -536,7 +538,7 @@
                        continue;
                }
                
-               if (LC_LUMINOSITY(totest) * lcd->error_rate > node->error_bound 
* parent->intensity * node->luminosity) {
+               if (LC_LUMINOSITY(totest) * lcd->error_rate > node->error_bound 
* parent->intensity) {
                        break;
                } else {
                        LightcutsCluster *rep= 
&lcd->array_local[parent->child1];
@@ -554,7 +556,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 / 
rep->lar->energy);
+                       VECADDFAC(totest, totest, rep->col, -node->f_clus);
                        
                        /* this is a strong assumption on linearity of 
intensity contribution... is it strong indeed?
                         * and numerically questionable again */
@@ -565,10 +567,9 @@
                        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;
-                       c_rep->luminosity= node->luminosity;
-                       ADDCONTR(totest, rep->lar, c_rep->f_clus / 
rep->lar->energy);
+                       VECADDFAC(totest, totest, rep->col, c_rep->f_clus);
                                                
-                       BLI_heap_insert(cut, -c_rep->error_bound * 
rep->intensity * c_rep->luminosity, c_rep);
+                       BLI_heap_insert(cut, -c_rep->error_bound * 
rep->intensity, c_rep);
                        
                        /* for the "unrepresented" light we have to compute 
stuff from scratch */
                        c_unrep->id= unrep->id;
@@ -576,21 +577,20 @@
                        get_contrib(unrep->lar, shi, &i, &i_noshad);
                        c_unrep->contr_factor= i;
                        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);
+                       VECADDFAC(totest, totest, unrep->col, c_unrep->f_clus);
                        
-                       BLI_heap_insert(cut, -c_unrep->error_bound * 
unrep->intensity * c_unrep->luminosity, c_unrep);
+                       BLI_heap_insert(cut, -c_unrep->error_bound * 
unrep->intensity, c_unrep);
                        
                        if(shi->passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
-                               ADDCONTR(totest_noshad, rep->lar, 
-node->f_clus_noshad / rep->lar->energy);
+                               VECADDFAC(totest_noshad, totest_noshad, 
rep->col, -node->f_clus_noshad);
                                
                                c_rep->contr_factor_noshad= 
node->contr_factor_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);
+                               VECADDFAC(totest_noshad, totest_noshad, 
rep->col, c_rep->f_clus_noshad);
                                
                                c_unrep->contr_factor_noshad= i_noshad;
                                c_unrep->f_clus_noshad= i_noshad * 
unrep->intensity;
-                               ADDCONTR(totest_noshad, unrep->lar, 
c_unrep->f_clus_noshad / unrep->lar->energy);
+                               VECADDFAC(totest_noshad, totest_noshad, 
unrep->col, c_unrep->f_clus_noshad);
                        }
                }
        }


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

Reply via email to