[Bf-blender-cvs] [016e75a] master: Fix T42139, vertical noise stripe patterns in noise texture.

Antony Riakiotakis noreply at git.blender.org
Thu Oct 9 15:49:08 CEST 2014


Commit: 016e75ad64935775b487e6674f7c2a4f084cd7fe
Author: Antony Riakiotakis
Date:   Thu Oct 9 15:48:38 2014 +0200
Branches: master
https://developer.blender.org/rB016e75ad64935775b487e6674f7c2a4f084cd7fe

Fix T42139, vertical noise stripe patterns in noise texture.

Two fixes here (only the second one is strictly needed to fix the issue,
but both make the system better).

First is introduction of a random generator array for use with threaded
systems where each thread needs to access its own number generator.
The random texture now uses this so it should not be influenced by other
random generator reseedings of the main random generator like it did
before.

Second, I reshuffled the texture code to resample the upper bits of the
random number first. According to Numerical Recipes, this is where the
most variance can be found, so by sampling those we avoid correlation
issues. Also, multiplying here is not ideal because if a pair of bits
are zero, then the whole result will also be zero.

Overall this is much more random (tm) than before, however result will
also be brighter, since we now have less black spots. Tweaking the
brightness/contrast should somewhat fix that, generally having the same
result as before is not possible anyway if we are to really fix this.

Also, seems like exposing procedural depth might be nice here since it
influences the precision of the texture lookup.

===================================================================

M	source/blender/blenkernel/intern/blender.c
M	source/blender/blenlib/BLI_rand.h
M	source/blender/blenlib/intern/rand.c
M	source/blender/render/extern/include/RE_render_ext.h
M	source/blender/render/intern/source/render_texture.c
M	source/creator/creator.c

===================================================================

diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index fff8265..adfe43c 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -80,6 +80,7 @@
 #include "BKE_sound.h"
 
 #include "RE_pipeline.h"
+#include "RE_render_ext.h"
 
 #include "BLF_api.h"
 
@@ -119,6 +120,7 @@ void free_blender(void)
 	DAG_exit();
 
 	BKE_brush_system_exit();
+	RE_exit_texture_rng();	
 
 	BLI_callback_global_finalize();
 
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h
index c86b3ae..879af44 100644
--- a/source/blender/blenlib/BLI_rand.h
+++ b/source/blender/blenlib/BLI_rand.h
@@ -40,6 +40,9 @@
 struct RNG;
 typedef struct RNG RNG;
 
+struct RNG_THREAD_ARRAY;
+typedef struct RNG_THREAD_ARRAY RNG_THREAD_ARRAY;
+
 struct RNG *BLI_rng_new(unsigned int seed);
 struct RNG *BLI_rng_new_srandom(unsigned int seed);
 void        BLI_rng_free(struct RNG *rng) ATTR_NONNULL(1);
@@ -89,4 +92,9 @@ int     BLI_thread_rand(int thread) ATTR_WARN_UNUSED_RESULT;
 /** Allows up to BLENDER_MAX_THREADS threads to address */
 float   BLI_thread_frand(int thread) ATTR_WARN_UNUSED_RESULT;
 
+/** array versions for thread safe random generation */
+RNG_THREAD_ARRAY *BLI_rng_threaded_new(void);
+void  BLI_rng_threaded_free(struct RNG_THREAD_ARRAY *rngarr) ATTR_NONNULL(1);
+int   BLI_rng_thread_rand(RNG_THREAD_ARRAY *rngarr, int thread) ATTR_WARN_UNUSED_RESULT;
+
 #endif  /* __BLI_RAND_H__ */
diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c
index 3dff0b3..70780f9 100644
--- a/source/blender/blenlib/intern/rand.c
+++ b/source/blender/blenlib/intern/rand.c
@@ -245,3 +245,29 @@ float BLI_thread_frand(int thread)
 	return BLI_rng_get_float(&rng_tab[thread]);
 }
 
