[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [27141] branches/render25/source/blender/ render/intern: Render Branch: fix for lowres raytracing of instanced objects, and some
Brecht Van Lommel
brecht at blender.org
Thu Feb 25 21:21:10 CET 2010
Revision: 27141
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=27141
Author: blendix
Date: 2010-02-25 21:21:09 +0100 (Thu, 25 Feb 2010)
Log Message:
-----------
Render Branch: fix for lowres raytracing of instanced objects, and some
cache test code that's still disabled.
Modified Paths:
--------------
branches/render25/source/blender/render/intern/include/cache.h
branches/render25/source/blender/render/intern/include/render_types.h
branches/render25/source/blender/render/intern/source/cache.c
branches/render25/source/blender/render/intern/source/convertblender.c
branches/render25/source/blender/render/intern/source/rayshade.c
Modified: branches/render25/source/blender/render/intern/include/cache.h
===================================================================
--- branches/render25/source/blender/render/intern/include/cache.h 2010-02-25 16:08:32 UTC (rev 27140)
+++ branches/render25/source/blender/render/intern/include/cache.h 2010-02-25 20:21:09 UTC (rev 27141)
@@ -92,5 +92,12 @@
IrrCache *cache, float *ao, float env[3], float indirect[3],
float P[3], float dPdu[3], float dPdv[3], float N[3], int do_sample);
+/* Radiosity Cache */
+
+void radio_cache_create(struct Render *re, int thread);
+void radio_cache_free(struct RenderDB *rdb, int thread);
+int radio_cache_lookup(struct Render *re, struct ShadeInput *shi, float color[3], float raylength);
+void radio_cache_add(struct Render *re, struct ShadeInput *shi, float color[3]);
+
#endif /* __RENDER_CACHE_H__ */
Modified: branches/render25/source/blender/render/intern/include/render_types.h
===================================================================
--- branches/render25/source/blender/render/intern/include/render_types.h 2010-02-25 16:08:32 UTC (rev 27140)
+++ branches/render25/source/blender/render/intern/include/render_types.h 2010-02-25 20:21:09 UTC (rev 27141)
@@ -47,6 +47,7 @@
struct MemArena;
struct Object;
struct ObjectInstanceRen;
+struct RadioCache;
struct RayFace;
struct RayObject;
struct VlakPrimitive;
@@ -110,6 +111,7 @@
/* irradiance cache for AO/env/indirect */
struct IrrCache *irrcache[BLENDER_MAX_THREADS];
+ struct RadioCache *radiocache[BLENDER_MAX_THREADS];
} RenderDB;
typedef struct RenderSampleData {
Modified: branches/render25/source/blender/render/intern/source/cache.c
===================================================================
--- branches/render25/source/blender/render/intern/source/cache.c 2010-02-25 16:08:32 UTC (rev 27140)
+++ branches/render25/source/blender/render/intern/source/cache.c 2010-02-25 20:21:09 UTC (rev 27141)
@@ -408,8 +408,6 @@
#define MAX_ERROR_K 1.0f
#define WEIGHT_NORMAL_DENOM 65.823047821929777f /* 1/(1 - cos(10°)) */
#define SINGULAR_VALUE_EPSILON 1e-4f
-#define LSQ_RECONSTRUCTION
-#define NEIGHBOUR_CLAMP
/* Data Structures */
@@ -442,10 +440,15 @@
MemArena *arena; /* memory arena for nodes and samples */
int thread; /* thread owning the cache */
- /* test: a stable global coordinate system may help */
int totsample;
int totlookup;
int totpost;
+
+ /* options */
+ int neighbour_clamp;
+ int lsq_reconstruction;
+
+ /* test: a stable global coordinate system may help */
};
typedef struct Lsq4DFit {
@@ -526,6 +529,10 @@
cache->stacksize= 10;
cache->stack= MEM_mallocN(sizeof(IrrCacheNode*)*cache->stacksize*8, "IrrCache stack");
+ /* options */
+ cache->lsq_reconstruction= 1;
+ cache->neighbour_clamp= 1;
+
return cache;
}
@@ -575,7 +582,6 @@
if(indirect) copy_v3_v3(indirect, C+4);
}
-#ifdef NEIGHBOUR_CLAMP
/* Neighbour Clamping [Křivánek 2006] */
static void irr_cache_clamp_sample(IrrCache *cache, IrrCacheSample *nsample)
@@ -615,7 +621,6 @@
}
}
}
-#endif
/* Add a Sample */
@@ -642,11 +647,11 @@
sample->dP= Rmean;
irr_sample_set(sample->C, ao, env, indirect);
-#ifdef NEIGHBOUR_CLAMP
- /* neighbour clamping trick */
- irr_cache_clamp_sample(cache, sample);
- Rmean= sample->dP; /* copy dP back so we get the right place in the octree */
-#endif
+ if(cache->neighbour_clamp) {
+ /* neighbour clamping trick */
+ irr_cache_clamp_sample(cache, sample);
+ Rmean= sample->dP; /* copy dP back so we get the right place in the octree */
+ }
/* error multiplier */
Rmean /= MAX_ERROR_K;
@@ -695,10 +700,8 @@
IrrCacheNode *node, **stack, **stacknode;
float accum[CACHE_DIMENSION], P[3], N[3], totw;
float discard_weight, maxdist, distfac;
- int i, added= 0, totfound= 0;
-#ifdef LSQ_RECONSTRUCTION
+ int i, added= 0, totfound= 0, use_lsq;
Lsq4DFit lsq;
-#endif
/* XXX check how often this is called! */
/* XXX can identical samples end up in the cache now? */
@@ -718,12 +721,13 @@
stacknode= stack;
*stacknode++= &cache->root;
-#ifdef LSQ_RECONSTRUCTION
- memset(&lsq, 0, sizeof(lsq));
-#else
- memset(accum, 0, sizeof(accum));
-#endif
+ use_lsq= cache->lsq_reconstruction;
+ if(use_lsq)
+ memset(&lsq, 0, sizeof(lsq));
+ else
+ memset(accum, 0, sizeof(accum));
+
/* the motivation for this factor is that in preprocess we only require
one sample for lookup not to fail, whereas for least squares
reconstruction we need more samples for a proper reconstruction. it's
@@ -776,14 +780,14 @@
if(w > BLI_thread_frand(cache->thread)*discard_weight) {
if(!preprocess) {
-#ifdef LSQ_RECONSTRUCTION
- float a[4]= {D[0], D[1], D[2], 1.0f};
-
- lsq_4D_add(&lsq, a, sample->C, w);
-#else
- for(i=0; i<CACHE_DIMENSION; i++)
- accum[i] += w*sample->C[i];
-#endif
+ if(use_lsq) {
+ float a[4]= {D[0], D[1], D[2], 1.0f};
+ lsq_4D_add(&lsq, a, sample->C, w);
+ }
+ else {
+ for(i=0; i<CACHE_DIMENSION; i++)
+ accum[i] += w*sample->C[i];
+ }
}
totw += w;
@@ -803,14 +807,15 @@
/* do we have anything ? */
if(totw > EPSILON && totfound >= 1) {
if(!preprocess) {
-#ifdef LSQ_RECONSTRUCTION
- lsq_4D_solve(&lsq, accum);
-#else
- float invw= 1.0/totw;
+ if(use_lsq) {
+ lsq_4D_solve(&lsq, accum);
+ }
+ else {
+ float invw= 1.0/totw;
- for(i=0; i<CACHE_DIMENSION; i++)
- accum[i] *= invw;
-#endif
+ for(i=0; i<CACHE_DIMENSION; i++)
+ accum[i] *= invw;
+ }
irr_sample_get(accum, ao, env, indirect);
}
@@ -842,6 +847,8 @@
if(!((re->db.wrld.aomode & WO_AOCACHE) && (re->db.wrld.mode & (WO_AMB_OCC|WO_ENV_LIGHT|WO_INDIRECT_LIGHT))))
return;
+ //radio_cache_create(re, pa->thread);
+
cache= irr_cache_new(re, pa->thread);
re->db.irrcache[pa->thread]= cache;
@@ -897,9 +904,9 @@
}
}
}
+
+ if(re->cb.test_break(re->cb.tbh)) break;
}
-
- if(re->cb.test_break(re->cb.tbh)) break;
}
step /= 2;
@@ -916,5 +923,313 @@
irr_cache_delete(cache);
re->db.irrcache[pa->thread]= NULL;
}
+
+ radio_cache_free(&re->db, pa->thread);
}
+/****************************** Radiosity Cache ******************************/
+
+#if 0
+#define RADIO_CACHE_MAX_CHILD 8
+
+/* Data Structures */
+
+typedef struct RadioCacheSample {
+ /* cache sample in a node */
+ struct RadioCacheSample *next;
+
+ float P[3];
+ float C[3];
+} RadioCacheSample;
+
+typedef struct RadioCacheNode {
+ /* node in the cache tree */
+ float center[3]; /* center of node */
+ float side; /* max side length */
+ RadioCacheSample *samples; /* samples in the node */
+ struct RadioCacheNode *children[8]; /* child nodes */
+ int totsample;
+} RadioCacheNode;
+
+typedef struct RadioCache {
+ /* radioadiance cache */
+ RadioCacheNode root; /* root node of the tree */
+ int maxdepth; /* maximum tree dist */
+
+ RadioCacheNode **stack; /* stack for traversal */
+ int stacksize; /* stack size */
+
+ MemArena *arena; /* memory arena for nodes and samples */
+ int thread; /* thread owning the cache */
+
+ int totsample;
+ int totlookup;
+} RadioCache;
+
+/* Create and Free */
+
+void radio_cache_create(Render *re, int thread)
+{
+ RadioCache *cache;
+ float bb[2][3];
+
+ cache= MEM_callocN(sizeof(RadioCache), "RadioCache");
+ cache->thread= thread;
+ cache->maxdepth= 1;
+
+ cache->arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE);
+ BLI_memarena_use_calloc(cache->arena);
+
+ /* initialize root node with bounds */
+ render_instances_bound(&re->db, bb);
+ mid_v3_v3v3(cache->root.center, bb[0], bb[1]);
+ cache->root.side= MAX3(bb[1][0]-bb[0][0], bb[1][1]-bb[0][1], bb[1][2]-bb[0][2]);
+
+ /* allocate stack */
+ cache->stacksize= 10;
+ cache->stack= MEM_mallocN(sizeof(RadioCacheNode*)*cache->stacksize*8, "RadioCache stack");
+
+ re->db.radiocache[thread]= cache;
+}
+
+void radio_cache_free(RenderDB *rdb, int thread)
+{
+ RadioCache *cache= rdb->radiocache[thread];
+
+ if(cache) {
+ printf("radio cache %d/%d, efficiency %f\n", cache->totsample, cache->totlookup, (float)cache->totsample/(float)cache->totlookup);
+
+ BLI_memarena_free(cache->arena);
+ MEM_freeN(cache->stack);
+ MEM_freeN(cache);
+
+ rdb->radiocache[thread]= NULL;
+ }
+}
+
+void radio_cache_check_stack(RadioCache *cache)
+{
+ /* increase stack size as more nodes are added */
+ if(cache->maxdepth > cache->stacksize) {
+ cache->stacksize= cache->maxdepth + 5;
+ MEM_freeN(cache->stack);
+ cache->stack= MEM_mallocN(sizeof(RadioCacheNode*)*cache->stacksize*8, "RadioCache stack");
+ }
+}
+
+static int radio_cache_node_point_inside(RadioCacheNode *node, float scale, float add, float P[3])
+{
+ float side= node->side*scale + add;
+
+ return (((node->center[0] + side) > P[0]) &&
+ ((node->center[1] + side) > P[1]) &&
+ ((node->center[2] + side) > P[2]) &&
+ ((node->center[0] - side) < P[0]) &&
+ ((node->center[1] - side) < P[1]) &&
+ ((node->center[2] - side) < P[2]));
+}
+
+void radio_cache_add(Render *re, ShadeInput *shi, float C[3])
+{
+ RadioCache *cache= re->db.radiocache[shi->shading.thread];
+ RadioCacheSample *sample;
+ RadioCacheNode *node;
+ float P[3];
+ int i, j, depth;
+
+ if(!cache)
+ return;
+
+ sample= BLI_memarena_alloc(cache->arena, sizeof(RadioCacheSample));
+
+ /* record the data */
+ copy_v3_v3(P, shi->geometry.co);
+ copy_v3_v3(sample->P, P);
+ copy_v3_v3(sample->C, C);
+
+ /* insert the new sample into the cache */
+ node= &cache->root;
+ depth= 0;
+ while(node->totsample > RADIO_CACHE_MAX_CHILD) {
+ depth++;
+
+ j= 0;
+ for(i=0; i<3; i++)
+ if(P[i] > node->center[i])
+ j |= 1 << i;
+
+ if(node->children[j] == NULL) {
+ RadioCacheNode *nnode= BLI_memarena_alloc(cache->arena, sizeof(RadioCacheNode));
+
+ for(i=0; i<3; i++) {
+ float fac= (P[i] > node->center[i])? 0.25f: -0.25f;
+ nnode->center[i]= node->center[i] + fac*node->side;
+ }
+
+ nnode->side= node->side*0.5f;
+ node->children[j]= nnode;
+ }
+
+ node= node->children[j];
+ }
+
+ sample->next= node->samples;
+ node->samples= sample;
+ node->totsample++;
+
+ cache->maxdepth= MAX2(depth, cache->maxdepth);
+ radio_cache_check_stack(cache);
+
+ cache->totsample++;
+}
+
+/* Lookup */
+
+int radio_cache_lookup(Render *re, ShadeInput *shi, float C[3], float raylength)
+{
+ RadioCache *cache= re->db.radiocache[shi->shading.thread];
+ RadioCacheSample *sample;
+ RadioCacheNode *node, **stack, **stacknode;
+ float P[3], accum[3], totw, maxdist;
+ int i, totfound= 0;
+
+ if(!cache)
+ return 0;
+
+ cache->totlookup++;
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list