Revision: 16780
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16780
Author:   unclezeiv
Date:     2008-09-28 11:17:38 +0200 (Sun, 28 Sep 2008)

Log Message:
-----------
Initial commit of "multiple representatives" feature. Long story short: this is 
a new option that should convert banding into noise.

Issues:
- slows down rendering significantly but there's still plenty of room for 
optimizations
- the refactoring required by this feature could have broken other stuff: 
testers, please re-run previous tests

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-09-28 08:00:22 UTC (rev 16779)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-09-28 09:17:38 UTC (rev 16780)
@@ -389,6 +389,80 @@
        
        dest->sphere= one->sphere && two->sphere;
        dest->sphere_dist= MAX2(one->sphere_dist, two->sphere_dist);
+       
+       if (lcd->options & LC_OPT_MULT_REPR) {
+               short found, used[LC_MAX_MULT_REPR * 2];
+               float x, lum;
+               float tot_lum= 0.0f;
+               int i, j;
+               
+               memset(used, 0, sizeof(used));
+               
+               /* calc tot_lum: TODO: slow but will change! */
+               for (j= 0; j< one->mrep_len; j++)
+                       tot_lum+= one->mrep_list[j].intensity;
+               for (j= 0; j< two->mrep_len; j++)
+                       tot_lum+= two->mrep_list[j].intensity;
+               
+               dest->mrep_len= MAX2(one->mrep_len, two->mrep_len);
+               
+               if (dest->mrep_len < LC_MAX_MULT_REPR) {
+                       if (one->mrep_len == two->mrep_len)
+                               dest->mrep_len++;
+                       else
+                       {
+                               float minlen= (float)MIN2(one->mrep_len, 
two->mrep_len);
+                               if (BLI_frand() < minlen / dest->mrep_len)
+                                       dest->mrep_len++;
+                       }
+               }
+               
+               dest->mrep_list= MEM_callocN(sizeof(ClusRep) * dest->mrep_len, 
"lc mreplist");
+               
+               for (i= 0; i< dest->mrep_len; i++) {
+                       x= BLI_frand() * tot_lum;
+                       found= 0;
+                       
+                       for (j= 0; j< one->mrep_len; j++) {
+                               if (used[j])
+                                       continue;
+                               lum= one->mrep_list[j].intensity;
+                               if (x <= lum) {
+                                       dest->mrep_list[i].lar= 
one->mrep_list[j].lar;
+                                       dest->mrep_list[i].intensity= lum;
+                                       found= 1;
+                                       tot_lum-= lum;
+                                       used[j]= 1;
+                                       break;
+                               }
+                               x -= lum;
+                       }
+                       
+                       if (found)
+                               continue;
+                       
+                       for (j= 0; j< two->mrep_len; j++) {
+                               if (used[one->mrep_len + j])
+                                       continue;
+                               lum= two->mrep_list[j].intensity;
+                               if (x <= lum) {
+                                       dest->mrep_list[i].lar= 
two->mrep_list[j].lar;
+                                       dest->mrep_list[i].intensity= lum;
+                                       found= 1;
+                                       tot_lum-= lum;
+                                       used[one->mrep_len + j]= 1;
+                                       break;
+                               }
+                               x -= lum;
+                       }
+                       
+                       if (!found)
+                               printf("TERRIBLE bug!\n");
+               }
+               
+               /* sort list and allocate list */
+               qsort(dest->mrep_list, dest->mrep_len, sizeof(ClusRep), 
cmp_clusrep);
+       }
 
        (*root)++;
        
@@ -565,6 +639,13 @@
                        clus->sphere = 1;
                        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= INPR(colw, clus->col);
+               }
 
                clus++;
                tree->free++;
