[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16230] branches/soc-2008-unclezeiv/source /blender/render: Added indirect lighting generation for directional lights and environment maps (several issues remaining)
Davide Vercelli
davide.vercelli at gmail.com
Fri Aug 22 15:49:27 CEST 2008
Revision: 16230
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16230
Author: unclezeiv
Date: 2008-08-22 15:49:27 +0200 (Fri, 22 Aug 2008)
Log Message:
-----------
Added indirect lighting generation for directional lights and environment maps (several issues remaining)
Also:
- added API to retrieve bounding box of RE_ray_tree
- fixed subtle bug: bounce colour was erroneously computed as black for surfaces facing away from camera; fixed by temporarily setting R_NOPUNOFLIP before issuing shading call
Modified Paths:
--------------
branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h
branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c
Modified: branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h 2008-08-22 12:48:12 UTC (rev 16229)
+++ branches/soc-2008-unclezeiv/source/blender/render/extern/include/RE_raytrace.h 2008-08-22 13:49:27 UTC (rev 16230)
@@ -110,5 +110,8 @@
end distance */
float RE_ray_tree_max_size(RayTree *tree);
+/* get the tree's axis aligned bounding box */
+void RE_ray_tree_aabb(RayTree *tree, float *min, float *max);
+
#endif /*__RE_RAYTRACE_H__*/
Modified: branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 2008-08-22 12:48:12 UTC (rev 16229)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 2008-08-22 13:49:27 UTC (rev 16230)
@@ -175,6 +175,7 @@
int stat_discard_black;
int stat_discard_nan;
float scene_diag;
+ float scene_min[3], scene_max[3];
float indir_fac;
int do_indir;
int options;
@@ -210,6 +211,8 @@
#define IS_LEAF(node) (!(node)->child1 && !(node)->child2)
#define LC_LUMINOSITY_LIMIT (0.0001f)
+static void add_virtual_point_light(Render * re, LightcutsData *lcd, LampRen *orig, float *col, int lev);
+
/* XXX: this function looks really slow! */
static float get_bounding_cone(LightcutsCluster * one, LightcutsCluster * two, float *vec)
{
@@ -853,7 +856,7 @@
{
GroupObject *gonew;
LampRen *lar;
- int k, kk;
+ int k, kk, i;
float t, p, phi, phirad, st;
float maxc;
@@ -934,7 +937,18 @@
/* so that bright lights don't get excluded when n is large */
lar->energy *= maxc;
}
+
+ /* indirect lighting */
+ for (i= 0; i < lcd->do_indir; i++) {
+ int lev= (lcd->options & LC_OPT_2ND_BOUNCE) ? 1 : 0;
+ add_virtual_point_light(re, lcd, lar, col, lev);
+ }
+ if (lcd->do_indir > 0 && (lcd->options & LC_OPT_ONLY_INDIR)) {
+ lamp_delete(lar);
+ continue;
+ }
+
BLI_addtail(&re->lampren, lar);
/* check deallocation */
gonew->lampren= lar;
@@ -1068,6 +1082,7 @@
GroupObject go;
float savecol[3], energy, max_col;
int max_idx;
+ int old_vlr_flag;
/* hack: increase current color/energy in order to avoid too dark results */
energy= lar->energy;
@@ -1079,6 +1094,10 @@
lar->b /= lar->energy;
lar->energy= 1.0f;
+ /* don't do normal flipping in this phase */
+ old_vlr_flag= vla->flag;
+ vla->flag |= R_NOPUNOFLIP;
+
/* fake group object in order to use "light override" */
go.lampren= lar;
go.next= go.prev= 0x0;
@@ -1170,8 +1189,11 @@
lar->g= savecol[1];
lar->b= savecol[2];
+ /* restore VlakRen flags */
+ vla->flag= old_vlr_flag;
+
max_col= MAX3(shr.col[0], shr.col[1], shr.col[2]);
-
+
if (max_col==0.0f) {
lcd->stat_discard_black+= 10000;
return 0.0f;
@@ -1195,19 +1217,39 @@
isec.mode= RE_RAY_MIRROR;
isec.faceorig= NULL;
isec.oborig= 0;
- VECCOPY(isec.start, orig->co);
- if (!(lcd->options & LC_OPT_FIXED_DIRS))
- get_cosine_weighted_random_direction(isec.vec);
- else {
- isec.vec[0]= 0.0f;
- isec.vec[1]= 0.0f;
- isec.vec[2]= 1.0f;
+ switch (orig->type) {
+ case LA_SPOT:
+ VECCOPY(isec.start, orig->co);
+ if (!(lcd->options & LC_OPT_FIXED_DIRS))
+ get_cosine_weighted_random_direction(isec.vec);
+ else {
+ isec.vec[0]= 0.0f;
+ isec.vec[1]= 0.0f;
+ isec.vec[2]= 1.0f;
+ }
+ Mat3MulVecfl(orig->mat, isec.vec);
+ VECNEG(isec.vec);
+ VECADDFAC(isec.end, isec.start, isec.vec, lcd->scene_diag);
+ break;
+ case LA_SUN:
+ {
+ /* generate random point in bounding box */
+ float r[3];
+ r[0]= BLI_frand() * (lcd->scene_max[0]-lcd->scene_min[0]) + lcd->scene_min[0];
+ r[1]= BLI_frand() * (lcd->scene_max[1]-lcd->scene_min[1]) + lcd->scene_min[1];
+ r[2]= BLI_frand() * (lcd->scene_max[2]-lcd->scene_min[2]) + lcd->scene_min[2];
+
+ /* trace ray in given direction passing from that point */
+ VECCOPY(isec.vec, orig->vec);
+ VECADDFAC(isec.start, r, isec.vec, -lcd->scene_diag);
+ VECADDFAC(isec.end, isec.start, isec.vec, lcd->scene_diag * 2);
+ }
+ break;
+ case LA_LOCAL:
+ /* TODO: indirect lighting for omnidirectional lamps */
+ return;
}
- Mat3MulVecfl(orig->mat, isec.vec);
- VECNEG(isec.vec);
- VECADDFAC(isec.end, isec.start, isec.vec, lcd->scene_diag);
-
if (!RE_ray_tree_intersect(re->raytree, &isec)) {
lcd->stat_discard_nohit++;
return;
@@ -1220,7 +1262,7 @@
VECADDFAC(co, isec.start, isec.vec, isec.labda - 0.01);
fac= get_bounce_color(lcd, isec.ob, vla, co, orig, scol, isec.isect);
-
+
if (fac == 0.0f) {
lcd->stat_discard_black++;
return;
@@ -1232,11 +1274,6 @@
return;
}
#endif
-
-#ifdef LIGHTCUTS_DEBUG_INDIR
- printf("PYDBG %d: %f %f %f - %f %f %f\n",
- lev, co[0], co[1], co[2], scol[0], scol[1], scol[2]);
-#endif
lar= (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
lamp_init(re, lar);
@@ -1266,6 +1303,11 @@
lar->g= lar->energy * scol[1];
lar->b= lar->energy * scol[2];
+#ifdef LIGHTCUTS_DEBUG_INDIR
+ printf("PYDBG %d: %f %f %f - %f %f %f - %f %f %f\n",
+ lev, co[0], co[1], co[2], scol[0], scol[1], scol[2], isec.vec[0], isec.vec[1], isec.vec[2]);
+#endif
+
/* XXX: see remarks on similar code in convert_environment_map */
go= MEM_callocN(sizeof(GroupObject), "groupobject");
BLI_addtail(&lcd->pointlights, go);
@@ -1411,6 +1453,7 @@
lcd->options= re->r.lightcuts_options;
lcd->error_rate= re->r.lightcuts_max_error;
lcd->scene_diag= RE_ray_tree_max_size(re->raytree);
+ RE_ray_tree_aabb(re->raytree, lcd->scene_min, lcd->scene_max);
if (lcd->options & LC_OPT_2ND_BOUNCE)
lcd->indir_fac /= 2.0f;
@@ -1462,6 +1505,22 @@
convert_area_light(re, lcd, lar);
continue;
}
+
+ if (!ELEM3(lar->type, LA_LOCAL, LA_SUN, LA_SPOT))
+ continue;
+
+ /* indirect lighting */
+ if (lcd->do_indir > 0) {
+ int i;
+ for (i= 0; i < lcd->do_indir; i++) {
+ int lev= (lcd->options & LC_OPT_2ND_BOUNCE) ? 1 : 0;
+ float col[3] = {lar->r, lar->g, lar->b};
+ add_virtual_point_light(re, lcd, lar, col, lev);
+ }
+
+ if (lcd->options & LC_OPT_ONLY_INDIR)
+ continue;
+ }
/* first copy the initial light */
gonew= MEM_callocN(sizeof(GroupObject), "groupobject");
Modified: branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c 2008-08-22 12:48:12 UTC (rev 16229)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c 2008-08-22 13:49:27 UTC (rev 16230)
@@ -1440,3 +1440,8 @@
return ((Octree*)tree)->ocsize;
}
+void RE_ray_tree_aabb(RayTree *tree, float *min, float *max)
+{
+ VECCOPY(min, ((Octree*)tree)->min);
+ VECCOPY(max, ((Octree*)tree)->max);
+}
More information about the Bf-blender-cvs
mailing list