[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