[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15035] branches/soc-2008-unclezeiv/source /blender/render/intern: Fixed "diffuse" and "shadow" render passes, which are now properly supported.

Davide Vercelli davide.vercelli at gmail.com
Thu May 29 01:41:49 CEST 2008


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)) {





More information about the Bf-blender-cvs mailing list