diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_rand.h | 18 | ||||
-rw-r--r-- | source/blender/blenlib/intern/rand.c | 40 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_world_types.h | 4 | ||||
-rw-r--r-- | source/blender/render/extern/include/render.h | 7 | ||||
-rw-r--r-- | source/blender/render/intern/source/initrender.c | 8 | ||||
-rw-r--r-- | source/blender/render/intern/source/ray.c | 134 | ||||
-rw-r--r-- | source/blender/render/intern/source/rendercore.c | 20 | ||||
-rw-r--r-- | source/blender/renderconverter/intern/convertBlenderScene.c | 28 | ||||
-rw-r--r-- | source/blender/src/previewrender.c | 2 |
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: */ |