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;
        }
 }
 


_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to