[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [17186] branches/soc-2008-unclezeiv/source /blender: New feature: meshlights.
Davide Vercelli
davide.vercelli at gmail.com
Thu Oct 23 00:06:03 CEST 2008
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");
More information about the Bf-blender-cvs
mailing list