features & fixes:

- Enabled Groups to execute in Compositor. They were ignored still.
  Note; inside of groups nothing is cached, so a change of a group input
  will recalculate it fully. This is needed because groups are linked
  data (instances use same internal nodes).

- Made Composit node "Viewer" display correctly input for images with
  1/2/3/4 channels.

- Added pass rendering, tested now with only regular Materials. For
  Material nodes this is quite more complex... since they cannot be
  easily separated in passes (each Material does a full shade)
  In this commit all pass render is disabled though, will continue work on
  that later.
  Sneak preview: http://www.blender.org/bf/rt.jpg  (temporal image)

- What did remain is the 'Normal' pass output. Normal works very nice for
  relighting effects. Use the "Normal Node" to define where more or less
  light should be. (Use "Value Map" node to tweak influence of the
  Normal node 'dot' output.)

- EVIL bug fix: I've spend almost a day finding it... when combining AO and
  mirror render, the event queue was totally screwing up... two things not
  related at all!
  Found out error was in ray-mirror code, which was using partially
  uninitialized 'ShadeInput' data to pass on to render code.

- Another fix; made sure that while thread render, the threads don't get
  events, only the main program will do. Might fix issues reported by
  people on linux/windows.
This commit is contained in:
2006-02-02 17:54:22 +00:00
parent ccbc32abed
commit f493e8ed2e
21 changed files with 982 additions and 4044 deletions

View File