+struct RNG_THREAD_ARRAY {
+	RNG rng_tab[BLENDER_MAX_THREADS];
+};
+
+RNG_THREAD_ARRAY *BLI_rng_threaded_new(void)
+{
+	unsigned int i;
+	RNG_THREAD_ARRAY *rngarr = MEM_mallocN(sizeof(RNG_THREAD_ARRAY), "random_array");
+	
+	for (i = 0; i < BLENDER_MAX_THREADS; i++) {
+		BLI_rng_srandom(&rngarr->rng_tab[i], (unsigned int)(rngarr->rng_tab[i].X * 257));
+	}
+	
+	return rngarr;
+}
+
+void BLI_rng_threaded_free(struct RNG_THREAD_ARRAY *rngarr)
+{
+	MEM_freeN(rngarr);
+}
+
+int BLI_rng_thread_rand(RNG_THREAD_ARRAY *rngarr, int thread)
+{
+	return BLI_rng_get_int(&rngarr->rng_tab[thread]);
+}
+
diff --git a/source/blender/render/extern/include/RE_render_ext.h b/source/blender/render/extern/include/RE_render_ext.h
index eb861d4..6d083ec 100644
--- a/source/blender/render/extern/include/RE_render_ext.h
+++ b/source/blender/render/extern/include/RE_render_ext.h
@@ -61,5 +61,7 @@ void RE_free_sample_material(struct Material *mat);
 void RE_sample_material_color(struct Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3],
                               int face_index, short hit_quad, struct DerivedMesh *orcoDm, struct Object *ob);
 
+void RE_init_texture_rng(void);
+void RE_exit_texture_rng(void);
 #endif /* __RE_RENDER_EXT_H__ */
 
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 0e61c3e..14e84c4 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -85,8 +85,19 @@
 extern struct Render R;
 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
 
+static RNG_THREAD_ARRAY *random_tex_array;
 
 
+void RE_init_texture_rng()
+{
+	random_tex_array = BLI_rng_threaded_new();
+}
+
+void RE_exit_texture_rng()
+{
+	BLI_rng_threaded_free(random_tex_array);
+}
+
 
 static void init_render_texture(Render *re, Tex *tex)
 {
@@ -709,19 +720,23 @@ static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres)
 
 /* ------------------------------------------------------------------------- */
 
-static int texnoise(Tex *tex, TexResult *texres)
+static int texnoise(Tex *tex, TexResult *texres, int thread)
 {
 	float div=3.0;
-	int val, ran, loop;
+	int val, ran, loop, shift = 30;
 	
-	ran= BLI_rand();
-	val= (ran & 3);
+	ran=  BLI_rng_thread_rand(random_tex_array, thread);
 	
 	loop= tex->noisedepth;
+
+	/* start from top bits since they have more variance */
+	val= ((ran >> shift) & 3);
+	shift -= 2;
+	
 	while (loop--) {
-		ran= (ran>>2);
-		val*= (ran & 3);
-		div*= 3.0f;
+		val += ((ran >> shift) & 3);
+		div += 3.0f;
+		shift -= 2;		
 	}
 	
 	texres->tin= ((float)val)/div;
@@ -1127,7 +1142,7 @@ static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int o
 				retval = stucci(tex, texvec, texres);
 				break;
 			case TEX_NOISE:
-				retval = texnoise(tex, texres);
+				retval = texnoise(tex, texres, thread);
 				break;
 			case TEX_IMAGE:
 				if (osatex) retval = imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres, pool);
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 12ae5c5..d779095 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -107,6 +107,7 @@
 
 #include "RE_engine.h"
 #include "RE_pipeline.h"
+#include "RE_render_ext.h"
 
 #include "ED_datafiles.h"
 #include "ED_util.h"
@@ -1627,6 +1628,8 @@ int main(
 	DAG_init();
 
 	BKE_brush_system_init();
+	RE_init_texture_rng();
+	
 
 	BLI_callback_global_init();




More information about the Bf-blender-cvs mailing list