[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16066] branches/soc-2008-unclezeiv/source /blender: - preliminary stuff to support "instant radiosity" -like indirect illumination.
Davide Vercelli
davide.vercelli at gmail.com
Tue Aug 12 17:06:49 CEST 2008
Revision: 16066
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16066
Author: unclezeiv
Date: 2008-08-12 17:06:49 +0200 (Tue, 12 Aug 2008)
Log Message:
-----------
- preliminary stuff to support "instant radiosity"-like indirect illumination. This is a work in progress: in particular, it currently works only for area lights and it does not take the surface color into account (=no color bleeding yet)
- raytrace.c: don't test for self intersection if the ray was not originated from a face (maybe there's another way to do this, the API is a bit obscure)
- shadeoutput.c: minor readability change
Modified Paths:
--------------
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/render/intern/source/raytrace.c
branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c
branches/soc-2008-unclezeiv/source/blender/src/buttons_scene.c
Modified: branches/soc-2008-unclezeiv/source/blender/makesdna/DNA_scene_types.h
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/makesdna/DNA_scene_types.h 2008-08-12 13:30:17 UTC (rev 16065)
+++ branches/soc-2008-unclezeiv/source/blender/makesdna/DNA_scene_types.h 2008-08-12 15:06:49 UTC (rev 16066)
@@ -318,7 +318,9 @@
int lightcuts_max_cut;
int lightcuts_area_density;
int lightcuts_env_map;
- int pad4;
+ float lightcuts_indir_fac;
+ int lightcuts_indirect;
+ int lightcuts_random_dirs;
} RenderData;
/* control render convert and shading engine */
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-12 13:30:17 UTC (rev 16065)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 2008-08-12 15:06:49 UTC (rev 16066)
@@ -49,6 +49,7 @@
#include "blendef.h"
#include "pixelshading.h"
#include "render_types.h"
+#include "shading.h"
/* #define LIGHTCUTS_DEBUG */
@@ -149,6 +150,7 @@
LightcutsTree trees[_TREES_SIZE];
int light_counter;
+ int vpl_counter;
float error_rate;
int max_lights;
@@ -159,7 +161,10 @@
int stat_samples;
int stat_cut_size;
int stat_rays_shot;
- float bb_diag_sq;
+ float scene_diag;
+ float indir_fac;
+ int do_indir;
+ int random_dirs;
double start_time;
double tree_creation_time;
@@ -299,6 +304,7 @@
return rep;
}
+#if 0
static void find_and_insert_new_min(Heap * heap, LightcutsCluster * array, int size, LightcutsClusterPair * pair, int id, int from, float c)
{
LightcutsCluster * el = &array[id];
@@ -336,6 +342,7 @@
BLI_heap_insert(heap, metric, pair);
}
}
+#endif
static void cb_update_metric_max_dist(void *data, int index, float *val, float *dist)
{
@@ -505,6 +512,7 @@
}
#endif
+#if 0
static void lightcuts_build_tree(LightcutsTree *tree, float c)
{
int i, cluster_id = 0;
@@ -563,6 +571,7 @@
MEM_freeN(pair_array);
}
+#endif
/* this one uses kdtree */
static void lightcuts_build_tree2(LightcutsTree *tree, float c)
@@ -1004,6 +1013,94 @@
}
}
+static void get_cosine_weighted_random_direction(float *dir)
+{
+ float theta, phi, rvar;
+ float sin_th;
+
+ /* cosine weighted angle to axis Z */
+ do {
+ rvar= BLI_frand();
+ theta= BLI_frand() * 0.5 * M_PI;
+ sin_th= sinf(theta);
+ } while (rvar < sin_th);
+
+ dir[2]= sqrtf(1 - sin_th * sin_th);
+
+ /* uniformly weighted angle around axis Z */
+ phi= BLI_frand() * M_PI;
+ dir[0]= cosf(phi) * sin_th;
+ dir[1]= sinf(phi) * sin_th;
+}
+
+static void add_virtual_point_light(Render * re, LightcutsData *lcd, LampRen *orig, float *col)
+{
+ GroupObject *gonew;
+ LampRen *lar;
+ VlakRen *vla;
+ Isect isec;
+ float tmp[3], dist;
+
+ isec.mode= RE_RAY_MIRROR; /* TODO: check */
+ isec.faceorig= NULL;
+ isec.oborig= 0;
+ VECCOPY(isec.start, orig->co);
+ if (lcd->random_dirs) {
+ get_cosine_weighted_random_direction(isec.vec);
+ Mat3MulVecfl(orig->mat, isec.vec);
+ VECNEG(isec.vec);
+ }
+ else
+ VECCOPY(isec.vec, orig->vec);
+ VECADDFAC(isec.end, isec.start, isec.vec, lcd->scene_diag);
+
+ if (!RE_ray_tree_intersect(re->raytree, &isec))
+ return;
+
+ vla= (VlakRen*)isec.face;
+
+ lar= (LampRen *)MEM_callocN(sizeof(LampRen), "lampren");
+ init_lamp(re, lar);
+ /* XXX: fixed distance or proportional to orig->dist? */
+ lar->dist= orig->dist / 2;
+ lar->distkw= lar->dist * lar->dist;
+ lar->lay= orig->lay;
+ 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;
+
+ /* XXX: err... something better than 0.01? */
+ VECADDFAC(lar->co, isec.start, isec.vec, isec.labda - 0.01);
+
+ /* TODO: read color */
+ lar->energy= lamp_get_visibility(orig, lar->co, tmp, &dist);
+ lar->energy*= 1.0 / (lcd->indir_fac * lcd->do_indir);
+ lar->r= lar->energy * col[0];// * isec.col[0];
+ lar->g= lar->energy * col[1];// * isec.col[1];
+ lar->b= lar->energy * col[2];// * isec.col[2];
+
+#ifdef LIGHTCUTS_DEBUG
+ //printf("coordinates: %4f %4f %4f\n", lar->co[0], lar->co[1], lar->co[2]);
+#endif
+
+ gonew= MEM_callocN(sizeof(GroupObject), "groupobject");
+ BLI_addtail(&lcd->pointlights, gonew);
+ /* XXX: see remarks on similar code in convert_environment_map */
+ gonew->ob= 0;
+
+ BLI_addtail(&re->lampren, lar);
+ /* check deallocation */
+ gonew->lampren= lar;
+
+ lcd->trees[TREE_SPOT].counter++;
+ lcd->light_counter++;
+ lcd->vpl_counter++;
+ lar->ray_samp_method = LA_SAMP_CONSTANT;
+}
+
static void convert_area_light(Render * re, LightcutsData *lcd, LampRen *orig)
{
GroupObject *gonew;
@@ -1012,7 +1109,7 @@
float xdir[3], ydir[3], col[3];
float stepx, stepy, texvec[2];
float p, u, v;
- int k, kk, pos, n;
+ int k, kk, pos, n, i;
int use_texture= 0;
int tex_nr;
@@ -1028,7 +1125,7 @@
factor= 2.0 * M_PI * orig->dist / (4.0 * realw * realh * n);
/* XXX: TODO: temporary check just to avoid freezing on undue densities */
- if (lcd->light_counter + n > re->r.lightcuts_max_lights) {
+ if (lcd->light_counter + n * (1 + lcd->do_indir) > re->r.lightcuts_max_lights) {
printf("Err: required light density would violate light limit\n");
return;
}
@@ -1107,6 +1204,10 @@
lcd->trees[TREE_SPOT].counter++;
lcd->light_counter++;
lar->ray_samp_method = LA_SAMP_CONSTANT;
+
+ /* indirect lighting */
+ for (i= 0; i < lcd->do_indir; i++)
+ add_virtual_point_light(re, lcd, lar, col);
}
}
@@ -1126,6 +1227,11 @@
re->lcdata = lcd = MEM_callocN(sizeof(LightcutsData), "LightcutsData");
pointlights= &lcd->pointlights;
lcd->light_counter= 0;
+ lcd->indir_fac= re->r.lightcuts_indir_fac;
+ lcd->do_indir= re->r.lightcuts_indirect;
+ lcd->random_dirs= re->r.lightcuts_random_dirs;
+ lcd->error_rate= re->r.lightcuts_max_error;
+ lcd->scene_diag= RE_ray_tree_max_size(re->raytree);
if (re->r.lightcuts_env_map > 0)
convert_environment_map(re, lcd, re->r.lightcuts_env_map);
@@ -1173,15 +1279,9 @@
/* XXX: this should be equal to re->r.lightcuts_max_lights when light generation is in place */
lcd->max_lights= lcd->light_counter;
- lcd->error_rate= re->r.lightcuts_max_error;
lcd->max_cut= MIN2(re->r.lightcuts_max_cut, lcd->light_counter);
lcd->start_time= PIL_check_seconds_timer();
- /* we need the scene's diagonal squared */
- lcd->bb_diag_sq= RE_ray_tree_max_size(re->raytree);
- printf("Scene diagonal %f\n", lcd->bb_diag_sq);
- lcd->bb_diag_sq*= lcd->bb_diag_sq;
-
re->i.infostr= "Building light trees";
re->stats_draw(&re->i);
@@ -1190,7 +1290,7 @@
if (lcd->trees[i].counter > 0) {
lightcuts_fill_array(pointlights, &lcd->trees[i], i);
printf("Lightcuts: building %s tree - ", tree_names[i]);
- lightcuts_build_tree2(&lcd->trees[i], lcd->bb_diag_sq);
+ lightcuts_build_tree2(&lcd->trees[i], lcd->scene_diag * lcd->scene_diag);
}
}
@@ -1824,7 +1924,7 @@
printf("Lightcuts stats\n"
"---------------\n"
"Computed samples: %d\n"
- "Number of (point) lights: %d (%dl + %ds + %do)\n"
+ "Number of (point) lights: %d (%dl + %ds + %do) (%dd + %di)\n"
"Requested error rate: %.3f\n"
"Max cut: %d\n"
"Average cut size: %.2f\n"
@@ -1832,6 +1932,7 @@
"---------------\n",
lcd->stat_samples, lcd->light_counter,
lcd->trees[TREE_LOCAL].counter, lcd->trees[TREE_SUN].counter, lcd->trees[TREE_SPOT].counter,
+ lcd->light_counter - lcd->vpl_counter, lcd->vpl_counter,
lcd->error_rate,
lcd->max_cut,
(float)lcd->stat_cut_size / (float)lcd->stat_samples,
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-12 13:30:17 UTC (rev 16065)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/raytrace.c 2008-08-12 15:06:49 UTC (rev 16066)
@@ -931,7 +931,7 @@
intersection to be detected in its neighbour face */
if(is->facecontr && is->faceisect); // optimizing, the tests below are not needed
- else if(is->labda< .1) {
+ else if(is->labda< .1 && is->faceorig) {
RayFace *face= is->faceorig;
float *origv1, *origv2, *origv3, *origv4;
short de= 0;
Modified: branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c
===================================================================
--- branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c 2008-08-12 13:30:17 UTC (rev 16065)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/shadeoutput.c 2008-08-12 15:06:49 UTC (rev 16066)
@@ -1072,7 +1072,7 @@
float visifac= 1.0f, t;
VECSUB(lv, co, lar->co);
- *dist= sqrt( INPR(lv, lv));
+ *dist= sqrt(INPR(lv, lv));
t= 1.0f/dist[0];
VECMUL(lv, t);
@@ -1115,42 +1115,39 @@
visifac*= t/lar->dist;
}
- if(visifac > 0.0f) {
- if(lar->type==LA_SPOT) {
- float inpr;
-
- if(lar->mode & LA_SQUARE) {
- if(lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2]>0.0f) {
- float lvrot[3], x;
-
- /* rotate view to lampspace */
- VECCOPY(lvrot, lv);
- MTC_Mat3MulVecfl(lar->imat, lvrot);
-
- x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2]));
- /* 1.0f/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
-
- inpr= 1.0f/(sqrt(1.0f+x*x));
- }
- else inpr= 0.0f;
+ if(lar->type==LA_SPOT && visifac > 0.0f) {
+ float inpr;
+
+ inpr= INPR(lv, lar->vec);
+
+ if(lar->mode & LA_SQUARE) {
+ if(inpr>0.0f) {
+ float lvrot[3], x;
+
+ /* rotate view to lampspace */
+ VECCOPY(lvrot, lv);
+ MTC_Mat3MulVecfl(lar->imat, lvrot);
+
+ x= MAX2(fabs(lvrot[0]/lvrot[2]) , fabs(lvrot[1]/lvrot[2]));
+ /* 1.0f/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
+
+ inpr= 1.0f/(sqrt(1.0f+x*x));
}
- else {
- inpr= lv[0]*lar->vec[0]+lv[1]*lar->vec[1]+lv[2]*lar->vec[2];
+ else inpr= 0.0f;
+ }
+
+ t= lar->spotsi;
+ if(inpr<=t)
+ visifac= 0.0f;
+ else {
+ t= inpr-t;
+ if(t<lar->spotbl && lar->spotbl!=0.0f) {
+ /* soft area */
+ float i= t/lar->spotbl;
+ t= i*i;
+ inpr*= (3.0f*t-2.0f*t*i);
}
-
- t= lar->spotsi;
- if(inpr<=t)
- visifac= 0.0f;
- else {
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list