forked from bartvdbraak/blender
Tweak for Speed vector calculus for Ztransp render layer; it used to mask
out moving transparent pixels by checking for alpha>0.95, now it also checks the solid layer (if present), and if there's no solid face in a pixel, the speed vector gets also added and used for transparent pixels. This solves the 'ugly' hard outlines for vectorblur of moving hair. Before: http://www.blender.org/bf/h1.jpg After: http://www.blender.org/bf/h2.jpg
This commit is contained in:
parent
8ab274ee30
commit
2c1a328f58
@ -3117,6 +3117,7 @@ static void calculate_speedvectors(Render *re, float *vectors, int startvert, in
|
||||
}
|
||||
|
||||
speed= RE_vertren_get_winspeed(re, ver, 1);
|
||||
/* note; in main vecblur loop speedvec is negated again */
|
||||
if(step) {
|
||||
speed[2]= -zco[0];
|
||||
speed[3]= -zco[1];
|
||||
@ -3125,10 +3126,7 @@ static void calculate_speedvectors(Render *re, float *vectors, int startvert, in
|
||||
speed[0]= zco[0];
|
||||
speed[1]= zco[1];
|
||||
}
|
||||
|
||||
//printf("speed %d %f %f\n", a, speed[0], speed[1]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* makes copy per object of all vectors */
|
||||
|
@ -2749,10 +2749,8 @@ static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
|
||||
|
||||
static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl)
|
||||
{
|
||||
|
||||
/* speed vector exception... if solid render was done, sky pixels are set to zero already */
|
||||
/* for all pixels with alpha zero, we re-initialize speed again then */
|
||||
if(rl->layflag & SCE_LAY_SOLID) {
|
||||
float *fp, *col;
|
||||
int a;
|
||||
|
||||
@ -2769,7 +2767,6 @@ static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* osa version */
|
||||
static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeResult *shr)
|
||||
@ -3140,6 +3137,7 @@ void zbufshadeDA_tile(RenderPart *pa)
|
||||
int x;
|
||||
|
||||
if(rl->passflag & SCE_PASS_VECTOR)
|
||||
if(rl->layflag & SCE_LAY_SOLID)
|
||||
reset_sky_speedvectors(pa, rl);
|
||||
|
||||
/* swap for live updates */
|
||||
@ -3252,6 +3250,7 @@ void zbufshade_tile(RenderPart *pa)
|
||||
int x;
|
||||
|
||||
if(addpassflag & SCE_PASS_VECTOR)
|
||||
if(rl->layflag & SCE_LAY_SOLID)
|
||||
reset_sky_speedvectors(pa, rl);
|
||||
|
||||
/* swap for live updates */
|
||||
|
@ -2236,7 +2236,7 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
|
||||
dm= rectmove;
|
||||
dvec1= vecbufrect;
|
||||
for(x=xsize*ysize; x>0; x--, dm++, dvec1+=4) {
|
||||
if(dvec1[0]!=0.0f || dvec1[1]!=0.0f)
|
||||
if(dvec1[0]!=0.0f || dvec1[1]!=0.0f || dvec1[2]!=0.0f || dvec1[3]!=0.0f)
|
||||
*dm= 255;
|
||||
}
|
||||
|
||||
@ -2484,9 +2484,10 @@ static void zbuffer_abuf(RenderPart *pa, APixstr *APixbuf, ListBase *apsmbase, u
|
||||
}
|
||||
|
||||
/* different rules for speed in transparent pass... */
|
||||
/* if speed is zero or alpha small, we clear winspeed if it's initialized to max still */
|
||||
|
||||
static void add_transp_speed(RenderLayer *rl, int offset, float *speed, float alpha)
|
||||
/* speed pointer NULL = sky, we clear */
|
||||
/* else if either alpha is full or no solid was filled in: copy speed */
|
||||
/* else fill in minimum speed */
|
||||
static void add_transp_speed(RenderLayer *rl, int offset, float *speed, float alpha, long *rdrect)
|
||||
{
|
||||
RenderPass *rpass;
|
||||
|
||||
@ -2494,16 +2495,28 @@ static void add_transp_speed(RenderLayer *rl, int offset, float *speed, float al
|
||||
if(rpass->passtype==SCE_PASS_VECTOR) {
|
||||
float *fp= rpass->rect + 4*offset;
|
||||
|
||||
if(speed && alpha>0.95f) {
|
||||
QUATCOPY(fp, speed);
|
||||
}
|
||||
else {
|
||||
if(speed==NULL) {
|
||||
/* clear */
|
||||
if(fp[0]==PASS_VECTOR_MAX) fp[0]= 0.0f;
|
||||
if(fp[1]==PASS_VECTOR_MAX) fp[1]= 0.0f;
|
||||
if(fp[2]==PASS_VECTOR_MAX) fp[2]= 0.0f;
|
||||
if(fp[3]==PASS_VECTOR_MAX) fp[3]= 0.0f;
|
||||
}
|
||||
else if(rdrect==NULL || rdrect[offset]==0 || alpha>0.95f) {
|
||||
QUATCOPY(fp, speed);
|
||||
}
|
||||
else {
|
||||
/* add minimum speed in pixel */
|
||||
if( (ABS(speed[0]) + ABS(speed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
|
||||
fp[0]= speed[0];
|
||||
fp[1]= speed[1];
|
||||
}
|
||||
if( (ABS(speed[2]) + ABS(speed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
|
||||
fp[2]= speed[2];
|
||||
fp[3]= speed[3];
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2636,7 +2649,8 @@ void zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass)
|
||||
APixstr *ap, *aprect, *apn;
|
||||
ListBase apsmbase={NULL, NULL};
|
||||
ShadeResult samp_shr[16];
|
||||
float fac, alpha[32], *passrect= pass;
|
||||
float fac, sampalpha, *passrect= pass;
|
||||
long *rdrect;
|
||||
int x, y, crop=0, a, zrow[MAX_ZROW][3], totface;
|
||||
int sval, addpassflag, offs= 0, od, addzbuf;
|
||||
|
||||
@ -2663,24 +2677,22 @@ void zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass)
|
||||
addpassflag= rl->passflag & ~(SCE_PASS_Z|SCE_PASS_COMBINED);
|
||||
addzbuf= rl->passflag & SCE_PASS_Z;
|
||||
|
||||
/* alpha LUT */
|
||||
if(R.osa) {
|
||||
fac= (1.0/(float)R.osa);
|
||||
for(a=0; a<=R.osa; a++) {
|
||||
alpha[a]= (float)a*fac;
|
||||
}
|
||||
}
|
||||
if(R.osa)
|
||||
sampalpha= 1.0f/(float)R.osa;
|
||||
else
|
||||
sampalpha= 1.0f;
|
||||
|
||||
/* fill the Apixbuf */
|
||||
zbuffer_abuf(pa, APixbuf, &apsmbase, rl->lay);
|
||||
aprect= APixbuf;
|
||||
rdrect= pa->rectdaps;
|
||||
|
||||
/* filtered render, for now we assume only 1 filter size */
|
||||
if(pa->crop) {
|
||||
crop= 1;
|
||||
passrect+= 4*(pa->rectx + 1);
|
||||
aprect+= pa->rectx + 1;
|
||||
offs= pa->rectx + 1;
|
||||
passrect+= 4*offs;
|
||||
aprect+= offs;
|
||||
}
|
||||
|
||||
/* init scanline updates */
|
||||
@ -2701,7 +2713,7 @@ void zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass)
|
||||
|
||||
if(ap->p[0]==NULL) {
|
||||
if(addpassflag & SCE_PASS_VECTOR)
|
||||
add_transp_speed(rl, od, NULL, 0.0f);
|
||||
add_transp_speed(rl, od, NULL, 0.0f, rdrect);
|
||||
}
|
||||
else {
|
||||
/* sort in z */
|
||||
@ -2736,7 +2748,7 @@ void zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass)
|
||||
add_transp_passes(rl, od, &shpi.shr, 1.0f);
|
||||
|
||||
if(addpassflag & SCE_PASS_VECTOR)
|
||||
add_transp_speed(rl, od, shpi.shr.winspeed, pass[3]);
|
||||
add_transp_speed(rl, od, shpi.shr.winspeed, pass[3], rdrect);
|
||||
|
||||
if(addzbuf)
|
||||
if(pa->rectz[od]>zrow[0][0])
|
||||
@ -2772,7 +2784,7 @@ void zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass)
|
||||
if(pass[3]>=0.999) break;
|
||||
}
|
||||
if(addpassflag & SCE_PASS_VECTOR)
|
||||
add_transp_speed(rl, od, shpi.shr.winspeed, pass[3]);
|
||||
add_transp_speed(rl, od, shpi.shr.winspeed, pass[3], rdrect);
|
||||
}
|
||||
else {
|
||||
/* for each mask-sample we alpha-under colors. then in end it's added using filter */
|
||||
@ -2791,23 +2803,17 @@ void zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pass)
|
||||
add_filt_fmask(1<<a, samp_shr[a].combined, pass, rr->rectx);
|
||||
|
||||
if(addpassflag)
|
||||
add_transp_passes(rl, od, samp_shr+a, alpha[1]);
|
||||
add_transp_passes(rl, od, samp_shr+a, sampalpha);
|
||||
}
|
||||
|
||||
if(addpassflag & SCE_PASS_VECTOR) {
|
||||
fac= 0.0f;
|
||||
for(a=0; a<R.osa; a++)
|
||||
fac+= samp_shr[a].combined[3];
|
||||
fac*= alpha[1];
|
||||
add_transp_speed(rl, od, samp_shr[0].winspeed, fac);
|
||||
add_transp_speed(rl, od, samp_shr[0].winspeed, fac*sampalpha, rdrect);
|
||||
}
|
||||
}
|
||||
}
|
||||
//if(R.osa && R.do_gamma) {
|
||||
// pass[0]= invGammaCorrect(pass[0]);
|
||||
// pass[1]= invGammaCorrect(pass[1]);
|
||||
// pass[2]= invGammaCorrect(pass[2]);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user