[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