Revision: 17186
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=17186
Author:   unclezeiv
Date:     2008-10-23 00:06:03 +0200 (Thu, 23 Oct 2008)

Log Message:
-----------
New feature: meshlights. Objects with materials having emit > 0.0 will actually 
emit light.

This is a preliminary commit and there are still some issues, but testing and 
user input is very welcome.

Also: cleaned up the code that creates a mesh with a vertex for each vpl, 
opening up the possibility to create other visualization meshes (for instance 
how the meshlights get sampled).

Modified Paths:
--------------
    branches/soc-2008-unclezeiv/source/blender/blenloader/intern/readfile.c
    branches/soc-2008-unclezeiv/source/blender/makesdna/DNA_scene_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/blenloader/intern/readfile.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/blenloader/intern/readfile.c     
2008-10-22 20:30:02 UTC (rev 17185)
+++ branches/soc-2008-unclezeiv/source/blender/blenloader/intern/readfile.c     
2008-10-22 22:06:03 UTC (rev 17186)
@@ -7838,8 +7838,8 @@
                                        r->lightcuts_indir_fac= 100.0f;
                                if(r->lightcuts_env_map<=0.0f)
                                        r->lightcuts_env_map= 4096.0f;
-                               if(r->lightcuts_area_lights<=0.0f)
-                                       r->lightcuts_area_lights= 4000.0f;
+                               if(r->lightcuts_area_lights<=0)
+                                       r->lightcuts_area_lights= 4000;
                                if(r->lightcuts_indir_dist<=0.0f)
                                        r->lightcuts_indir_dist= 5.0f;
                                if(r->lightcuts_color_weight==0)
@@ -7848,6 +7848,8 @@
                                        r->lightcuts_env_map_fac= 1.0f;
                                if(r->lightcuts_indir_bounces==0)
                                        r->lightcuts_indir_bounces= 1;
+                               if(r->lightcuts_meshlights==0)
+                                       r->lightcuts_meshlights= 4000;
                        }
                        
                        sce= sce->id.next;

Modified: branches/soc-2008-unclezeiv/source/blender/makesdna/DNA_scene_types.h
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/makesdna/DNA_scene_types.h       
2008-10-22 20:30:02 UTC (rev 17185)
+++ branches/soc-2008-unclezeiv/source/blender/makesdna/DNA_scene_types.h       
2008-10-22 22:06:03 UTC (rev 17186)
@@ -324,6 +324,8 @@
        int lightcuts_options;
        float lightcuts_indir_dist;
        float lightcuts_env_map_fac;
+       int lightcuts_meshlights;
+       int lcpad;
        int lightcuts_debug_options;
 } RenderData;
 

Modified: 
branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-10-22 20:30:02 UTC (rev 17185)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 
2008-10-22 22:06:03 UTC (rev 17186)
@@ -48,6 +48,7 @@
 
 #include "blendef.h"
 #include "pixelshading.h"
+#include "renderdatabase.h"
 #include "render_types.h"
 #include "shading.h"
 
@@ -206,6 +207,7 @@
        float colw[3];
        
        float area_density;
+       float meshlights_density;
 
        CutNode *cut_nodes;
        int cut_nodes_size;
@@ -1440,7 +1442,7 @@
        dir[2]= cosf(phi);
 }
 
-static void dbg_create_vpl_mesh(Render *re, LightcutsData *lcd)
+static void dbg_create_vis_mesh(Render *re, int counter, float *coords, char * 
name)
 {
        int i, newlen;
        Mesh *mesh;
@@ -1450,13 +1452,13 @@
        Scene *scene;
        Object *object, *camera;
 
-       mesh= add_mesh("indir_visualize");
+       mesh= add_mesh(name);
        MEM_freeN(mesh->bb);
        mesh->bb= NULL;
        mesh->id.us = 0;
 
        /* create custom vertex data arrays and copy existing vertices into it 
*/
-       newlen = mesh->totvert + lcd->vpl_counter;
+       newlen = mesh->totvert + counter;
        CustomData_copy( &mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, newlen 
);
        CustomData_copy_data( &mesh->vdata, &vdata, 0, 0, mesh->totvert );
 
@@ -1468,8 +1470,8 @@
        /* scan the input list and insert the new vertices */
 
        tmpvert = &newvert[mesh->totvert];
-       for( i = 0; i < lcd->vpl_counter; ++i, ++tmpvert )
-               memcpy( tmpvert->co, &lcd->dbg_vis_vpl[3 * i], sizeof(float) * 
3 );
+       for( i = 0; i < counter; ++i, ++tmpvert )
+               memcpy( tmpvert->co, &coords[3 * i], sizeof(float) * 3 );
        
        CustomData_free( &mesh->vdata, mesh->totvert );
        mesh->vdata = vdata;
@@ -1888,14 +1890,119 @@
        }
 }
 
