diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-04-16 03:12:40 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-04-16 03:12:40 +0400 |
commit | afb4b65167165613f177a531bd3d4dcb3649c1c6 (patch) | |
tree | 32e1446b5fc3ce8ec00fa0e8b9e0fcb2eedda127 /source/blender/render | |
parent | 638b084f824bc345468bc8e02422b5da65a641a7 (diff) |
Random number generator: replace a bunch of usage of the global random number
generator with a local one. It's not thread safe and will not give repeatable
results, so in most cases it should not be used.
Also fixes #34992 where the noise texture of a displacement modifier was not
properly random in opengl animation render, because the seed got reset to a
fixed value by an unrelated function while for final render it changed each
frame.
Diffstat (limited to 'source/blender/render')
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 21 | ||||
-rw-r--r-- | source/blender/render/intern/source/rayshade.c | 34 |
2 files changed, 33 insertions, 22 deletions
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 6b033a4eb3c..76179b25871 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -176,6 +176,7 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void), Scene *scene; Object *camera; Camera *cam; + RNG *rng; double dblrand, hlfrand; float vec[4], fx, fy, fz; float fac, starmindist, clipend; @@ -244,14 +245,16 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void), if (re) /* add render object for stars */ obr= RE_addRenderObject(re, NULL, NULL, 0, 0, 0); + rng = BLI_rng_new(0); + for (x = sx, fx = sx * stargrid; x <= ex; x++, fx += stargrid) { for (y = sy, fy = sy * stargrid; y <= ey; y++, fy += stargrid) { for (z = sz, fz = sz * stargrid; z <= ez; z++, fz += stargrid) { - BLI_srand((hash[z & 0xff] << 24) + (hash[y & 0xff] << 16) + (hash[x & 0xff] << 8)); - vec[0] = fx + (hlfrand * BLI_drand()) - dblrand; - vec[1] = fy + (hlfrand * BLI_drand()) - dblrand; - vec[2] = fz + (hlfrand * BLI_drand()) - dblrand; + BLI_rng_seed(rng, (hash[z & 0xff] << 24) + (hash[y & 0xff] << 16) + (hash[x & 0xff] << 8)); + vec[0] = fx + (hlfrand * BLI_rng_get_double(rng)) - dblrand; + vec[1] = fy + (hlfrand * BLI_rng_get_double(rng)) - dblrand; + vec[2] = fz + (hlfrand * BLI_rng_get_double(rng)) - dblrand; vec[3] = 1.0; if (vertexfunc) { @@ -281,7 +284,7 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void), if (alpha != 0.0f) { - fac = force * BLI_drand(); + fac = force * BLI_rng_get_double(rng); har = initstar(re, obr, vec, fac); @@ -290,9 +293,9 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void), har->add= 255; har->r = har->g = har->b = 1.0; if (maxjit) { - har->r += ((maxjit * BLI_drand()) ) - maxjit; - har->g += ((maxjit * BLI_drand()) ) - maxjit; - har->b += ((maxjit * BLI_drand()) ) - maxjit; + har->r += ((maxjit * BLI_rng_get_double(rng)) ) - maxjit; + har->g += ((maxjit * BLI_rng_get_double(rng)) ) - maxjit; + har->b += ((maxjit * BLI_rng_get_double(rng)) ) - maxjit; } har->hard = 32; har->lay= -1; @@ -321,6 +324,8 @@ void RE_make_stars(Render *re, Scene *scenev3d, void (*initfunc)(void), if (obr) re->tothalo += obr->tothalo; + + BLI_rng_free(rng); } diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index 88c0719fa59..387004527c0 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -935,15 +935,14 @@ void init_jitter_plane(LampRen *lar) /* if 1 sample, we leave table to be zero's */ if (tot>1) { + /* set per-lamp fixed seed */ + RNG *rng = BLI_rng_new_srandom(tot); int iter=12; - /* set per-lamp fixed seed */ - BLI_srandom(tot); - /* fill table with random locations, area_size large */ for (x=0; x<tot; x++, fp+=2) { - fp[0]= (BLI_frand()-0.5f)*lar->area_size; - fp[1]= (BLI_frand()-0.5f)*lar->area_sizey; + fp[0]= (BLI_rng_get_float(rng)-0.5f)*lar->area_size; + fp[1]= (BLI_rng_get_float(rng)-0.5f)*lar->area_sizey; } while (iter--) { @@ -952,6 +951,8 @@ void init_jitter_plane(LampRen *lar) DP_energy(lar->jitter, fp, tot, lar->area_size, lar->area_sizey); } } + + BLI_rng_free(rng); } /* create the dithered tables (could just check lamp type!) */ jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, 0.5f, 0.0f); @@ -1727,12 +1728,12 @@ static int UNUSED_FUNCTION(ray_trace_shadow_rad)(ShadeInput *ship, ShadeResult * } /* aolight: function to create random unit sphere vectors for total random sampling */ -static void RandomSpherical(float v[3]) +static void RandomSpherical(RNG *rng, float v[3]) { float r; - v[2] = 2.f*BLI_frand()-1.f; + v[2] = 2.f*BLI_rng_get_float(rng)-1.f; if ((r = 1.f - v[2]*v[2])>0.f) { - float a = 6.283185307f*BLI_frand(); + float a = 6.283185307f*BLI_rng_get_float(rng); r = sqrt(r); v[0] = r * cosf(a); v[1] = r * sinf(a); @@ -1770,6 +1771,8 @@ static void DS_energy(float *sphere, int tot, float vec[3]) /* and allocates threadsafe memory */ void init_ao_sphere(World *wrld) { + /* fixed random */ + RNG *rng; float *fp; int a, tot, iter= 16; @@ -1777,14 +1780,12 @@ void init_ao_sphere(World *wrld) tot= 2*wrld->aosamp*wrld->aosamp; wrld->aosphere= MEM_mallocN(3*tot*sizeof(float), "AO sphere"); - - /* fixed random */ - BLI_srandom(tot); + rng = BLI_rng_new_srandom(tot); /* init */ fp= wrld->aosphere; for (a=0; a<tot; a++, fp+= 3) { - RandomSpherical(fp); + RandomSpherical(rng, fp); } while (iter--) { @@ -1795,6 +1796,8 @@ void init_ao_sphere(World *wrld) /* tables */ wrld->aotables= MEM_mallocN(BLENDER_MAX_THREADS*3*tot*sizeof(float), "AO tables"); + + BLI_rng_free(rng); } /* give per thread a table, we have to compare xs ys because of way OSA works... */ @@ -1823,17 +1826,20 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys, in tot= 2*resol*resol; if (type & WO_AORNDSMP) { + /* total random sampling. NOT THREADSAFE! (should be removed, is not useful) */ + RNG *rng = BLI_rng_new(BLI_thread_rand(thread)); float *sphere; int a; /* always returns table */ sphere= threadsafe_table_sphere(0, thread, xs, ys, tot); - /* total random sampling. NOT THREADSAFE! (should be removed, is not useful) */ vec= sphere; for (a=0; a<tot; a++, vec+=3) { - RandomSpherical(vec); + RandomSpherical(rng, vec); } + + BLI_rng_free(rng); return sphere; } |