Revision: 15035
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15035
Author:   unclezeiv
Date:     2008-05-29 01:41:47 +0200 (Thu, 29 May 2008)

Log Message:
-----------
Fixed "diffuse" and "shadow" render passes, which are now properly supported.
Also, code changes allowed simplification of the CutNode structure.

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

Modified: 
branches/soc-2008-unclezeiv/source/blender/render/intern/include/lightcuts.h
===================================================================
--- 
branches/soc-2008-unclezeiv/source/blender/render/intern/include/lightcuts.h    
    2008-05-28 23:38:40 UTC (rev 15034)
+++ 
branches/soc-2008-unclezeiv/source/blender/render/intern/include/lightcuts.h    
    2008-05-28 23:41:47 UTC (rev 15035)
@@ -37,7 +37,7 @@
 
 void lightcuts_free(struct LightcutsData **p);
 
-typedef float (*LightContribFunc)(LampRen *lar, ShadeInput *shi);
+typedef void (*LightContribFunc)(LampRen *lar, ShadeInput *shi, float *i, 
float *i_noshad);
 
 void lightcuts_do_lights(struct LightcutsData *lcd, LightContribFunc 
get_contrib, ShadeInput *shi, ShadeResult *shr);
 

Modified: 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-05-28 23:38:40 UTC (rev 15034)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-05-28 23:41:47 UTC (rev 15035)
@@ -71,10 +71,11 @@
 
 typedef struct CutNode {
        int id;
+       float error_bound;
        float contr_factor;
-       float contr_own[3];
-       float contr_clus[3];
-       float error_bound;
+       float contr_factor_noshad;
+       float f_clus;
+       float f_clus_noshad;
 } CutNode;
 
 typedef struct LightcutsData {
@@ -460,6 +461,8 @@
  * 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 */
@@ -467,6 +470,7 @@
        int free_node= 1;
        int it= 0;
        int used= 0;
+       float i, i_noshad;
        
        /* this heap maintaines the current cut */
        /* TODO: its maximum size is known in advance, this allows to
@@ -476,6 +480,7 @@
        
        /* this is the total radiance estimate, continuously updated */
        float totest[3]= {0.0f, 0.0f, 0.0f};
+       float totest_noshad[3]= {0.0f, 0.0f, 0.0f};
        
        cut_nodes= MEM_callocN(sizeof(CutNode) * (lcd->max_lights * 2 + 1), 
"cut_nodes");
        
@@ -484,21 +489,19 @@
                LampRen *lar= lcd->array_local[lcd->root_local].lar;
                
                root->id= lcd->root_local;
+               root->error_bound= calc_geometric_eb(lcd, lcd->root_local, 
shi->co);
                
-               root->contr_factor= get_contrib(lar, shi);
+               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->contr_own[0]= lar->r * root->contr_factor;
-               root->contr_own[1]= lar->g * root->contr_factor;
-               root->contr_own[2]= lar->b * root->contr_factor;
+               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->contr_clus[0]= root->contr_own[0] * 
lcd->array_local[lcd->root_local].intensity / lar->energy;
-               root->contr_clus[1]= root->contr_own[1] * 
lcd->array_local[lcd->root_local].intensity / lar->energy;
-               root->contr_clus[2]= root->contr_own[2] * 
lcd->array_local[lcd->root_local].intensity / lar->energy;
-               
-               root->error_bound= calc_geometric_eb(lcd, lcd->root_local, 
shi->co);
-               
-               VECADD(totest, totest, root->contr_clus);
-               
                BLI_heap_insert(cut, -root->error_bound, root);
        }
        
@@ -519,7 +522,7 @@
                        used++;
                        continue;
                }
