[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16230] branches/soc-2008-unclezeiv/source /blender/render: Added indirect lighting generation for directional lights and environment maps (several issues remaining)

Davide Vercelli davide.vercelli at gmail.com
Fri Aug 22 15:49:27 CEST 2008


Revision: 16230
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16230
Author:   unclezeiv
Date:     2008-08-22 15:49:27 +0200 (Fri, 22 Aug 2008)

Log Message:
-----------
Added indirect lighting generation for directional lights and environment maps (several issues remaining)

Also:
- added API to retrieve bounding box of RE_ray_tree
- fixed subtle bug: bounce colour was erroneously computed as black for surfaces facing away from camera; fixed by temporarily setting R_NOPUNOFLIP before issuing shading call

Modified Paths:
--------------
    branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h
    branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
    branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c

Modified: branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h	2008-08-22 12:48:12 UTC (rev 16229)
+++ branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h	2008-08-22 13:49:27 UTC (rev 16230)
@@ -110,5 +110,8 @@
    end distance */
 float RE_ray_tree_max_size(RayTree *tree);
 
+/* get the tree's axis aligned bounding box */
+void RE_ray_tree_aabb(RayTree *tree, float *min, float *max);
+
 #endif /*__RE_RAYTRACE_H__*/
 

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-22 12:48:12 UTC (rev 16229)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c	2008-08-22 13:49:27 UTC (rev 16230)
@@ -175,6 +175,7 @@
 	int stat_discard_black;
 	int stat_discard_nan;
 	float scene_diag;
+	float scene_min[3], scene_max[3];
 	float indir_fac;
 	int do_indir;
 	int options;
@@ -210,6 +211,8 @@
 #define IS_LEAF(node) (!(node)->child1 && !(node)->child2)
 #define LC_LUMINOSITY_LIMIT (0.0001f)
 
