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:
-rw-r--r--source/blender/blenlib/BLI_rand.h18
-rw-r--r--source/blender/blenlib/intern/rand.c40
-rw-r--r--source/blender/makesdna/DNA_world_types.h4
-rw-r--r--source/blender/render/extern/include/render.h7
-rw-r--r--source/blender/render/intern/source/initrender.c8
-rw-r--r--source/blender/render/intern/source/ray.c134
-rw-r--r--source/blender/render/intern/source/rendercore.c20
-rw-r--r--source/blender/renderconverter/intern/convertBlenderScene.c28
-rw-r--r--source/blender/src/previewrender.c2
9 files changed, 157 insertions, 104 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]);
+}
+
diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h
index 06f52de8e6a..e284044a633 100644
--- a/source/blender/makesdna/DNA_world_types.h
+++ b/source/blender/makesdna/DNA_world_types.h
@@ -88,6 +88,7 @@ typedef struct World {
* bit 3: (gameengine): Activity culling is enabled.
*/
short mode;
+ int physicsEngine; /* here it's aligned */
float misi, miststa, mistdist, misthi;
@@ -101,9 +102,8 @@ typedef struct World {
/* ambient occlusion */
float aodist, aodistfac, aoenergy, aobias;
short aomode, aosamp, aomix, aocolor;
+ float *aosphere;
- int physicsEngine;
-
struct Ipo *ipo;
struct MTex *mtex[10];
diff --git a/source/blender/render/extern/include/render.h b/source/blender/render/extern/include/render.h
index b0c7939b3ab..3aef5a678d0 100644
--- a/source/blender/render/extern/include/render.h
+++ b/source/blender/render/extern/include/render.h
@@ -188,6 +188,13 @@ void ramp_spec_result(float *specr, float *specg, float *specb, ShadeInput *shi)
/* --------------------------------------------------------------------- */
+/* ray.c (2) */
+/* --------------------------------------------------------------------- */
+void init_jitter_plane(LampRen *lar);
+void init_ao_sphere(float *sphere, int tot, int iter);
+
+
+/* --------------------------------------------------------------------- */
/* renderdatabase (3) */
/* --------------------------------------------------------------------- */
struct VlakRen *RE_findOrAddVlak(int nr);
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index ee03bd8a873..259c84750d2 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -876,7 +876,7 @@ static void yafrayRender(void)
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
// exported to other files, belongs in include... later
-SDL_mutex *render_abuf_lock=NULL, *load_ibuf_lock=NULL, *make_table_lock= NULL;
+SDL_mutex *render_abuf_lock=NULL, *load_ibuf_lock=NULL;
static void renderloop_setblending(void)
@@ -920,7 +920,6 @@ static void mainRenderLoop(void) /* here the PART and FIELD loops */
/* create mutexes for threaded render */
render_abuf_lock = SDL_CreateMutex();
load_ibuf_lock = SDL_CreateMutex();
- make_table_lock = SDL_CreateMutex();
if(R.rectz) MEM_freeN(R.rectz);
R.rectz = NULL;
@@ -944,7 +943,7 @@ static void mainRenderLoop(void) /* here the PART and FIELD loops */
for(fi=0; fi<fields; fi++) {
/* INIT */
- BLI_srand( 2*(G.scene->r.cfra)+fi);
+ BLI_srandom( 2*(G.scene->r.cfra)+fi);
R.flag|= R_RENDERING;
if(fi==1) R.flag |= R_SEC_FIELD;
@@ -962,7 +961,6 @@ static void mainRenderLoop(void) /* here the PART and FIELD loops */
R.xend= R.xstart+R.rectx-1;
R.yend= R.ystart+R.recty-1;
-
if(R.r.mode & R_MBLUR) set_mblur_offs(R.osa-blur);
initparts(); /* always do, because of border */
@@ -1175,10 +1173,8 @@ static void mainRenderLoop(void) /* here the PART and FIELD loops */
/* mutexes free */
SDL_DestroyMutex(load_ibuf_lock);
SDL_DestroyMutex(render_abuf_lock);
- SDL_DestroyMutex(make_table_lock);
load_ibuf_lock= NULL;
render_abuf_lock= NULL;
- make_table_lock= NULL;
}
void render() {
diff --git a/source/blender/render/intern/source/ray.c b/source/blender/render/intern/source/ray.c
index 52266bc156e..50d7d60a19b 100644
--- a/source/blender/render/intern/source/ray.c
+++ b/source/blender/render/intern/source/ray.c
@@ -121,7 +121,6 @@ static int accepted, rejected, coherent_ray;
/* prototypes ------------------------ */
void freeoctree(void);
void makeoctree(void);
-float *test_jitter(int resol, int iter, float xsize, float ysize);
int ray_trace_shadow_rad(ShadeInput *ship, ShadeResult *shr);
/* **************** ocval method ******************* */
@@ -1594,29 +1593,6 @@ static void DP_energy(float *table, float *vec, int tot, float xsize, float ysiz
vec[1]= vec[1] - ysize*floor(vec[1]/ysize + 0.5);
}
-
-float *test_jitter(int resol, int iter, float xsize, float ysize)
-{
- static float jitter[2*256];
- float *fp;
- int x;
-
- /* fill table with random locations, area_size large */
- fp= jitter;
- for(x=0; x<resol*resol; x++, fp+=2) {
- fp[0]= (BLI_frand()-0.5)*xsize;
- fp[1]= (BLI_frand()-0.5)*ysize;
- }
-
- while(iter--) {
- fp= jitter;
- for(x=0; x<resol*resol; x++, fp+=2) {
- DP_energy(jitter, fp, resol*resol, xsize, ysize);
- }
- }
- return jitter;
-}
-
// random offset of 1 in 2
static void jitter_plane_offset(float *jitter1, float *jitter2, int tot, float sizex, float sizey, float ofsx, float ofsy)
{
@@ -1633,57 +1609,56 @@ static void jitter_plane_offset(float *jitter1, float *jitter2, int tot, float s
}
}
-/* table around origin, -0.5*size to 0.5*size */
-static float *jitter_plane(LampRen *lar, int xs, int ys)
+/* called from convertBlenderScene.c */
+/* we do this in advance to get consistant random, not alter the render seed, and be threadsafe */
+void init_jitter_plane(LampRen *lar)
{
float *fp;
- int tot, x, iter=12;
+ int x, iter=12, tot= lar->ray_totsamp;
- tot= lar->ray_totsamp;
+ fp=lar->jitter= MEM_mallocN(4*tot*2*sizeof(float), "lamp jitter tab");
- if(lar->jitter==NULL) {
- extern SDL_mutex *make_table_lock; // initrender.c
- if(make_table_lock) SDL_mutexP(make_table_lock);
-
- /* check again, since other thread could have entered */
- if(lar->jitter==NULL) {
-
-
- fp=lar->jitter= MEM_mallocN(4*tot*2*sizeof(float), "lamp jitter tab");
-
- /* fill table with random locations, area_size large */
- for(x=0; x<tot; x++, fp+=2) {
- fp[0]= (BLI_frand()-0.5)*lar->area_size;
- fp[1]= (BLI_frand()-0.5)*lar->area_sizey;
- }
-
- while(iter--) {
- fp= lar->jitter;
- for(x=tot; x>0; x--, fp+=2) {
- DP_energy(lar->jitter, fp, tot, lar->area_size, lar->area_sizey);
- }
- }
-
- jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, 0.5, 0.0);
- jitter_plane_offset(lar->jitter, lar->jitter+4*tot, tot, lar->area_size, lar->area_sizey, 0.5, 0.5);
- jitter_plane_offset(lar->jitter, lar->jitter+6*tot, tot, lar->area_size, lar->area_sizey, 0.0, 0.5);
+ /* 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.5)*lar->area_size;
+ fp[1]= (BLI_frand()-0.5)*lar->area_sizey;
+ }
+
+ while(iter--) {
+ fp= lar->jitter;
+ for(x=tot; x>0; x--, fp+=2) {
+ DP_energy(lar->jitter, fp, tot, lar->area_size, lar->area_sizey);
}
-
- if(make_table_lock) SDL_mutexV(make_table_lock);
}
-
+
+ /* create the dithered tables */
+ jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, 0.5, 0.0);
+ jitter_plane_offset(lar->jitter, lar->jitter+4*tot, tot, lar->area_size, lar->area_sizey, 0.5, 0.5);
+ jitter_plane_offset(lar->jitter, lar->jitter+6*tot, tot, lar->area_size, lar->area_sizey, 0.0, 0.5);
+}
+
+/* table around origin, -0.5*size to 0.5*size */
+static float *give_jitter_plane(LampRen *lar, int xs, int ys)
+{
+ int tot;
+
+ tot= lar->ray_totsamp;
+
if(lar->ray_samp_type & LA_SAMP_JITTER) {
/* made it threadsafe */
if(ys & 1) {
if(lar->xold1!=xs || lar->yold1!=ys) {
- jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, BLI_frand(), BLI_frand());
+ jitter_plane_offset(lar->jitter, lar->jitter+2*tot, tot, lar->area_size, lar->area_sizey, BLI_thread_frand(1), BLI_thread_frand(1));
lar->xold1= xs; lar->yold1= ys;
}
return lar->jitter+2*tot;
}
else {
if(lar->xold2!=xs || lar->yold2!=ys) {
- jitter_plane_offset(lar->jitter, lar->jitter+4*tot, tot, lar->area_size, lar->area_sizey, BLI_frand(), BLI_frand());
+ jitter_plane_offset(lar->jitter, lar->jitter+4*tot, tot, lar->area_size, lar->area_sizey, BLI_thread_frand(0), BLI_thread_frand(0));
lar->xold2= xs; lar->yold2= ys;
}
return lar->jitter+4*tot;
@@ -1907,11 +1882,15 @@ static void DS_energy(float *sphere, int tot, float *vec)
}
-static void DistributedSpherical(float *sphere, int tot, int iter)
+/* called from convertBlenderScene.c */
+/* creates an equally distributed spherical sample pattern */
+void init_ao_sphere(float *sphere, int tot, int iter)
{
float *fp;
int a;
+ BLI_srandom(tot);
+
/* init */
fp= sphere;
for(a=0; a<tot; a++, fp+= 3) {
@@ -1948,56 +1927,51 @@ static float *threadsafe_table_sphere(int test, int xs, int ys)
static float *sphere_sampler(int type, int resol, int xs, int ys)
{
- static float sphere[2*3*256];
- float *sphere1;
int tot;
float *vec;
- if(resol>16) return sphere;
+ if(resol>16) resol= 16;
tot= 2*resol*resol;
if (type & WO_AORNDSMP) {
+ static float sphere[2*3*256];
int a;
- /* total random sampling */
+ /* total random sampling. NOT THREADSAFE! (should be removed, is not useful) */
vec= sphere;
for (a=0; a<tot; a++, vec+=3) {
RandomSpherical(vec);
}
+
+ return sphere;
}
else {
- static int last_distr= 0;
+ float *sphere;
float cosf, sinf, cost, sint;
float ang, *vec1;
int a;
- if(last_distr!=resol) {
- last_distr= resol;
- DistributedSpherical(sphere, tot, 16);
- }
-
- sphere1= threadsafe_table_sphere(1, xs, ys);
- if(sphere1==NULL) {
- sphere1= threadsafe_table_sphere(0, xs, ys);
+ sphere= threadsafe_table_sphere(1, xs, ys); // returns table if xs and ys were equal to last call
+ if(sphere==NULL) {
+ sphere= threadsafe_table_sphere(0, xs, ys);
// random rotation
- ang= BLI_frand();
+ ang= BLI_thread_frand(ys & 1);
sinf= sin(ang); cosf= cos(ang);
- ang= BLI_frand();
+ ang= BLI_thread_frand(ys & 1);
sint= sin(ang); cost= cos(ang);
- vec= sphere;
- vec1= sphere1;
+ vec= R.wrld.aosphere;
+ vec1= sphere;
for (a=0; a<tot; a++, vec+=3, vec1+=3) {
vec1[0]= cost*cosf*vec[0] - sinf*vec[1] + sint*cosf*vec[2];
vec1[1]= cost*sinf*vec[0] + cosf*vec[1] + sint*sinf*vec[2];
vec1[2]= -sint*vec[0] + cost*vec[2];
}
}
- return sphere1;
+ return sphere;
}
- return sphere;
}
@@ -2157,7 +2131,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
else shadfac[3]= 1.0; // 1.0=full light
fac= 0.0;
- jitlamp= jitter_plane(lar, floor(shi->xs+0.5), floor(shi->ys+0.5));
+ jitlamp= give_jitter_plane(lar, floor(shi->xs+0.5), floor(shi->ys+0.5));
a= lar->ray_totsamp;
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index b6f712c0212..9f0cf4f23f3 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -2536,8 +2536,11 @@ static int do_renderlineDA(void *poin)
float fcol[4], *acol=NULL, *rb1, *rb2, *rb3;
long *rd= rl->rd;
int zbuf, samp, curmask, face, mask, fullmask;
- int b, x, full_osa;
-
+ int b, x, full_osa, seed;
+
+ /* we set per pixel a fixed seed, for random AO and shadow samples */
+ seed= (R.ystart + rl->y + R.afmy)*R.r.xsch + R.xstart + R.afmx;
+
fullmask= (1<<R.osa)-1;
rb1= rl->rb1;
rb2= rl->rb2;
@@ -2549,7 +2552,9 @@ static int do_renderlineDA(void *poin)
}
for(x=0; x<R.rectx; x++, rd++) {
-
+
+ BLI_thread_srandom(rl->y & 1, seed+x);
+
ps= (PixStr *)(*rd);
mask= 0;
@@ -2829,7 +2834,10 @@ static int do_renderline(void *poin)
struct renderline *rl= poin;
float *fcol= rl->rowbuf;
float *acol=NULL;
- int x, *rz, *rp;
+ int x, *rz, *rp, seed;
+
+ /* we set per pixel a fixed seed, for random AO and shadow samples */
+ seed= (R.ystart + rl->y + R.afmy)*R.r.xsch + R.xstart + R.afmx;
if(R.flag & R_ZTRA) { /* zbuf tra */
abufsetrow(rl->acol, rl->ys);
@@ -2837,6 +2845,8 @@ static int do_renderline(void *poin)
}
for(x=0, rz= rl->rz, rp= rl->rp; x<R.rectx; x++, rz++, rp++, fcol+=4) {
+ BLI_thread_srandom(rl->ys & 1, seed+x);
+
shadepixel_sky((float)x, rl->y, *rz, *rp, 0, fcol);
if(acol) {
if(acol[3]!=0.0) addAlphaOverFloat(fcol, acol);
@@ -2848,7 +2858,7 @@ static int do_renderline(void *poin)
scanlinehalo(rl->rz, rl->rowbuf, rl->ys);
}
- transferColourBufferToOutput(rl->rowbuf, rl->y);
+ transferColourBufferToOutput(rl->rowbuf, rl->ys);
if(R.rectftot) {
memcpy(R.rectftot + 4*rl->ys*R.rectx, rl->rowbuf, 4*sizeof(float)*R.rectx);
diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c
index bc9aceb9ad5..b6fb272036e 100644
--- a/source/blender/renderconverter/intern/convertBlenderScene.c
+++ b/source/blender/renderconverter/intern/convertBlenderScene.c
@@ -1540,7 +1540,7 @@ static void area_lamp_vectors(LampRen *lar)
}
/* If lar takes more lamp data, the decoupling will be better. */
-void RE_add_render_lamp(Object *ob, int doshadbuf)
+void RE_add_render_lamp(Object *ob, int actual_render)
{
Lamp *la;
LampRen *lar, **temp;
@@ -1715,13 +1715,17 @@ void RE_add_render_lamp(Object *ob, int doshadbuf)
}
}
- /* yafray: shadowbuffers only needed for internal render */
- if (R.r.renderer==R_INTERN)
- {
- if( (R.r.mode & R_SHADOW) && (lar->mode & LA_SHAD) && (la->type==LA_SPOT) && doshadbuf ) {
- /* Per lamp, one shadow buffer is made. */
- Mat4CpyMat4(mat, ob->obmat);
- RE_initshadowbuf(lar, mat); // mat is altered
+ /* yafray: shadowbuffers and jitter only needed for internal render */
+ if (actual_render && R.r.renderer==R_INTERN) {
+ if(R.r.mode & R_SHADOW) {
+ if (la->type==LA_SPOT && (lar->mode & LA_SHAD) ) {
+ /* Per lamp, one shadow buffer is made. */
+ Mat4CpyMat4(mat, ob->obmat);
+ RE_initshadowbuf(lar, mat); // mat is altered
+ }
+ else if(la->type==LA_AREA && (lar->mode & LA_SHAD_RAY) ) {
+ init_jitter_plane(lar);
+ }
}
}
@@ -2300,6 +2304,10 @@ void RE_freeRotateBlenderScene(void)
end_render_textures();
end_render_materials();
end_radio_render();
+ if(R.wrld.aosphere) {
+ MEM_freeN(R.wrld.aosphere);
+ R.wrld.aosphere= NULL;
+ }
R.totvlak=R.totvert=R.totlamp=R.tothalo= 0;
}
@@ -2484,6 +2492,10 @@ void RE_rotateBlenderScene(void)
}
init_render_world(); /* do first, because of ambient. also requires R.osa set correct */
+ if( (R.wrld.mode & WO_AMB_OCC) && (R.r.mode & R_RAYTRACE) ) {
+ R.wrld.aosphere= MEM_mallocN(2*3*R.wrld.aosamp*R.wrld.aosamp*sizeof(float), "AO sphere");
+ init_ao_sphere(R.wrld.aosphere, R.wrld.aosamp*R.wrld.aosamp, 16);
+ }
init_render_textures();
init_render_materials();
diff --git a/source/blender/src/previewrender.c b/source/blender/src/previewrender.c
index 622e1e4bbf4..5c0902ab5b9 100644
--- a/source/blender/src/previewrender.c
+++ b/source/blender/src/previewrender.c
@@ -1140,7 +1140,7 @@ void BIF_previewrender(SpaceButs *sbuts)
init_render_world();
init_render_textures(); /* do not do it twice!! (brightness) */
R.totlamp= 0;
- RE_add_render_lamp(ob, 0); /* 0=no shadbuf */
+ RE_add_render_lamp(ob, 0); /* 0=no shadbuf or tables */
lar= R.la[0];
/* exceptions: */