[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16254] branches/soc-2008-unclezeiv/source /blender: Indirect lighting: added clamping mechanism for virtual point lights, to reduce artifacts such as random bright spots.

Davide Vercelli davide.vercelli at gmail.com
Mon Aug 25 23:41:50 CEST 2008


Revision: 16254
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16254
Author:   unclezeiv
Date:     2008-08-25 23:41:50 +0200 (Mon, 25 Aug 2008)

Log Message:
-----------
Indirect lighting: added clamping mechanism for virtual point lights, to reduce artifacts such as random bright spots.

As the code is still relatively untested (and I'm not 100% even sure to have correctly understood the paper on this), I'm also adding a temporary toggle to disable it, in order to easily perform tests and comparisons.

Modified Paths:
--------------
    branches/soc-2008-unclezeiv/source/blender/render/intern/include/render_types.h
    branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
    branches/soc-2008-unclezeiv/source/blender/src/buttons_scene.c

Modified: branches/soc-2008-unclezeiv/source/blender/render/intern/include/render_types.h
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/include/render_types.h	2008-08-25 19:50:17 UTC (rev 16253)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/include/render_types.h	2008-08-25 21:41:50 UTC (rev 16254)
@@ -484,6 +484,8 @@
 	float YF_glowint, YF_glowofs;
 	short YF_glowtype;
 	
+	short lightcuts_options;
+	
 	/* ray optim */
 	VlakRen *vlr_last[BLENDER_MAX_THREADS];
 	ObjectInstanceRen *obi_last[BLENDER_MAX_THREADS];

Modified: branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c	2008-08-25 19:50:17 UTC (rev 16253)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c	2008-08-25 21:41:50 UTC (rev 16254)
@@ -97,7 +97,10 @@
 #define LC_OPT_2ND_BOUNCE  0x04
 #define LC_OPT_ENV_LIGHT   0x08
 #define LC_OPT_INDIR_MESH  0x10
+#define LC_OPT_NO_CLAMP    0x20
 
+#define LC_LAR_INDIR 0x01
+
 /*
  * This is a table to select the "worst falloff" for a cluster, given the
  * falloff types of its children.
@@ -207,7 +210,8 @@
 	int dbg_first_pixel;
 	int dbg_options;
 #endif
-	float* dbg_vis_vpl;
+	float *dbg_vis_vpl;
+	int *vpl_to_cap;
 } LightcutsData;
 
 typedef struct SampleCoordInfo {
@@ -1400,6 +1404,8 @@
 	lar->distkw= lar->dist * lar->dist;
 	lar->lay= orig->lay;
 	
+	lar->lightcuts_options= LC_LAR_INDIR;
+	
 	/* lamp is oriented as (negated) face normal */
 	VECCOPY(lar->vec, vla->n);
 	VECNEG(lar->vec);
@@ -1736,8 +1742,12 @@
 	/* XXX: restore mode (terrible hack needed by get_bounce_color) */
 	R.r.mode|= R_LIGHTCUTS;
 	
-	if (lcd->options & LC_OPT_INDIR_MESH && lcd->vpl_counter > 0)
-		dbg_create_vpl_mesh(re, lcd);
+	if (lcd->vpl_counter) {
+		lcd->vpl_to_cap= MEM_callocN(sizeof(int) * lcd->max_cut * re->r.threads, "vpl_to_cap");
+		
+		if (lcd->options & LC_OPT_INDIR_MESH && lcd->vpl_counter > 0)
+			dbg_create_vpl_mesh(re, lcd);
+	}
 }
 
 /* Adapted from "Transforming Axis-Aligned Bounding Boxes" by Jim Arvo, "Graphics Gems", Academic Press, 1990 */
@@ -2046,6 +2056,8 @@
 	float noropp[3];
 	float mirdir[3];
 	LightcutsCluster *array;