-                               
+               
                if (LC_LUMINOSITY(totest) * lcd->error_rate > node->error_bound 
* parent->intensity) {
                        break;
                } else {
@@ -538,49 +541,62 @@
                         * but please note that it's the same quantity
                         * we are not calculating it in different ways
                         */
-                       VECSUB(totest, totest, node->contr_clus);
+                       ADDCONTR(totest, rep->lar, -node->f_clus);
                        
                        /* this is a strong assumption on linearity of 
intensity contribution... is it strong indeed?
                         * and numerically questionable again */
                        /* TODO: there is room to reuse the same block here */
                        
                        /* for the reprsented light we can reuse most 
calculations */
+                       c_rep->id= rep->id;
+                       c_rep->error_bound= calc_geometric_eb(lcd, rep->id, 
shi->co);
                        c_rep->contr_factor= node->contr_factor;
-                       VECCOPY(c_rep->contr_own, node->contr_own);
-                       VECCOPYMUL(c_rep->contr_clus, c_rep->contr_own, 
rep->intensity / rep->lar->energy);
-                       c_rep->error_bound= calc_geometric_eb(lcd, rep->id, 
shi->co);
-                       c_rep->id= rep->id;
-                       
+                       c_rep->f_clus= node->contr_factor * rep->intensity / 
rep->lar->energy;
+                       ADDCONTR(totest, rep->lar, c_rep->f_clus);
+                                               
                        BLI_heap_insert(cut, -c_rep->error_bound, c_rep);
                        
-                       VECADD(totest, totest, c_rep->contr_clus);
-                       
                        /* for the "unrepresented" light we have to compute 
stuff from scratch */
-                       c_unrep->contr_factor= get_contrib(unrep->lar, shi);
-                       c_unrep->contr_own[0]= unrep->lar->r * 
c_unrep->contr_factor;
-                       c_unrep->contr_own[1]= unrep->lar->g * 
c_unrep->contr_factor;
-                       c_unrep->contr_own[2]= unrep->lar->b * 
c_unrep->contr_factor;
-                       c_unrep->contr_clus[0]= c_unrep->contr_own[0] * 
unrep->intensity / unrep->lar->energy;
-                       c_unrep->contr_clus[1]= c_unrep->contr_own[1] * 
unrep->intensity / unrep->lar->energy;
-                       c_unrep->contr_clus[2]= c_unrep->contr_own[2] * 
unrep->intensity / unrep->lar->energy;
+                       c_unrep->id= unrep->id;
                        c_unrep->error_bound= calc_geometric_eb(lcd, unrep->id, 
shi->co);
-                       c_unrep->id= unrep->id;
+                       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);
+                       
                        BLI_heap_insert(cut, -c_unrep->error_bound, c_unrep);
                        
-                       VECADD(totest, totest, c_unrep->contr_clus);
+                       if(shi->passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
+                               ADDCONTR(totest_noshad, rep->lar, 
-node->f_clus_noshad);
+                               
+                               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_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);
+                       }
                }
        }
        
        /*
         * here, the content of the queue IS the cut, but we already should have
-        * an updated TOTREP value (even thought numerically questionable?)
+        * an updated TOTEST value (even thought numerically questionable?)
         */
        
        shr->shad[0]+= totest[0]*shi->r;
        shr->shad[1]+= totest[1]*shi->g;
        shr->shad[2]+= totest[2]*shi->b;
-       VECCOPY(shr->diff, shr->shad);
        
+       if(shi->passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
+               shr->diff[0]+= totest_noshad[0]*shi->r;
+               shr->diff[1]+= totest_noshad[1]*shi->g;
+               shr->diff[2]+= totest_noshad[2]*shi->b;
+       }
+       else
+               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;

Modified: 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c
===================================================================
--- 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c   
    2008-05-28 23:38:40 UTC (rev 15034)
+++ 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c   
    2008-05-28 23:41:47 UTC (rev 15035)
@@ -1525,7 +1525,7 @@
        diff[2]= R.wrld.linfac*(1.0f-exp( diff[2]*R.wrld.logfac) );
 }
 
-static float single_light_contrib(LampRen *lar, ShadeInput *shi);
+static void single_light_contrib(LampRen *lar, ShadeInput *shi, float *pi, 
float *pi_noshad);
 
 void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
 {
@@ -2096,7 +2096,7 @@
 #else // SIMPLIFIED STARTS
 
 /* function returns raw diff, spec and full shadowed diff in the 'shad' pass */
-static float single_light_contrib(LampRen *lar, ShadeInput *shi)
+static void single_light_contrib(LampRen *lar, ShadeInput *shi, float *pi, 
float *pi_noshad)
 {
        Material *ma= shi->mat;
        float lv[3], lampdist, shadfac[4];
@@ -2137,7 +2137,9 @@
                }
        }
        
-       return i;
+       *pi= i;
+       *pi_noshad= i_noshad;
+
 #if 0
                /* in case 'no diffuse' we still do most calculus, spec can be 
in shadow.*/
                if(!(lar->mode & LA_NO_DIFF)) {


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

Reply via email to