+static void add_virtual_point_light(Render * re, LightcutsData *lcd, LampRen *orig, float *col, int lev);
+
 /* XXX: this function looks really slow! */
 static float get_bounding_cone(LightcutsCluster * one, LightcutsCluster * two, float *vec)
 {
@@ -853,7 +856,7 @@
 {
 	GroupObject *gonew;
 	LampRen *lar;
-	int k, kk;
+	int k, kk, i;
 	float t, p, phi, phirad, st;
 	float maxc;
 	
@@ -934,7 +937,18 @@
 			/* so that bright lights don't get excluded when n is large */
 			lar->energy *= maxc;
 		}
+		
+		/* indirect lighting */
+		for (i= 0; i < lcd->do_indir; i++) {
+			int lev= (lcd->options & LC_OPT_2ND_BOUNCE) ? 1 : 0;
+			add_virtual_point_light(re, lcd, lar, col, lev);
+		}
 
+		if (lcd->do_indir > 0 && (lcd->options & LC_OPT_ONLY_INDIR)) {
+			lamp_delete(lar);
+			continue;
+		}
+
 		BLI_addtail(&re->lampren, lar);
 		/* check deallocation */
 		gonew->lampren= lar;
@@ -1068,6 +1082,7 @@
 	GroupObject go;
 	float savecol[3], energy, max_col;
 	int max_idx;
+	int old_vlr_flag;
 	
 	/* hack: increase current color/energy in order to avoid too dark results */
 	energy= lar->energy;
@@ -1079,6 +1094,10 @@
 	lar->b /= lar->energy;
 	lar->energy= 1.0f;
 	
+	/* don't do normal flipping in this phase */
+	old_vlr_flag= vla->flag;
+	vla->flag |= R_NOPUNOFLIP;
+	
 	/* fake group object in order to use "light override" */
 	go.lampren= lar;
 	go.next= go.prev= 0x0;
@@ -1170,8 +1189,11 @@
 	lar->g= savecol[1];
 	lar->b= savecol[2];
 	
+	/* restore VlakRen flags */
+	vla->flag= old_vlr_flag;
+	
 	max_col= MAX3(shr.col[0], shr.col[1], shr.col[2]);
-	
+
 	if (max_col==0.0f) {
 		lcd->stat_discard_black+= 10000;
 		return 0.0f;
@@ -1195,19 +1217,39 @@
 	isec.mode= RE_RAY_MIRROR;
 	isec.faceorig= NULL;
 	isec.oborig= 0;
-	VECCOPY(isec.start, orig->co);
-	if (!(lcd->options & LC_OPT_FIXED_DIRS))
-		get_cosine_weighted_random_direction(isec.vec);
-	else {
-		isec.vec[0]= 0.0f;
-		isec.vec[1]= 0.0f;
-		isec.vec[2]= 1.0f;
+	switch (orig->type) {
+	case LA_SPOT:
+		VECCOPY(isec.start, orig->co);
+		if (!(lcd->options & LC_OPT_FIXED_DIRS))
+			get_cosine_weighted_random_direction(isec.vec);
+		else {
+			isec.vec[0]= 0.0f;
+			isec.vec[1]= 0.0f;
+			isec.vec[2]= 1.0f;
+		}
+		Mat3MulVecfl(orig->mat, isec.vec);
+		VECNEG(isec.vec);
+		VECADDFAC(isec.end, isec.start, isec.vec, lcd->scene_diag);
+		break;
+	case LA_SUN:
+		{
+			/* generate random point in bounding box */
+			float r[3];
+			r[0]= BLI_frand() * (lcd->scene_max[0]-lcd->scene_min[0]) + lcd->scene_min[0];
+			r[1]= BLI_frand() * (lcd->scene_max[1]-lcd->scene_min[1]) + lcd->scene_min[1];
+			r[2]= BLI_frand() * (lcd->scene_max[2]-lcd->scene_min[2]) + lcd->scene_min[2];
+			
+			/* trace ray in given direction passing from that point */
+			VECCOPY(isec.vec, orig->vec);
+			VECADDFAC(isec.start, r, isec.vec, -lcd->scene_diag);
+			VECADDFAC(isec.end, isec.start, isec.vec, lcd->scene_diag * 2);
+		}
+		break;
+	case LA_LOCAL:
+		/* TODO: indirect lighting for omnidirectional lamps */
+		return;
 	}
-	Mat3MulVecfl(orig->mat, isec.vec);
-	VECNEG(isec.vec);
 	
-	VECADDFAC(isec.end, isec.start, isec.vec, lcd->scene_diag);
-	
 	if (!RE_ray_tree_intersect(re->raytree, &isec)) {
 		lcd->stat_discard_nohit++;
 		return;
@@ -1220,7 +1262,7 @@
 	VECADDFAC(co, isec.start, isec.vec, isec.labda - 0.01);
 	
 	fac= get_bounce_color(lcd, isec.ob, vla, co, orig, scol, isec.isect);
-	
+
 	if (fac == 0.0f) {
 		lcd->stat_discard_black++;
 		return;
@@ -1232,11 +1274,6 @@
 		return;
 	}
 #endif
-
-#ifdef LIGHTCUTS_DEBUG_INDIR
-	printf("PYDBG %d: %f %f %f - %f %f %f\n",
-			lev, co[0], co[1], co[2], scol[0], scol[1], scol[2]);
-#endif
 	
 	lar= (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
 	lamp_init(re, lar);
@@ -1266,6 +1303,11 @@
 	lar->g= lar->energy * scol[1];
 	lar->b= lar->energy * scol[2];
 	
+#ifdef LIGHTCUTS_DEBUG_INDIR
+	printf("PYDBG %d: %f %f %f - %f %f %f - %f %f %f\n",
+			lev, co[0], co[1], co[2], scol[0], scol[1], scol[2], isec.vec[0], isec.vec[1], isec.vec[2]);
+#endif
+	
 	/* XXX: see remarks on similar code in convert_environment_map */
 	go= MEM_callocN(sizeof(GroupObject), "groupobject");
 	BLI_addtail(&lcd->pointlights, go);
@@ -1411,6 +1453,7 @@
 	lcd->options= re->r.lightcuts_options;
 	lcd->error_rate= re->r.lightcuts_max_error;
 	lcd->scene_diag= RE_ray_tree_max_size(re->raytree);
+	RE_ray_tree_aabb(re->raytree, lcd->scene_min, lcd->scene_max);
 	
 	if (lcd->options & LC_OPT_2ND_BOUNCE)
 		lcd->indir_fac /= 2.0f;
@@ -1462,6 +1505,22 @@
 			convert_area_light(re, lcd, lar);
 			continue;
 		}
+		
+		if (!ELEM3(lar->type, LA_LOCAL, LA_SUN, LA_SPOT))
+			continue;
+		
+		/* indirect lighting */
+		if (lcd->do_indir > 0) {
+			int i;
+			for (i= 0; i < lcd->do_indir; i++) {
+				int lev= (lcd->options & LC_OPT_2ND_BOUNCE) ? 1 : 0;
+				float col[3] = {lar->r, lar->g, lar->b};
+				add_virtual_point_light(re, lcd, lar, col, lev);
+			}
+		
+			if (lcd->options & LC_OPT_ONLY_INDIR)
+				continue;
+		}
 
 		/* first copy the initial light */
 		gonew= MEM_callocN(sizeof(GroupObject), "groupobject");

Modified: branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c	2008-08-22 12:48:12 UTC (rev 16229)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c	2008-08-22 13:49:27 UTC (rev 16230)
@@ -1440,3 +1440,8 @@
 	return ((Octree*)tree)->ocsize;
 }
 
+void RE_ray_tree_aabb(RayTree *tree, float *min, float *max)
+{
+	VECCOPY(min, ((Octree*)tree)->min);
+	VECCOPY(max, ((Octree*)tree)->max);
+}





More information about the Bf-blender-cvs mailing list