@@ -2104,21 +2185,43 @@
        dbg_convert[tree->node]= 0;
 #endif
        if (node->error_bound > FLT_EPSILON) {
-               single_light_contrib(clus->lar, si->shi, &i, &i_noshad, &t);
+               LampRen *lar= clus->lar;
+               float intensity= clus->intensity;
+               if (lcd->options & LC_OPT_MULT_REPR && clus->mrep_len > 1) {
+                       int i;
+                       float rand, tot_lum= 0.0f; 
+                       /* XXX */
+                       for (i= 0; i< clus->mrep_len; i++)
+                               tot_lum+= clus->mrep_list[i].intensity;
+                       
+                       rand= BLI_frand() * tot_lum;
+                       
+                       for (i= 0; i< clus->mrep_len; i++) {
+                               float lum= clus->mrep_list[i].intensity;
+                               if (rand < lum) {
+                                       lar= clus->mrep_list[i].lar;
+                                       intensity= clus->luminance / lum;
+                                       break;
+                               }
+                               rand -= lum;
+                       }
+               }
+               single_light_contrib(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 * clus->intensity;
-               node->f_clus_spec= node->contr_factor_spec * clus->intensity;
+               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);
 
                /* 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 * 
clus->intensity;
+                       node->f_clus_noshad= node->contr_factor_noshad * 
intensity;
                        VECADDFAC(si->totest_noshad, si->totest_noshad, 
clus->col, node->f_clus_noshad);
                }
+               
 #ifdef LIGHTCUTS_DEBUG
                dbg_totlum+= node->contr_factor * clus->luminance;
 #endif
@@ -2129,7 +2232,7 @@
                        si->used++;
                        
                        /* XXX unneeded for root ? */
-                       if (clus->lar->lightcuts_options & LC_LAR_INDIRECT) {
+                       if (lar->lightcuts_options & LC_LAR_INDIRECT) {
                                si->vpl_queue[si->vpl_to_cap]= node - 
si->cut_nodes;
                                si->vpl_to_cap++;
                        }
@@ -2152,7 +2255,6 @@
        SampleInfo si;
        
        int it= 0;
-       float i, i_noshad, t;
        float noropp[3];
        float mirdir[3];
        
@@ -2305,108 +2407,66 @@
                         */
                        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);
+                       
+                       if(si.shi->passflag & 
(SCE_PASS_DIFFUSE|SCE_PASS_SHADOW))
+                               VECADDFAC(si.totest_noshad, si.totest_noshad, 
rep->col, -cn_hinode->f_clus_noshad);
+                                                       
 #ifdef LIGHTCUTS_DEBUG
                        dbg_totlum-= cn_hinode->contr_factor * 
hinode->luminance;
 #endif
                        
-                       /* for the represented light we can reuse most 
calculations */
-                       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);
+                       /* 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 */
+                               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);
 
-                       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);
+                               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);
 #ifdef LIGHTCUTS_DEBUG
-                               dbg_totlum+= rep->luminance * 
cn_rep->contr_factor;
+                                       dbg_totlum+= rep->luminance * 
cn_rep->contr_factor;
 #endif
 
