[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15627] branches/soc-2008-unclezeiv/source /blender/render/intern/source/lightcuts.c: Textured area lights: now using Hammersley sampling instead of own silly jittering.

Davide Vercelli davide.vercelli at gmail.com
Fri Jul 18 21:54:15 CEST 2008


Revision: 15627
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15627
Author:   unclezeiv
Date:     2008-07-18 21:54:15 +0200 (Fri, 18 Jul 2008)

Log Message:
-----------
Textured area lights: now using Hammersley sampling instead of own silly jittering.

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-07-18 19:09:41 UTC (rev 15626)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c	2008-07-18 19:54:15 UTC (rev 15627)
@@ -634,7 +634,7 @@
 		 * The point here is that we create new lights with no corresponding
 		 * objects... do we need objects there?
 		 */
-		gonew->ob= 0; /* XXX: or go->ob */
+		gonew->ob= 0;
 		
 		lar = (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
 		init_lamp(re, lar);
@@ -678,7 +678,7 @@
 /*
  * TODO: this is similar to do_lamp_tex in texture.c, which in turn is similar
  * to do_material_tex; maybe all three functions should share most of the code
- * but there are many subtleties there.
+ * but there are many subtle differences to take into account.
  */
 static void do_lamp_tex_eval(LampRen *la, float *texvec, int osatex, float *colf)
 {
@@ -770,14 +770,12 @@
 static void convert_area_light(Render * re, LightcutsData *lcd, LampRen *orig)
 {
 	GroupObject *gonew;
-	int x, y, smpx, smpy;
-	float area, gapx, gapy, factor, realw, realh;
-	float xdir[3];
-	float ydir[3];
-	float col[3];
-	float stepx, stepy, texvec[2];
 	LampRen *lar;
-	float density;
+	float factor, realw, realh, density;
+	float xdir[3], ydir[3], col[3];
+	float stepx, stepy, texvec[2];
+	float p, u, v;
+	int k, kk, pos, n;
 	int use_texture= 0;
 	int tex_nr;
 	
@@ -788,16 +786,12 @@
 
 	realw= sqrtf(VEC_LEN_SQ(orig->mat[0])) * orig->area_size;
 	realh= sqrtf(VEC_LEN_SQ(orig->mat[1])) * orig->area_sizey;
+	
+	n= MAX2((int)(density * realw), 1) * MAX2((int)(density * realh), 1); 
+	factor= 0.5f * sqrtf(orig->dist) * realw * realh / n;
 
-	area= realw * realh;
-	smpx= MAX2((int)(density * realw), 1);
-	smpy= MAX2((int)(density * realh), 1);
-	gapx= 1.0 / (float)(smpx);
-	gapy= 1.0 / (float)(smpy);
-	factor= 0.5f * sqrtf(orig->dist) * area / (smpx * smpy);
-
 	/* XXX: TODO: temporary check just to avoid freezing on undue densities */
-	if (lcd->light_counter + smpx * smpy > re->r.lightcuts_max_lights) {
+	if (lcd->light_counter + n > re->r.lightcuts_max_lights) {
 		printf("Err: required light density would violate light limit\n");
 		return;
 	}
@@ -811,72 +805,75 @@
 		}
 	}
 
-	for (x=0; x<smpx; x++) {
-		for (y=0; y<smpy; y++) {
-			gonew= MEM_callocN(sizeof(GroupObject), "groupobject");
-			BLI_addtail(&lcd->pointlights, gonew);
-			/* gonew->recalc= go->recalc; // XXX: what is this? */
-			/*
-			 * XXX: probably wrong, more a test to see if it is used somewhere
-			 * or deallocated
-			 * The point here is that we create new lights with no corresponding
-			 * objects... do we need objects there?
-			 */
-			gonew->ob= 0; /* XXX: or go->ob */
+	for (k= 0, pos= 0; k < n; k++) {
+		/*
+		 * hammersley algorithm, from
+		 * Wong, Luk, Heng "Sampling with Hammersley and Halton Points"
+		 * Journal of Graphics Tools , vol. 2, no. 2, 1997, pp 9-24.
+		 */
+		u= 0;
+		for (p= 0.5f, kk= k; kk; p*= 0.5f, kk>>= 1)
+			if (kk & 1) /* equivalent to: kk % 2 == 1 */
+				u+= p;
+		
+		v= (k + 0.5f) / n;
+		
+		texvec[0]= u;
+		texvec[1]= v;
+		stepx= orig->area_size * (texvec[0] - 0.5f);
+		stepy= orig->area_sizey * (texvec[1] - 0.5f);
+		
+		if (use_texture) {
+			/* TODO: NOTE: not using osatex */
+			texvec[0]= 1.0f - texvec[0]*2.0f;
+			texvec[1]= texvec[1]*2.0f - 1.0f;
 			
-			/* place a light in its own square with random jittering */
-			texvec[0]= gapx * (x + BLI_frand());
-			texvec[1]= gapy * (y + BLI_frand());
-			stepx= orig->area_size * (texvec[0] - 0.5f);
-			stepy= orig->area_sizey * (texvec[1] - 0.5f);
-			
-			if (use_texture) {
-				/* TODO: NOTE: not using osatex */
-				texvec[0]= 1.0f - texvec[0]*2.0f;
-				texvec[1]= texvec[1]*2.0f - 1.0f;
-				
-				col[0]= col[1]= col[2]= 0.0f;
-				do_lamp_tex_eval(orig, texvec, 0, col);
-			}
-			else {
-				col[0]= orig->r;
-				col[1]= orig->g;
-				col[2]= orig->b;
-			}
-			
-			/* XXX: arbitrary limit */
-			if (LC_LUMINOSITY(col) < 0.01f)
-				continue;
-			
-			lar = (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
+			col[0]= col[1]= col[2]= 0.0f;
+			do_lamp_tex_eval(orig, texvec, 0, col);
+		}
+		else {
+			col[0]= orig->r;
+			col[1]= orig->g;
+			col[2]= orig->b;
+		}
+		
+		/* XXX: arbitrary limit */
+		if (LC_LUMINOSITY(col) < 0.01f)
+			continue;
+		
+		gonew= MEM_callocN(sizeof(GroupObject), "groupobject");
+		BLI_addtail(&lcd->pointlights, gonew);
+		/* XXX: see remarks on similar code in convert_environment_map */
+		gonew->ob= 0;
+		
+		lar = (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
 
-			create_lamp_oriented(re, lar, orig);
-			
-			lar->co[0]= orig->co[0] + xdir[0] * stepx + ydir[0] * stepy;
-			lar->co[1]= orig->co[1] + xdir[1] * stepx + ydir[1] * stepy;
-			lar->co[2]= orig->co[2] + xdir[2] * stepx + ydir[2] * stepy;
-			
-			lar->r= col[0] * factor;
-			lar->g= col[1] * factor;
-			lar->b= col[2] * factor;
-			lar->energy= orig->energy * factor;
+		create_lamp_oriented(re, lar, orig);
+		
+		lar->co[0]= orig->co[0] + xdir[0] * stepx + ydir[0] * stepy;
+		lar->co[1]= orig->co[1] + xdir[1] * stepx + ydir[1] * stepy;
+		lar->co[2]= orig->co[2] + xdir[2] * stepx + ydir[2] * stepy;
+		
+		lar->r= col[0] * factor;
+		lar->g= col[1] * factor;
+		lar->b= col[2] * factor;
+		lar->energy= orig->energy * factor;
 
 #ifdef LIGHTCUTS_DEBUG
-			//printf("coordinates: %4f %4f %4f\n", lar->co[0], lar->co[1], lar->co[2]);
+		//printf("coordinates: %4f %4f %4f\n", lar->co[0], lar->co[1], lar->co[2]);
 #endif
 
-			BLI_addtail(&re->lampren, lar);
-			/* check deallocation */
-			gonew->lampren= lar;
+		BLI_addtail(&re->lampren, lar);
+		/* check deallocation */
+		gonew->lampren= lar;
 
-			/* TODO: handle other attenuation models */
-			if (lar->dist < lcd->max_spot_dist)
-				lcd->max_spot_dist= lar->dist;
+		/* TODO: handle other attenuation models */
+		if (lar->dist < lcd->max_spot_dist)
+			lcd->max_spot_dist= lar->dist;
 
-			lcd->trees[TREE_SPOT].counter++;
-			lcd->light_counter++;
-			lar->ray_samp_method = LA_SAMP_CONSTANT;
-		}
+		lcd->trees[TREE_SPOT].counter++;
+		lcd->light_counter++;
+		lar->ray_samp_method = LA_SAMP_CONSTANT;
 	}
 }
 





More information about the Bf-blender-cvs mailing list