[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16985] branches/soc-2008-unclezeiv/source /blender/render/intern/source/lightcuts.c: Refactored some redundant code for "multiple representatives"; also fixed a bug that would make "noisy" images brighter than the original ones.
Davide Vercelli
davide.vercelli at gmail.com
Thu Oct 9 00:50:44 CEST 2008
Revision: 16985
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16985
Author: unclezeiv
Date: 2008-10-09 00:50:43 +0200 (Thu, 09 Oct 2008)
Log Message:
-----------
Refactored some redundant code for "multiple representatives"; also fixed a bug that would make "noisy" images brighter than the original ones.
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-10-08 20:54:19 UTC (rev 16984)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 2008-10-08 22:50:43 UTC (rev 16985)
@@ -131,6 +131,7 @@
{
LampRen *lar;
float intensity;
+
} ClusRep;
/* node of the lightcuts tree */
@@ -141,15 +142,12 @@
int id; /* must be able to accommodate millions of lights */
int child1;
int child2;
- float intensity;
float min[3];
float max[3];
- float col[3];
/* cone_* variables only for oriented lights */
float cone_dir[3]; /* store normalized */
float cone_angle;
float luminance;
- LampRen * lar;
short falloff_type, sphere;
float falloff_dist;
float sphere_dist;
@@ -368,25 +366,7 @@
/* if LA_SPOT, compute new bounding cone */
if (one->type == CLUSTER_SPOT)
dest->cone_angle= get_bounding_cone(one, two, dest->cone_dir);
-
- if (lcd->options & LC_OPT_NO_RAND_CLS)
- use_one_as_repr= one->luminance > two->luminance;
- else
- use_one_as_repr= BLI_frand() * (one->luminance + two->luminance) < one->luminance;
- /* the representative light is chosen randomly among children */
- if (use_one_as_repr) {
- dest->lar= one->lar;
- VECCOPY(dest->col, one->col);
- rep= 0;
- }
- else {
- dest->lar= two->lar;
- VECCOPY(dest->col, two->col);
- rep= 1;
- }
- dest->intensity= dest->luminance / INPR(lcd->colw, dest->col);
-
/* worst case falloff type/dist for conservative error estimation */
dest->falloff_type= falloff_merge[one->falloff_type][two->falloff_type];
dest->falloff_dist= MAX2(one->falloff_dist, two->falloff_dist);
@@ -425,7 +405,7 @@
for (j= 0; j< one->mrep_len; j++) {
if (used[j])
continue;
- lum= one->mrep_list[j].intensity;
+ lum= one->mrep_list[j].intensity * dest->luminance / one->luminance;
if (x <= lum) {
dest->mrep_list[i].lar= one->mrep_list[j].lar;
dest->mrep_list[i].intensity= lum;
@@ -444,7 +424,7 @@
for (j= 0; j< two->mrep_len; j++) {
if (used[one->mrep_len + j])
continue;
- lum= two->mrep_list[j].intensity;
+ lum= two->mrep_list[j].intensity * dest->luminance / two->luminance;
if (x <= lum) {
dest->mrep_list[i].lar= two->mrep_list[j].lar;
dest->mrep_list[i].intensity= lum;
@@ -464,6 +444,27 @@
/* sort list and allocate list */
qsort(dest->mrep_list, dest->mrep_len, sizeof(ClusRep), cmp_clusrep);
}
+ else {
+ if (lcd->options & LC_OPT_NO_RAND_CLS)
+ use_one_as_repr= one->luminance > two->luminance;
+ else
+ use_one_as_repr= BLI_frand() * (one->luminance + two->luminance) < one->luminance;
+
+ dest->mrep_list= MEM_callocN(sizeof(ClusRep), "lc mrep single");
+ dest->mrep_len= 1;
+
+ /* the representative light is chosen randomly among children */
+ if (use_one_as_repr) {
+ dest->mrep_list[0].lar= one->mrep_list[0].lar;
+ dest->mrep_intensity= dest->mrep_list[0].intensity= dest->luminance / one->mrep_list[0].lar->energy;
+ rep= 0;
+ }
+ else {
+ dest->mrep_list[0].lar= two->mrep_list[0].lar;
+ dest->mrep_intensity= dest->mrep_list[0].intensity= dest->luminance / two->mrep_list[0].lar->energy;
+ rep= 1;
+ }
+ }
(*root)++;
@@ -538,7 +539,7 @@
#ifdef LIGHTCUTS_DEBUG
printf("id %d, type %d, energy %10.7f, intensity %10.7f, luminance %10.7f ", one->id, one->type, one->lar->energy, one->intensity, one->luminance);
#endif
- other= BLI_kdtree_find_callback(tree, one->lar->co, NULL, one->id, cb_update_metric_max_dist, data, nearest);
+ other= BLI_kdtree_find_callback(tree, one->mrep_list[0].lar->co, NULL, one->id, cb_update_metric_max_dist, data, nearest);
if (other != -1)
{
@@ -574,7 +575,6 @@
clus->type = LA_TYPE_TO_CLUSTER_TYPE(cur_type);
clus->in_tree = 0;
clus->id = tree->free;
- clus->intensity = lar->energy;
switch (lar->type) {
case LA_LOCAL:
@@ -598,14 +598,10 @@
clus->cone_angle= 0.0f;
break;
}
- 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->luminance= INPR(colw, clus->col) * lar->energy;
+ clus->luminance= lar->r * colw[0] + lar->g * colw[1] + lar->b * colw[2];
switch (lar->falloff_type) {
case LA_FALLOFF_CONSTANT:
@@ -651,12 +647,10 @@
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= clus->mrep_intensity= INPR(colw, clus->col);
- }
+ clus->mrep_len= 1;
+ clus->mrep_list= MEM_callocN(sizeof(ClusRep), "clusrep");
+ clus->mrep_list[0].lar= lar;
+ clus->mrep_list[0].intensity= clus->mrep_intensity= clus->luminance / lar->energy;
clus++;
tree->free++;
@@ -792,7 +786,7 @@
/* kdtree construction */
for (i= 0; i < tree->counter; i++)
- BLI_kdtree_insert(kdtree, i, array[i].lar->co, NULL);
+ BLI_kdtree_insert(kdtree, i, array[i].mrep_list[0].lar->co, NULL);
#ifdef LIGHTCUTS_DEBUG
if (print_times) {
@@ -2235,8 +2229,10 @@
dbg_convert[tree->node]= 0;
#endif
if (node->error_bound > FLT_EPSILON) {
- float intensity= clus->intensity;
- node->used_lar= clus->lar;
+ float intensity;
+ float col[3];
+ node->used_lar= clus->mrep_list[0].lar;
+ intensity= clus->luminance / clus->mrep_list[0].intensity;
if (lcd->options & LC_OPT_MULT_REPR && clus->mrep_len > 1) {
int i;
float rand= BLI_frand() * clus->mrep_intensity;
@@ -2251,20 +2247,24 @@
rand -= lum;
}
}
+ col[0]= node->used_lar->r / node->used_lar->energy;
+ col[1]= node->used_lar->g / node->used_lar->energy;
+ col[2]= node->used_lar->b / node->used_lar->energy;
+
single_light_contrib(node->used_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 * 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);
+ VECADDFAC(si->totest_shad, si->totest_shad, col, node->f_clus);
+ VECADDFAC(si->totest_spec, si->totest_spec, 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 * intensity;
- VECADDFAC(si->totest_noshad, si->totest_noshad, clus->col, node->f_clus_noshad);
+ VECADDFAC(si->totest_noshad, si->totest_noshad, col, node->f_clus_noshad);
}
#ifdef LIGHTCUTS_DEBUG
@@ -2434,6 +2434,7 @@
LightcutsCluster *unrep= &array[hinode->child2];
CutNode *cn_rep= &si.cut_nodes[si.free_node];
CutNode *cn_unrep= &si.cut_nodes[si.free_node + 1];
+ float hicol[3];
if (lcd->options & LC_OPT_MULT_REPR) {
int i;
@@ -2443,7 +2444,7 @@
if (i == rep->mrep_len)
SWAP(LightcutsCluster*, rep, unrep);
}
- else if (hinode->lar != rep->lar)
+ else if (hinode->mrep_list[0].lar != rep->mrep_list[0].lar)
SWAP(LightcutsCluster*, rep, unrep);
#ifdef LIGHTCUTS_DEBUG
@@ -2458,33 +2459,34 @@
* but please note that it's the same quantity
* we are not calculating it in different ways
*/
- 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);
+ hicol[0]= cn_hinode->used_lar->r / cn_hinode->used_lar->energy;
+ hicol[1]= cn_hinode->used_lar->g / cn_hinode->used_lar->energy;
+ hicol[2]= cn_hinode->used_lar->b / cn_hinode->used_lar->energy;
+ VECADDFAC(si.totest_shad, si.totest_shad, hicol, -cn_hinode->f_clus);
+ VECADDFAC(si.totest_spec, si.totest_spec, hicol, -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);
+ VECADDFAC(si.totest_noshad, si.totest_noshad, hicol, -cn_hinode->f_clus_noshad);
#ifdef LIGHTCUTS_DEBUG
dbg_totlum-= cn_hinode->contr_factor * hinode->luminance;
#endif
- /* 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 */
{
- /* for the represented light we can reuse most calculations */
+ float intensity= rep->luminance / INPR(lcd->colw, hicol);
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);
+ cn_rep->used_lar= cn_hinode->used_lar;
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);
+ cn_rep->f_clus= cn_hinode->contr_factor * intensity;
+ cn_rep->f_clus_spec= cn_hinode->contr_factor_spec * intensity;
+ VECADDFAC(si.totest_shad, si.totest_shad, hicol, cn_rep->f_clus);
+ VECADDFAC(si.totest_spec, si.totest_spec, hicol, cn_rep->f_clus_spec);
#ifdef LIGHTCUTS_DEBUG
dbg_totlum+= rep->luminance * cn_rep->contr_factor;
#endif
@@ -2494,7 +2496,7 @@
else {
si.used++;
- if (rep->lar->lightcuts_options & LC_LAR_INDIRECT) {
+ if (cn_hinode->used_lar->lightcuts_options & LC_LAR_INDIRECT) {
si.vpl_queue[si.vpl_to_cap]= cn_rep - si.cut_nodes;
si.vpl_to_cap++;
}
@@ -2513,8 +2515,8 @@
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;
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list