diff options
author | Ton Roosendaal <ton@blender.org> | 2005-08-25 17:11:04 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2005-08-25 17:11:04 +0400 |
commit | 8d940dfafe577ea92c279cc41e791b0012c78d2b (patch) | |
tree | 88d286b2bc9ad136e7f96661fcd802d2811a52f2 /source/blender/blenlib | |
parent | c9f01eefcd3c21da95c7245a6b1f54ceae4024b1 (diff) |
Random() issues with rendering...
- AO and soft shadow AreaLight tables were generated without fixed seed,
causing animations to give unwanted amounts of noise.
- Made sure these tables now are calculated before render, with fixed seed
- Then found out the BLI_rand() has very bad seeding... it showed up as
patterns. After some experimenting, found a nice method using noise.c
hash tables. For compatibility with old code, named it BLI_srandom() to
use this next to the BLI_srand(). This follows libc rand() and random()
naming convention.
- Then of course threading should work... so made a BLI_thread_rand version
of the calls. Now supports up to 16 threads, comments added in .h and .c
Result is stable animation render with AO and soft shadow. But, please
test and feedback!
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_rand.h | 18 | ||||
-rw-r--r-- | source/blender/blenlib/intern/rand.c | 40 |
2 files changed, 56 insertions, 2 deletions
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h index e6b0146cfab..da2ecb79651 100644 --- a/source/blender/blenlib/BLI_rand.h +++ b/source/blender/blenlib/BLI_rand.h @@ -55,6 +55,9 @@ void rng_shuffleArray(struct RNG *rng, void *data, int elemSize, int numElems); /** Seed the random number generator */ void BLI_srand (unsigned int seed); + /** Better seed for the random number generator, using noise.c hash[] */ +void BLI_srandom (unsigned int seed); + /** Return a pseudo-random number N where 0<=N<(2^31) */ int BLI_rand (void); @@ -77,5 +80,20 @@ void BLI_fillrand (void *addr, int len); */ void BLI_array_randomize (void *data, int elemSize, int numElems, unsigned int seed); + + /** Better seed for the random number generator, using noise.c hash[] */ + /** Allows up to 16 threads to address */ +void BLI_thread_srandom (int thread, unsigned int seed); + + /** Return a pseudo-random number N where 0<=N<(2^31) */ + /** Allows up to 16 threads to address */ +int BLI_thread_rand (int thread); + + /** Return a pseudo-random number N where 0.0f<=N<1.0f */ + /** Allows up to 16 threads to address */ +float BLI_thread_frand (int thread); + + + #endif diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c index 191d63f9748..a8b59fc58f3 100644 --- a/source/blender/blenlib/intern/rand.c +++ b/source/blender/blenlib/intern/rand.c @@ -48,7 +48,7 @@ typedef unsigned __int64 r_uint64; typedef unsigned long long r_uint64; #endif -#define MULTIPLIER 0x5DEECE66D +#define MULTIPLIER 0x5DEECE66DLL #define ADDEND 0xB #define LOWSEED 0x330E @@ -78,7 +78,7 @@ void rng_seed(RNG *rng, unsigned int seed) { } int rng_getInt(RNG *rng) { - rng->X= (MULTIPLIER*rng->X + ADDEND)&0x0000FFFFFFFFFFFF; + rng->X= (MULTIPLIER*rng->X + ADDEND)&0x0000FFFFFFFFFFFFLL; return (int) (rng->X>>17); } @@ -112,10 +112,22 @@ void rng_shuffleArray(RNG *rng, void *data, int elemSize, int numElems) static RNG theBLI_rng = {0}; +/* note, this one creates periodical patterns */ void BLI_srand(unsigned int seed) { rng_seed(&theBLI_rng, seed); } +/* using hash table to create better seed */ +void BLI_srandom(unsigned int seed) { + extern unsigned char hash[]; // noise.c + + rng_seed(&theBLI_rng, seed + hash[seed & 255]); + seed= rng_getInt(&theBLI_rng); + rng_seed(&theBLI_rng, seed + hash[seed & 255]); + seed= rng_getInt(&theBLI_rng); + rng_seed(&theBLI_rng, seed + hash[seed & 255]); +} + int BLI_rand(void) { return rng_getInt(&theBLI_rng); } @@ -144,3 +156,27 @@ void BLI_array_randomize(void *data, int elemSize, int numElems, unsigned int se rng_shuffleArray(&rng, data, elemSize, numElems); } +/* ********* for threaded random ************** */ +#define MAX_RNG_THREADS 16 + +static RNG rng_tab[MAX_RNG_THREADS]; + +void BLI_thread_srandom(int thread, unsigned int seed) +{ + extern unsigned char hash[]; // noise.c + + rng_seed(&rng_tab[thread], seed + hash[seed & 255]); + seed= rng_getInt(&rng_tab[thread]); + rng_seed(&rng_tab[thread], seed + hash[seed & 255]); + seed= rng_getInt(&rng_tab[thread]); + rng_seed(&rng_tab[thread], seed + hash[seed & 255]); +} + +int BLI_thread_rand(int thread) { + return rng_getInt(&rng_tab[thread]); +} + +float BLI_thread_frand(int thread) { + return rng_getFloat(&rng_tab[thread]); +} + |