+void get_random_point_on_triangle(float *v1, float *v2, float *v3, float *res)
+{
+       float dir1[3], dir2[3];
+       float r1= BLI_frand(), r2= BLI_frand();
+       
+       VECSUB(dir1, v2, v1);
+       VECSUB(dir2, v3, v1);
+       
+       if (r1 + r2 > 1.0f) {
+               r1= 1.0 - r1;
+               r2= 1.0 - r2;
+       }
+       
+       res[0]= res[1]= res[2]= 0.0f;
+       
+       VECADDFAC(res, v1, dir1, r1);
+       VECADDFAC(res, res, dir2, r2);
+}
+
+void add_meshlight(Render *re, LightcutsData *lcd, ObjectRen *obr, VlakRen 
*vla, float *co, float weight)
+{
+       LampRen *lar;
+       Material *mat= vla->mat;
+       lar= MEM_callocN(sizeof(LampRen), "lampren");
+       lamp_init(re, lar);
+       lar->dist= lcd->indir_dist;
+       lar->distkw= lar->dist * lar->dist;
+       lar->lay= obr->lay;
+
+       /* TODO: how to decide specular */
+       // lar->mode |= LA_NO_SPEC;
+
+       /* lamp is oriented as (negated) face normal */
+       VECCOPY(lar->vec, vla->n);
+       VECNEG(lar->vec);
+       VECCOPY(lar->mat[2], vla->n);
+       VecOrthoBasisf(lar->mat[2], lar->mat[0], lar->mat[1]);
+       Mat3Inv(lar->imat, lar->mat);
+       lar->type = LA_SPOT;
+       VECADDFAC(lar->co, co, vla->n, -0.01);
+       /* VECCOPY(lcd->dbg_vis_vpl + 3 * lcd->light_counter, lar->co); */
+       lar->ray_samp_method= LA_SAMP_CONSTANT;
+       
+       lar->energy= mat->emit * weight;
+
+       lar->r= lar->energy * mat->r;
+       lar->g= lar->energy * mat->g;
+       lar->b= lar->energy * mat->b;
+
+       BLI_addtail(&lcd->pointlights, lar);
+
+       lcd->trees[TREE_SPOT].counter++;
+       lcd->light_counter++;
+}
+
+void add_lights_from_mesh(LightcutsData *lcd, Render *re)
+{
+       ObjectRen *obr;
+       float *v1, *v2, *v3, *v4, area, co[3], budget;
+       float density= lcd->meshlights_density;
+       float weight= 1.0f / density;
+       int a, n, i;
+       
+       for(obr=re->objecttable.first; obr; obr=obr->next) {
+               for(a=0; a<obr->totvlak; a++) {
+                       VlakRen *vlr= RE_findOrAddVlak(obr, a);
+                       
+                       if (!vlr->mat || vlr->mat->emit == 0.0f)
+                               continue;
+                               
+                       v1= vlr->v1->co;
+                       v2= vlr->v2->co;
+                       v3= vlr->v3->co;
+                       if (vlr->v4)
+                               v4= vlr->v4->co;
+                       
+                       area= AreaT3Dfl(v1, v2, v3);
+                       budget= area * density;
+                       n= (int)(budget);
+                       if (BLI_frand() < (budget - (float)n))
+                               n++;
+
+                       for (i= 0; i < n; i++) {
+                               get_random_point_on_triangle(v1, v2, v3, co);
+                               add_meshlight(re, lcd, obr, vlr, co, weight);
+                       }
+                       
+                       if (vlr->v4) {
+                               /* XXX: check */
+                               area= AreaT3Dfl(v1, v3, v4);
+                               budget= area * density;
+                               n= (int)(budget);
+                               if (BLI_frand() < (budget - (float)n))
+                                       n++;
+
+                               for (i= 0; i < n; i++) {
+                                       get_random_point_on_triangle(v1, v3, 
v4, co);
+                                       add_meshlight(re, lcd, obr, vlr, co, 
weight);
+                               }       
+                       } 
+               }
+       }
+}
+
 void lightcuts_init(Render * re)
 {
        LightcutsData *lcd;
        GroupObject *go;
        ListBase *lights = &re->lights;
        LampRen *lar, *own;
+       ObjectRen *obr;
        char tree_time_str[12]; /* length 12 required by BLI_timestr */
-       int i, stop=0;
+       int i, stop=0, a;
        
        re->i.infostr= "Initializing Lightcuts";
        re->stats_draw(&re->i);
@@ -1943,7 +2050,7 @@
        else if (lcd->options & LC_OPT_ENV_LIGHT && re->r.lightcuts_env_map > 0)
                R= *re;
        
-       {
+       if (lcd->do_indir > 0 && lcd->options & LC_OPT_INDIR_MESH) {
                int n_orig= 0;
                int n_area= 0;
                int n_vpl= 0;
@@ -1966,15 +2073,13 @@
                if (lcd->options & LC_OPT_ENV_LIGHT)
                        n_generated+= re->r.lightcuts_env_map;
                
-               if (lcd->do_indir > 0) {
-                       n_vpl= (n_orig + n_generated) * lcd->do_indir * 
lcd->indir_bounces;
-                       
-                       /* allocate array to hold coordinates for all possible 
virtual point lights */
-                       if (lcd->options & LC_OPT_INDIR_MESH && n_vpl != 0)
-                               lcd->dbg_vis_vpl= MEM_callocN(sizeof(float) * 3 
* n_vpl, "lc_vpl_visualization");
-                       
-                       n_generated+= n_vpl;
-               }
+               n_vpl= (n_orig + n_generated) * lcd->do_indir * 
lcd->indir_bounces;
+
+               /* allocate array to hold coordinates for all possible virtual 
point lights */
+               if (n_vpl != 0)
+                       lcd->dbg_vis_vpl= MEM_callocN(sizeof(float) * 3 * 
n_vpl, "lc_vpl_visualization");
+
+               /* n_generated+= n_vpl; */
        }
        
        /* TODO: we could do some form of importance sampling here */
@@ -1986,10 +2091,32 @@
        }
        lcd->area_density= re->r.lightcuts_area_lights / lcd->area_density;
        
+       /* meshlights */
+       if (re->r.lightcuts_meshlights > 0) {
+               for(obr=re->objecttable.first; obr; obr=obr->next) {
+                       for(a=0; a<obr->totvlak; a++) {
+                               VlakRen *vlr= RE_findOrAddVlak(obr, a);
+                               
+                               if (vlr->mat && vlr->mat->emit != 0.0f) {
+                                       if (vlr->v4)
+                                               lcd->meshlights_density+= 
AreaQ3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co, vlr->v4->co);
+                                       else
+                                               lcd->meshlights_density+= 
AreaT3Dfl(vlr->v1->co, vlr->v2->co, vlr->v3->co); 
+                               }
+                       }
+               }
+               if (lcd->meshlights_density > 0.0f)
+                       lcd->meshlights_density= re->r.lightcuts_meshlights / 
lcd->meshlights_density;
+               /* lcd->dbg_vis_vpl= MEM_callocN(sizeof(float) * 3 * 
re->r.lightcuts_meshlights, "lc_vpl_visualization"); */
+       }
+
        /* light conversion */
        
        if (lcd->options & LC_OPT_ENV_LIGHT && re->r.lightcuts_env_map > 0)
                convert_environment_map(re, lcd, re->r.lightcuts_env_map, 
re->r.lightcuts_env_map_fac);
+       
+       if (lcd->meshlights_density > 0.0f)
+               add_lights_from_mesh(lcd, re);
 
        for(go=lights->first; go; go= go->next) {
                lar= go->lampren;
@@ -2084,8 +2211,10 @@
                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);