-                               if (!IS_LEAF(rep))
-                                       BLI_heap_insert(si.cut, 
-cn_rep->error_bound * rep->luminance, cn_rep);
-                               else {
-                                       si.used++;
-                                       
-                                       if (rep->lar->lightcuts_options & 
LC_LAR_INDIRECT) {
-                                               si.vpl_queue[si.vpl_to_cap]= 
cn_rep - si.cut_nodes;
-                                               si.vpl_to_cap++;
-                                       }
-                                       
-#ifdef LIGHTCUTS_DEBUG
-                                       if (lcd->dbg_options & 
LC_DBG_TRAV_A_NODE_PRINT && lcd->dbg_first_pixel==0)
-                                               printf("A t:%d id:%4d eb:%7.5f 
fc:%7.5f\n",
-                                                               
CLUSTER_TYPE_TO_ARRAY_IDX(cn_rep->type), cn_rep->id,
-                                                               
cn_rep->error_bound, cn_rep->f_clus);
-#endif
-                               }
-                       }
-                       else
-                               si.used++;
-                       si.used_type[CLUSTER_TYPE_TO_ARRAY_IDX(cn_rep->type)]++;
+                                       if (!IS_LEAF(rep))
+                                               BLI_heap_insert(si.cut, 
-cn_rep->error_bound * rep->luminance, cn_rep);
+                                       else {
+                                               si.used++;
 
-                       /* for the "unrepresented" light we have to compute 
stuff from scratch */
-                       {
-                               LightcutsCluster *clus= unrep;
-                               CutNode *node = cn_unrep;
-                               SampleInfo *ssi = &si;
-                               //fill_cut_node(lcd, node, clus, &si);
+                                               if (rep->lar->lightcuts_options 
& LC_LAR_INDIRECT) {
+                                                       
si.vpl_queue[si.vpl_to_cap]= cn_rep - si.cut_nodes;
+                                                       si.vpl_to_cap++;
+                                               }
 
-#if 1
-                               node->id= clus->id;
-                               node->type= clus->type;
-                               node->error_bound= calc_geometric_eb(lcd, clus, 
ssi->shi->co) * calc_material_eb(clus, ssi->shi, &ssi->sci);
-       
-                               if (node->error_bound > FLT_EPSILON) {
-                                       single_light_contrib(clus->lar, 
ssi->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 * 
clus->intensity;
-                                       node->f_clus_spec= 
node->contr_factor_spec * clus->intensity;
-                                       VECADDFAC(ssi->totest_shad, 
ssi->totest_shad, clus->col, node->f_clus);
-                                       VECADDFAC(ssi->totest_spec, 
ssi->totest_spec, clus->col, node->f_clus_spec);
-       #ifdef LIGHTCUTS_DEBUG
-                                       dbg_totlum+= clus->luminance * 
node->contr_factor;
-       #endif
-       
-                                       if (!IS_LEAF(clus))
-                                               BLI_heap_insert(ssi->cut, 
-node->error_bound * clus->luminance, node);
-                                       else {
-                                               ssi->used++;
-                                               
-                                               if 
(clus->lar->lightcuts_options & LC_LAR_INDIRECT) {
-                                                       
ssi->vpl_queue[ssi->vpl_to_cap]= node - ssi->cut_nodes;
-                                                       ssi->vpl_to_cap++;
-                                               }
-                                               
-       #ifdef LIGHTCUTS_DEBUG
+#ifdef LIGHTCUTS_DEBUG
                                                if (lcd->dbg_options & 
LC_DBG_TRAV_A_NODE_PRINT && lcd->dbg_first_pixel==0)
                                                        printf("A t:%d id:%4d 
eb:%7.5f fc:%7.5f\n",
-                                                                       
CLUSTER_TYPE_TO_ARRAY_IDX(node->type), node->id,
-                                                                       
node->error_bound, node->f_clus);
-       #endif
+                                                                       
CLUSTER_TYPE_TO_ARRAY_IDX(cn_rep->type), cn_rep->id,
+                                                                       
cn_rep->error_bound, cn_rep->f_clus);
+#endif
                                        }
                                }
                                else
-                                       ssi->used++;
-                               
ssi->used_type[CLUSTER_TYPE_TO_ARRAY_IDX(node->type)]++;
-#endif
+                                       si.used++;
+                               
si.used_type[CLUSTER_TYPE_TO_ARRAY_IDX(cn_rep->type)]++;
+                               
+                               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;
+                                       VECADDFAC(si.totest_noshad, 
si.totest_noshad, rep->col, cn_rep->f_clus_noshad);
+                               }
                        }
 
-                       if(si.shi->passflag & 
(SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
-                               VECADDFAC(si.totest_noshad, si.totest_noshad, 
rep->col, -cn_hinode->f_clus_noshad);
-
-                               cn_rep->contr_factor_noshad= 
cn_hinode->contr_factor_noshad;
-                               cn_rep->f_clus_noshad= 
cn_hinode->contr_factor_noshad * rep->intensity;
-                               VECADDFAC(si.totest_noshad, si.totest_noshad, 
rep->col, cn_rep->f_clus_noshad);
-

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