[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