@@ -133,6 +133,11 @@ void RE_freeN(void *poin)
/* ********************** */
static int g_break= 0;
static int thread_break(void)
{
return g_break;
}
/* default callbacks, set in each new render */
static void result_nothing(RenderResult *rr) {}
@@ -148,9 +153,14 @@ static void free_render_result(RenderResult *res)
while(res->layers.first) {
RenderLayer *rl= res->layers.first;
if(rl->rectf) RE_freeN(rl->rectf);
if(rl->rectz) RE_freeN(rl->rectz);
if(rl->rectvec) RE_freeN(rl->rectvec);
while(rl->passes.first) {
RenderPass *rpass= rl->passes.first;
RE_freeN(rpass->rect);
BLI_remlink(&rl->passes, rpass);
RE_freeN(rpass);
}
BLI_remlink(&res->layers, rl);
RE_freeN(rl);
}
@@ -165,6 +175,25 @@ static void free_render_result(RenderResult *res)
RE_freeN(res);
}
static void render_layer_add_pass(RenderLayer *rl, int rectsize, int passtype, char *mallocstr)
{
RenderPass *rpass= MEM_mallocN(sizeof(RenderPass), mallocstr);
BLI_addtail(&rl->passes, rpass);
rpass->passtype= passtype;
rpass->rect= MEM_callocN(sizeof(float)*rectsize, mallocstr);
}
float *RE_RenderLayerGetPass(RenderLayer *rl, int passtype)
{
RenderPass *rpass;
for(rpass=rl->passes.first; rpass; rpass= rpass->next)
if(rpass->passtype== passtype)
return rpass->rect;
return NULL;
}
/* called by main render as well for parts */
/* will read info from Render *re to define layers */
/* called in threads */
@@ -205,10 +234,25 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
rl->passflag= srl->passflag;
rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "layer float rgba");
if(srl->passflag & SCE_PASS_Z)
rl->rectz= RE_callocN(rectx*recty*sizeof(float), "layer float Z");
render_layer_add_pass(rl, rectx*recty, SCE_PASS_Z, "Layer float Z");
if(srl->passflag & SCE_PASS_VECTOR)
rl->rectvec= RE_callocN(rectx*recty*sizeof(float)*2, "layer float Vector");
render_layer_add_pass(rl, rectx*recty*2, SCE_PASS_VECTOR, "layer float Vector");
if(srl->passflag & SCE_PASS_NORMAL)
render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_NORMAL, "layer float Normal");
if(srl->passflag & SCE_PASS_RGBA)
render_layer_add_pass(rl, rectx*recty*4, SCE_PASS_RGBA, "layer float Color");
if(srl->passflag & SCE_PASS_DIFFUSE)
render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_DIFFUSE, "layer float Diffuse");
if(srl->passflag & SCE_PASS_SPEC)
render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_SPEC, "layer float Spec");
if(srl->passflag & SCE_PASS_SHADOW)
render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_SHADOW, "layer float Shadow");
if(srl->passflag & SCE_PASS_AO)
render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_AO, "layer float AO");
if(srl->passflag & SCE_PASS_RAY)
render_layer_add_pass(rl, rectx*recty*3, SCE_PASS_RAY, "layer float Mirror");
}
/* previewrender and envmap don't do layers, so we make a default one */
@@ -217,13 +261,11 @@ static RenderResult *new_render_result(Render *re, rcti *partrct, int crop)
BLI_addtail(&rr->layers, rl);
rl->rectf= RE_callocN(rectx*recty*sizeof(float)*4, "prev/env float rgba");
rl->rectz= RE_callocN(rectx*recty*sizeof(float), "prev/env float Z");
/* note, this has to be in sync with scene.c */
rl->lay= (1<<20) -1;
rl->layflag= 0x7FFF; /* solid ztra halo strand */
rl->passflag= SCE_PASS_COMBINED|SCE_PASS_Z;
rl->passflag= SCE_PASS_COMBINED;
}
return rr;
@@ -277,18 +319,30 @@ static void do_merge_tile(RenderResult *rr, RenderResult *rrpart, float *target,
static void merge_render_result(RenderResult *rr, RenderResult *rrpart)
{
RenderLayer *rl, *rlp;
RenderPass *rpass, *rpassp;
for(rl= rr->layers.first, rlp= rrpart->layers.first; rl && rlp; rl= rl->next, rlp= rlp->next) {
/* combined */
if(rl->rectf && rlp->rectf)
do_merge_tile(rr, rrpart, rl->rectf, rlp->rectf, 4);
/* z */
if(rl->rectz && rlp->rectz)
do_merge_tile(rr, rrpart, rl->rectz, rlp->rectz, 1);
/* vector */
if(rl->rectvec && rlp->rectvec)
do_merge_tile(rr, rrpart, rl->rectvec, rlp->rectvec, 2);
/* passes are allocated in sync */
for(rpass= rl->passes.first, rpassp= rlp->passes.first; rpass && rpassp; rpass= rpass->next, rpassp= rpassp->next) {
switch(rpass->passtype) {
case SCE_PASS_Z:
do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 1);
break;
case SCE_PASS_VECTOR:
do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 2);
break;
case SCE_PASS_RGBA:
do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 4);
break;
default:
do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, 3);
}
}
}
}
@@ -337,7 +391,7 @@ void RE_GetResultImage(Render *re, RenderResult *rr)
if(rr->rectf==NULL)
rr->rectf= rl->rectf;
if(rr->rectz==NULL)
rr->rectz= rl->rectz;
rr->rectz= RE_RenderLayerGetPass(rl, SCE_PASS_Z);
}
}
}
@@ -683,11 +737,12 @@ static void threaded_tile_processor(Render *re)
/* assuming no new data gets added to dbase... */
R= *re;
/* set threadsafety */
R.test_break= thread_break;
malloc_lock = SDL_CreateMutex();
while(rendering) {
/* I noted that test_break() in a thread doesn't make ghost send ESC */
if(BLI_available_threads(&threads) && !re->test_break()) {
pa= find_nicest_part(re);
if(pa) {
@@ -728,12 +783,14 @@ static void threaded_tile_processor(Render *re)
drawtimer= 0;
/* on break, wait for all slots to get freed */
if(re->test_break() && BLI_available_threads(&threads)==maxthreads)
if( (g_break=re->test_break()) && BLI_available_threads(&threads)==maxthreads)
rendering= 0;
}
/* restore threadsafety */
if(malloc_lock) SDL_DestroyMutex(malloc_lock); malloc_lock= NULL;
g_break= 0;
BLI_end_threads(&threads);
freeparts(re);

View File

@@ -212,24 +212,18 @@ void add_filt_fmask(unsigned int mask, float *col, float *rowbuf, int row_w)
}
}
/* filtered adding to scanlines */
void add_filt_fmask_alphaunder(unsigned int mask, float *col, float *rowbuf, int row_w)
void add_filt_fmask_pixsize(unsigned int mask, float *in, float *rowbuf, int row_w, int pixsize)
{
/* calc the value of mask */
float **fmask1= R.samples->fmask1, **fmask2=R.samples->fmask2;
float *rb1, *rb2, *rb3;
float val, r, g, b, al, acol[4];
float val;
unsigned int a, maskand, maskshift;
int j;
int i, j;
r= col[0];
g= col[1];
b= col[2];
al= col[3];
rb2= rowbuf-4;
rb3= rb2-4*row_w;
rb1= rb2+4*row_w;
rb2= rowbuf-pixsize;
rb3= rb2-pixsize*row_w;
rb1= rb2+pixsize*row_w;
maskand= (mask & 255);
maskshift= (mask >>8);
@@ -240,40 +234,30 @@ void add_filt_fmask_alphaunder(unsigned int mask, float *col, float *rowbuf, int
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
acol[0]= val*r;
acol[1]= val*g;
acol[2]= val*b;
acol[3]= val*al;
addAlphaUnderFloat(rb1, acol);
for(i= 0; i<pixsize; i++)
rb1[i]+= val*in[i];
}
a+=3;
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
acol[0]= val*r;
acol[1]= val*g;
acol[2]= val*b;
acol[3]= val*al;
addAlphaUnderFloat(rb2, acol);
for(i= 0; i<pixsize; i++)
rb2[i]+= val*in[i];
}
a+=3;
val= *(fmask1[a] +maskand) + *(fmask2[a] +maskshift);
if(val!=0.0) {
acol[0]= val*r;
acol[1]= val*g;
acol[2]= val*b;
acol[3]= val*al;
addAlphaUnderFloat(rb3, acol);
for(i= 0; i<pixsize; i++)
rb3[i]+= val*in[i];
}
rb1+= 4;
rb2+= 4;
rb3+= 4;
rb1+= pixsize;
rb2+= pixsize;
rb3+= pixsize;
}
}
/* ------------------------------------------------------------------------- */
void addalphaAddFloat(float *dest, float *source)
{

View File

@@ -1516,7 +1516,7 @@ static void color_combine(float *result, float fac1, float fac2, float *col1, fl
#endif
/* the main recursive tracer itself */
static void traceray(short depth, float *start, float *vec, float *col, VlakRen *vlr, int mask, int osatex, int traflag)
static void traceray(ShadeInput *origshi, short depth, float *start, float *vec, float *col, VlakRen *vlr, int traflag)
{
ShadeInput shi;
ShadeResult shr;
@@ -1533,9 +1533,13 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
if( d3dda(&isec) ) {
shi.mask= mask;
shi.osatex= osatex;
shi.mask= origshi->mask;
shi.osatex= origshi->osatex;
shi.depth= 1; // only now to indicate tracing
shi.thread= origshi->thread;
shi.xs= origshi->xs;
shi.ys= origshi->ys;
shi.do_preview= 0;
shade_ray(&isec, &shi, &shr);
@@ -1559,10 +1563,10 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
refraction(refract, shi.vn, shi.view, shi.ang);
}
traflag |= RAY_TRA;
traceray(depth-1, shi.co, refract, tracol, shi.vlr, shi.mask, osatex, traflag ^ RAY_TRAFLIP);
traceray(origshi, depth-1, shi.co, refract, tracol, shi.vlr, traflag ^ RAY_TRAFLIP);
}
else
traceray(depth-1, shi.co, shi.view, tracol, shi.vlr, shi.mask, osatex, 0);
traceray(origshi, depth-1, shi.co, shi.view, tracol, shi.vlr, 0);
f= shr.alpha; f1= 1.0-f;
fr= 1.0+ shi.mat->filter*(shi.r-1.0);
@@ -1591,7 +1595,7 @@ static void traceray(short depth, float *start, float *vec, float *col, VlakRen
float mircol[4];
reflection(ref, shi.vn, shi.view, NULL);
traceray(depth-1, shi.co, ref, mircol, shi.vlr, shi.mask, osatex, 0);
traceray(origshi, depth-1, shi.co, ref, mircol, shi.vlr, 0);
f1= 1.0-f;
@@ -1767,10 +1771,10 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
if(shi->mat->mode & MA_RAYTRANSP) {
refraction(refract, shi->vn, shi->view, shi->ang);
traceray(shi->mat->ray_depth_tra, shi->co, refract, tracol, shi->vlr, shi->mask, 0, RAY_TRA|RAY_TRAFLIP);
traceray(shi, shi->mat->ray_depth_tra, shi->co, refract, tracol, shi->vlr, RAY_TRA|RAY_TRAFLIP);
}
else
traceray(shi->mat->ray_depth_tra, shi->co, shi->view, tracol, shi->vlr, shi->mask, 0, 0);
traceray(shi, shi->mat->ray_depth_tra, shi->co, shi->view, tracol, shi->vlr, 0);
f= shr->alpha; f1= 1.0-f;
fr= 1.0+ shi->mat->filter*(shi->r-1.0);
@@ -1796,7 +1800,7 @@ void ray_trace(ShadeInput *shi, ShadeResult *shr)
else
reflection(vec, shi->vn, shi->view, NULL);
traceray(shi->mat->ray_depth, shi->co, vec, mircol, shi->vlr, shi->mask, shi->osatex, 0);
traceray(shi, shi->mat->ray_depth, shi->co, vec, mircol, shi->vlr, 0);
f= i*fr*(1.0-shr->spec[0]); f1= 1.0-i;
shr->diff[0]= f*mircol[0] + f1*shr->diff[0];
@@ -2073,7 +2077,7 @@ void ray_ao(ShadeInput *shi, float *shadfac)
bias= 0.0;
nrm= shi->facenor;
}
vec= sphere_sampler(R.wrld.aomode, R.wrld.aosamp, shi->thread, shi->xs, shi->ys);
// warning: since we use full sphere now, and dotproduct is below, we do twice as much

File diff suppressed because it is too large Load Diff

View File

@@ -2049,7 +2049,7 @@ static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, i
if(vlr->flag & R_FULL_OSA) {
for(a=0; a<R.osa; a++) {
if(mask & (1<<a)) {
shadepixel(pa, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, &shr, rco);
shadepixel(pa, x+R.jit[a][0], y+R.jit[a][1], z, facenr, 1<<a, &shr, rco, 0);
accumcol[0]+= shr.combined[0];
accumcol[1]+= shr.combined[1];
accumcol[2]+= shr.combined[2];
@@ -2067,12 +2067,12 @@ static void shadetrapixel(RenderPart *pa, float x, float y, int z, int facenr, i
int b= R.samples->centmask[mask];
x= x+R.samples->centLut[b & 15];
y= y+R.samples->centLut[b>>4];
shadepixel(pa, x, y, z, facenr, mask, &shr, rco);
shadepixel(pa, x, y, z, facenr, mask, &shr, rco, 0);
QUATCOPY(fcol, shr.combined);
}
}
else {
shadepixel(pa, x, y, z, facenr, mask, &shr, rco);
shadepixel(pa, x, y, z, facenr, mask, &shr, rco, 0);
QUATCOPY(fcol, shr.combined);
}
}
@@ -2238,15 +2238,21 @@ void zbuffer_transp_shade(RenderPart *pa, float *pass, unsigned int lay, short l
/* uses part zbuffer values to convert into distances from camera in renderlayer */
void convert_zbuf_to_distbuf(RenderPart *pa, RenderLayer *rl)
{
RenderPass *rpass;
float *rectzf, zco;
int a, *rectz, ortho= R.r.mode & R_ORTHO;
if(pa->rectz==NULL) return;
if(rl->rectz==NULL) {
for(rpass= rl->passes.first; rpass; rpass= rpass->next)
if(rpass->passtype==SCE_PASS_Z)
break;
if(rpass==NULL) {
printf("called convert zbuf wrong...\n");
return;
}
rectzf= rl->rectz;
rectzf= rpass->rect;
rectz= pa->rectz;
for(a=pa->rectx*pa->recty; a>0; a--, rectz++, rectzf++) {