Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-04-16 03:12:40 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-04-16 03:12:40 +0400
commitafb4b65167165613f177a531bd3d4dcb3649c1c6 (patch)
tree32e1446b5fc3ce8ec00fa0e8b9e0fcb2eedda127 /source/blender/render
parent638b084f824bc345468bc8e02422b5da65a641a7 (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.c21
-rw-r--r--source/blender/render/intern/source/rayshade.c34
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;
}