+	int vpl_to_cap= 0;
+	int *vpl_queue= 0;
 
 	/* 
 	 * this heap maintains the current cut
@@ -2110,6 +2122,7 @@
 	}
 
 	cut_nodes= lcd->cut_nodes + shi->thread * lcd->cut_nodes_size;
+	vpl_queue= lcd->vpl_to_cap + shi->thread * lcd->max_cut;
 
 	/* initial nodes in the queue */
 	{
@@ -2258,6 +2271,12 @@
 					BLI_heap_insert(cut, -cn_rep->error_bound * rep->luminance, cn_rep);
 				else {
 					used++;
+					
+					if (rep->lar->lightcuts_options & LC_LAR_INDIR) {
+						vpl_queue[vpl_to_cap]= cn_rep - cut_nodes;
+						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",
@@ -2292,6 +2311,12 @@
 					BLI_heap_insert(cut, -cn_unrep->error_bound * unrep->luminance, cn_unrep);
 				else {
 					used++;
+					
+					if (unrep->lar->lightcuts_options & LC_LAR_INDIR) {
+						vpl_queue[vpl_to_cap]= cn_unrep - cut_nodes;
+						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",
@@ -2318,6 +2343,30 @@
 		}
 	}
 
+	/* here we cap the vpl contribution to half the error rate */
+	if (!(lcd->options & LC_OPT_NO_CLAMP) && vpl_to_cap > 0)
+	{
+		float bound_shad= INPR(lcd->colw, totest_shad) * lcd->error_rate * 0.5f;
+		float bound_spec= INPR(lcd->colw, totest_spec) * lcd->error_rate * 0.5f;
+		LightcutsCluster *array= lcd->trees[TREE_SPOT].array;
+		int i;
+		for (i= 0; i < vpl_to_cap; i++) {
+			int idx= vpl_queue[i];
+			CutNode *cn= &cut_nodes[idx];
+			LightcutsCluster *lc= &array[cn->id];
+			
+			if (cn->f_clus * lc->luminance > bound_shad) {
+				float fac= bound_shad - cn->f_clus;
+				VECADDFAC(totest_shad, totest_shad, lc->col, fac);
+			}
+			 
+			if (cn->f_clus_spec * lc->luminance > bound_spec) {
+				float fac= bound_spec - cn->f_clus_spec;
+				VECADDFAC(totest_spec, totest_spec, lc->col, fac);
+			}
+		}
+	}
+
 	/*
 	 * here, the content of the queue IS the cut, but we already should have
 	 * an updated TOTEST value (even thought numerically questionable?)
@@ -2399,6 +2448,8 @@
 		MEM_freeN(lcd->cut_nodes);
 		if (lcd->dbg_vis_vpl)
 			MEM_freeN(lcd->dbg_vis_vpl);
+		if (lcd->vpl_to_cap)
+			MEM_freeN(lcd->vpl_to_cap);
 		MEM_freeN(lcd);
 	}
 	*p= NULL;

Modified: branches/soc-2008-unclezeiv/source/blender/src/buttons_scene.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/src/buttons_scene.c	2008-08-25 19:50:17 UTC (rev 16253)
+++ branches/soc-2008-unclezeiv/source/blender/src/buttons_scene.c	2008-08-25 21:41:50 UTC (rev 16254)
@@ -3450,7 +3450,8 @@
 	uiBlockBeginAlign(block);
 	uiDefButBitI(block, TOG, SCE_PASS_LCFAUX, B_SET_PASS, "False color", 200, 0, 48, 20, &srl->passflag, 0, 0, 0, 0, "(Debug option) Deliver false color pass");
 	uiDefButI(block, NUM, B_DIFF, "Debug:", 200, -22, 48, 20, &G.scene->r.lightcuts_debug_options, 0, 0xffffffff, 0, 0, "(Debug option) Slider to select debug prints");
-	uiDefButBitS(block, TOG, 0x10, B_SET_PASS, "VPL Mesh", 200, -44, 48, 20, &G.scene->r.lightcuts_options, 0, 0, 0, 0, "(Debug option) Creates a mesh to visualize indirect light placement");
+	uiDefButBitS(block, TOG, 0x10, B_DIFF, "VPL Mesh", 200, -44, 48, 20, &G.scene->r.lightcuts_options, 0, 0, 0, 0, "(Debug option) Creates a mesh to visualize indirect light placement");
+	uiDefButBitS(block, TOG, 0x20, B_DIFF, "No clamp", 200, -66, 48, 20, &G.scene->r.lightcuts_options, 0, 0, 0, 0, "(Debug option) Disable clamping mechanism for virtual point lights");
 	uiBlockEndAlign(block);
 	
 	uiBlockBeginAlign(block);





More information about the Bf-blender-cvs mailing list