+                       dbg_create_vis_mesh(re, lcd->vpl_counter, 
lcd->dbg_vis_vpl, "indir_visualize");
        }
+       
+       /* dbg_create_vis_mesh(re, re->r.lightcuts_meshlights, 
lcd->dbg_vis_vpl, "meshlight_visualize"); */
 }
 
 /* Adapted from "Transforming Axis-Aligned Bounding Boxes" by Jim Arvo, 
"Graphics Gems", Academic Press, 1990 */

Modified: branches/soc-2008-unclezeiv/source/blender/src/buttons_scene.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/src/buttons_scene.c      
2008-10-22 20:30:02 UTC (rev 17185)
+++ branches/soc-2008-unclezeiv/source/blender/src/buttons_scene.c      
2008-10-22 22:06:03 UTC (rev 17186)
@@ -3481,7 +3481,8 @@
        uiDefButI(block, NUM, B_DIFF, "Max cut:", 97, -22, 95, 20, 
&G.scene->r.lightcuts_max_cut, 0, 5000, 0, 0, "The maximum size of the cut 
(higher values increase rendering times for occluded areas)");
        uiBlockEndAlign(block);
        
-       uiDefButI(block, NUM, B_DIFF, "Area lights:", 0, -54, 192, 20, 
&G.scene->r.lightcuts_area_lights, 0, 100000, 0, 0, "The number of point lights 
generated for all the area lights");
+       uiDefButI(block, NUM, B_DIFF, "Area lights:", 0, -54, 96, 20, 
&G.scene->r.lightcuts_area_lights, 0, 100000, 0, 0, "The number of point lights 
generated for all the area lights");
+       uiDefButI(block, NUM, B_DIFF, "Meshlights:", 96, -54, 96, 20, 
&G.scene->r.lightcuts_meshlights, 0, 100000, 0, 0, "The number of point lights 
generated for all the meshlights");
 
        uiBlockBeginAlign(block);
        uiDefButBitI(block, TOG, 0x8, B_DIFF, "Enable", 0, -86, 62, 20, 
&G.scene->r.lightcuts_options, 0, 0, 0, 0, "Enable environment map lighting");


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

Reply via email to