[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16780] branches/soc-2008-unclezeiv/source /blender/render/intern/source/lightcuts.c: Initial commit of " multiple representatives" feature.
Davide Vercelli
davide.vercelli at gmail.com
Sun Sep 28 11:17:43 CEST 2008
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. @@
More information about the Bf-blender-cvs
mailing list