[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15365] branches/soc-2008-unclezeiv/source /blender/render/intern/source/lightcuts.c: - added correct computation of scene bounding box diagonal, needed to compute cluster similiarity metric during tree building; this completes support for oriented lights
Davide Vercelli
davide.vercelli at gmail.com
Fri Jun 27 03:06:37 CEST 2008
Revision: 15365
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15365
Author: unclezeiv
Date: 2008-06-27 03:05:31 +0200 (Fri, 27 Jun 2008)
Log Message:
-----------
- added correct computation of scene bounding box diagonal, needed to compute cluster similiarity metric during tree building; this completes support for oriented lights
- simplified code a bit, as translations were often not needed in many calculations; this way I also found out that I was using transposed matrices w.r.t. blender convention (they were isolated though, no bugs because of this)
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-06-26 18:28:33 UTC (rev 15364)
+++ branches/soc-2008-unclezeiv/source/blender/render/intern/source/lightcuts.c 2008-06-27 01:05:31 UTC (rev 15365)
@@ -40,6 +40,7 @@
#include "MEM_guardedalloc.h"
#include "PIL_time.h"
#include "RE_pipeline.h"
+#include "RE_raytrace.h"
#include "blendef.h"
#include "render_types.h"
@@ -115,7 +116,6 @@
typedef struct LightcutsData {
/* NOTE: conservative space estimation */
- /* TODO: equivalent data structures for sun and spot */
ListBase pointlights;
LightcutsTree trees[_TREES_SIZE];
@@ -145,10 +145,11 @@
} LightcutsData;
#define VEC_LEN_SQ(v) (v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
+#define VECCOPYMUL(v1,v2,aS) {*(v1)= *(v2)*aS; *(v1+1)= *(v2+1)*aS; *(v1+2)= *(v2+2)*aS;}
+#define VECNEG(v) {*(v)=-*(v); *(v+1)=-*(v+1); *(v+2)=-*(v+2);}
/* TODO: tentative calculation, will look better into it */
#define LC_LUMINOSITY(c) (0.299*(c)[0] + 0.587*(c)[1] + 0.114*(c)[2])
/* #define LC_LUMINOSITY(c) (0.316*c[0] + 0.460*c[1] + 0.224*c[2]) */
-#define VECCOPYMUL(v1,v2,aS) {*(v1)= *(v2)*aS; *(v1+1)= *(v2+1)*aS; *(v1+2)= *(v2+2)*aS;}
#define IS_LEAF(node) (!(node)->child1 && !(node)->child2)
/* XXX: this function looks really slow! */
@@ -464,7 +465,7 @@
lar->shadsamp= MEM_mallocN(re->r.threads*sizeof(LampShadowSample), "lamp shadow sample");
ls= lar->shadsamp;
- /* shadfacs actually mean light, let's put them to 1 to prevent unitialized accidents */
+ /* shadfacs actually mean light, let's put them to 1 to prevent uninitialized accidents */
for(a=0; a<re->r.threads; a++, ls++) {
lss= ls->s;
for(b=0; b<re->r.osa; b++, lss++) {
@@ -520,7 +521,6 @@
lcd->trees[TREE_LOCAL].counter++;
/* TODO: handle other attenuation models */
-
if (lar->dist < lcd->max_local_dist)
lcd->max_local_dist = lar->dist;
@@ -530,6 +530,8 @@
break;
case LA_SPOT:
/* TODO: check if it's a valid spot */
+
+ /* TODO: handle other attenuation models */
if (lar->dist < lcd->max_spot_dist)
lcd->max_spot_dist= lar->dist;
@@ -560,7 +562,7 @@
gonew->recalc= go->recalc;
/*
* XXX: probably wrong, more a test to see if it is used somewhere
- * or dealloacated
+ * or deallocated
* The point here is that we create new lights with no corresponding
* objects... do we need objects there?
*/
@@ -599,9 +601,12 @@
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();
- /* XXX: TODO: get proper scene diagonal */
- lcd->bb_diag_sq= 11.747*11.747;
+ /* 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);
@@ -611,7 +616,6 @@
lightcuts_fill_array(pointlights, &lcd->trees[i], i);
printf("Lightcuts: building %s tree - ", tree_names[i]);
lightcuts_build_tree(&lcd->trees[i], lcd->bb_diag_sq);
- /* TODO: put square of scene bounding box diagonale instead of 0.0f */
}
}
@@ -627,18 +631,17 @@
}
/* Adapted from "Transforming Axis-Aligned Bounding Boxes" by Jim Arvo, "Graphics Gems", Academic Press, 1990 */
-static void transform_aabb(float tsm[4][4], float min[3], float max[3], float rmin[3], float rmax[3], int do_transl)
+static void transform_aabb(float tsm[3][3], float min[3], float max[3], float rmin[3], float rmax[3])
{
int i, j;
float a, b;
for (i = 0; i < 3; i++) {
- /* translation */
- rmin[i]= rmax[i]= (do_transl ? tsm[i][3] : 0.0f);
+ rmin[i]= rmax[i]= 0.0f;
for (j = 0; j < 3; j++) {
- a= tsm[i][j] * min[j];
- b= tsm[i][j] * max[j];
+ a= tsm[j][i] * min[j];
+ b= tsm[j][i] * max[j];
if (a < b) {
rmin[i]+= a;
rmax[i]+= b;
@@ -667,45 +670,32 @@
return max[2] / sqrt(xsq + ysq + max[2]*max[2]);
}
-/* fill in tangent space matrix tsm given normal and position; please note, it's also a translation matrix */
-/* TODO: scrap the translation part, use a 3x3 and transform the vector when needed */
-static void get_tangent_space_matrix(float tsm[4][4], float *nor, float *pos, int negate)
+/* fill in tangent space matrix tsm given normal */
+static void get_tangent_space_matrix(float tsm[3][3], float *nor)
{
- float normat[4][4];
-
- /* warning: we fill it transposed as it's easier */
- /* XXX: shi->vn seems to point inside the mesh, investigate; works inverted like this */
- if (negate) {
- normat[2][0] = -nor[0];
- normat[2][1] = -nor[1];
- normat[2][2] = -nor[2];
- }
- else
- VECCOPY(normat[2], nor);
-
+ float normat[3][3];
+
+ VECCOPY(normat[2], nor);
VecOrthoBasisf(normat[2], normat[0], normat[1]);
- VECCOPY(normat[3], pos);
-
- normat[0][3]= normat[1][3]= normat[2][3]= 0.0f;
- normat[3][3]= 1.0f;
-
- Mat4Transp(normat);
/* now we have a proper tangent-to-world matrix: let's invert it */
- Mat4Invert(tsm, normat);
+ Mat3Inv(tsm, normat);
}
/* error bound: material term */
/* TODO: currently supporting only diffuse */
-static float calc_material_eb(float tsm[4][4], LightcutsCluster *clus)
+static float calc_material_eb(float tsm[3][3], LightcutsCluster *clus, float *pos)
{
float tmin[3], tmax[3];
- transform_aabb(tsm, clus->min, clus->max, tmin, tmax, (clus->type!=CLUSTER_SUN));
+ transform_aabb(tsm, clus->min, clus->max, tmin, tmax);
+ if (clus->type != CLUSTER_SUN) {
+ VECADD(tmin, pos, tmin);
+ VECADD(tmax, pos, tmax);
+ }
return MAX2(compute_cosine_bound(tmin, tmax), 0.0);
}
/* error bound: geometric term */
-/* TODO: missing LA_SPOT eb */
static float calc_geometric_eb(LightcutsData *lcd, LightcutsCluster *clus, float *pos)
{
/* find the nearest point in the bounding box */
@@ -734,14 +724,14 @@
float newmin[3], transmin[3];
float newmax[3], transmax[3];
float cos_t, angle;
- float tsm[4][4];
+ float tsm[3][3];
- get_tangent_space_matrix(tsm, clus->cone_dir, pos, 0);
+ get_tangent_space_matrix(tsm, clus->cone_dir);
VECSUB(newmax, pos, clus->min);
VECSUB(newmin, pos, clus->max);
- transform_aabb(tsm, newmin, newmax, transmin, transmax, 0);
+ transform_aabb(tsm, newmin, newmax, transmin, transmax);
cos_t= compute_cosine_bound(transmin, transmax);
angle= acosf(cos_t);
@@ -773,11 +763,13 @@
int it= 0;
int used= 0;
float i, i_noshad;
- float tsm[4][4]; /* tangent space matrix */
+ float tsm[3][3]; /* tangent space matrix */
+ float tspos[3];
LightcutsCluster *array;
- /* this heap maintaines the current cut */
- /* TODO: its maximum size is known in advance, this allows to
+ /*
+ * this heap maintains the current cut
+ * TODO: its maximum size is known in advance, this allows to
* preallocate it and share it between subsequent executions
*/
Heap *cut= BLI_heap_new();
@@ -791,9 +783,17 @@
float dbg_totlum = 0.0f;
#endif
+
+ /* XXX: shi->vn seems to point inside the mesh, investigate; works inverted like this */
+ VECCOPY(tspos, shi->vn);
+ VECNEG(tspos);
+ get_tangent_space_matrix(tsm, tspos);
+
+ /* get sample coordinates in tangent space */
+ VECCOPY(tspos, shi->co);
+ Mat3MulVecfl(tsm, tspos);
+ VECNEG(tspos);
- get_tangent_space_matrix(tsm, shi->vn, shi->co, 1);
-
cut_nodes= lcd->cut_nodes + shi->thread * lcd->cut_nodes_size;
/* initial nodes in the queue */
@@ -810,7 +810,7 @@
root->id= tree->root;
root->type= clus->type;
- root->error_bound= calc_geometric_eb(lcd, clus, shi->co) * calc_material_eb(tsm, clus) * shi->refl;
+ root->error_bound= calc_geometric_eb(lcd, clus, shi->co) * calc_material_eb(tsm, clus, tspos) * shi->refl;
#ifdef LIGHTCUTS_DEBUG
dbg_convert[tree->root]= 0;
#endif
@@ -903,15 +903,11 @@
#ifdef LIGHTCUTS_DEBUG
dbg_totlum-= cn_hinode->contr_factor * hinode->luminance;
#endif
-
- /* this is a strong assumption on linearity of intensity contribution... is it strong indeed?
- * and numerically questionable again */
- /* TODO: there is room to reuse the same block here */
-
- /* for the reprsented light we can reuse most calculations */
+
+ /* for the represented light we can reuse most calculations */
cn_rep->id= rep->id;
cn_rep->type= rep->type;
- cn_rep->error_bound= calc_geometric_eb(lcd, rep, shi->co) * calc_material_eb(tsm, rep) * shi->refl;
+ cn_rep->error_bound= calc_geometric_eb(lcd, rep, shi->co) * calc_material_eb(tsm, rep, tspos) * shi->refl;
if (cn_rep->error_bound > FLT_EPSILON) {
cn_rep->contr_factor= cn_hinode->contr_factor;
@@ -932,7 +928,7 @@
/* for the "unrepresented" light we have to compute stuff from scratch */
cn_unrep->id= unrep->id;
cn_unrep->type= unrep->type;
- cn_unrep->error_bound= calc_geometric_eb(lcd, unrep, shi->co) * calc_material_eb(tsm, unrep) * shi->refl;
+ cn_unrep->error_bound= calc_geometric_eb(lcd, unrep, shi->co) * calc_material_eb(tsm, unrep, tspos) * shi->refl;
if (cn_unrep->error_bound > FLT_EPSILON) {
get_contrib(unrep->lar, shi, &i, &i_noshad);
More information about the Bf-blender-cvs
mailing list