Revision: 16439
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16439
Author:   blendix
Date:     2008-09-09 19:27:01 +0200 (Tue, 09 Sep 2008)

Log Message:
-----------

Fix for bug #12132: vector blur with fast moving objects does
not give a smooth fallof. there's no correct fix possible due
to a lack of information, but this manually adds a smoother
falloff, overestimating the contribution of foregroud pixels
instead of becoming transparent.

Modified Paths:
--------------
    trunk/blender/source/blender/render/intern/source/zbuf.c

Modified: trunk/blender/source/blender/render/intern/source/zbuf.c
===================================================================
--- trunk/blender/source/blender/render/intern/source/zbuf.c    2008-09-09 
16:40:36 UTC (rev 16438)
+++ trunk/blender/source/blender/render/intern/source/zbuf.c    2008-09-09 
17:27:01 UTC (rev 16439)
@@ -2981,10 +2981,11 @@
 {
        ZSpan zspan;
        DrawBufPixel *rectdraw, *dr;
-       static float jit[16][2];
+       static float jit[256][2];
        float v1[3], v2[3], v3[3], v4[3], fx, fy;
-       float *rectvz, *dvz, *dimg, *dvec1, *dvec2, *dz, *dz1, *dz2, *rectz, 
*minvecbufrect= NULL;
-       float maxspeedsq= (float)nbd->maxspeed*nbd->maxspeed;
+       float *rectvz, *dvz, *dimg, *dvec1, *dvec2, *dz, *dz1, *dz2, *rectz;
+       float *minvecbufrect= NULL, *rectweight, *rw, *rectmax, *rm, *ro;
+       float maxspeedsq= (float)nbd->maxspeed*nbd->maxspeed, totfac;
        int y, x, step, maxspeed=nbd->maxspeed, samples= nbd->samples;
        int tsktsk= 0;
        static int firsttime= 1;
@@ -3003,6 +3004,9 @@
        rectmove= MEM_mapallocN(xsize*ysize, "rectmove");
        rectdraw= MEM_mapallocN(sizeof(DrawBufPixel)*xsize*ysize, "rect draw");
        zspan.rectp= (int *)rectdraw;
+
+       rectweight= MEM_mapallocN(sizeof(float)*xsize*ysize, "rect weight");
+       rectmax= MEM_mapallocN(sizeof(float)*xsize*ysize, "rect max");
        
        /* debug... check if PASS_VECTOR_MAX still is in buffers */
        dvec1= vecbufrect;
@@ -3142,7 +3146,7 @@
        dm= rectmove;
        dvec1= vecbufrect;
        for(x=xsize*ysize; x>0; x--, dm++, dvec1+=4) {
-               if(dvec1[0]!=0.0f || dvec1[1]!=0.0f || dvec1[2]!=0.0f || 
dvec1[3]!=0.0f)
+               if((dvec1[0]!=0.0f || dvec1[1]!=0.0f || dvec1[2]!=0.0f || 
dvec1[3]!=0.0f))
                        *dm= 255;
        }
        
@@ -3151,9 +3155,12 @@
        /* has to become static, the init-jit calls a random-seed, screwing up 
texture noise node */
        if(firsttime) {
                firsttime= 0;
-               BLI_initjit(jit[0], 16);
+               BLI_initjit(jit[0], 256);
        }
        
+       memset(newrect, 0, sizeof(float)*xsize*ysize*4);
+       totfac= 0.0f;
+
        /* accumulate */
        samples/= 2;
        for(step= 1; step<=samples; step++) {
@@ -3161,7 +3168,7 @@
                int side;
                
                for(side=0; side<2; side++) {
-                       float blendfac= 1.0f/((ABS(step)*2+side)+1), ipodata[4];
+                       float blendfac, ipodata[4];
                        
                        /* clear zbuf, if we draw future we fill in not moving 
pixels */
                        if(0)
@@ -3193,30 +3200,32 @@
                        
                        set_quad_bezier_ipo(0.5f + 0.5f*speedfac, ipodata);
                        
-                       for(fy= -0.5f+jit[step & 15][0], y=0; y<ysize; y++, 
fy+=1.0f) {
-                               for(fx= -0.5f+jit[step & 15][1], x=0; x<xsize; 
x++, fx+=1.0f, dimg+=4, dz1+=4, dz2+=4, dm++, dz++) {
+                       for(fy= -0.5f+jit[step & 255][0], y=0; y<ysize; y++, 
fy+=1.0f) {
+                               for(fx= -0.5f+jit[step & 255][1], x=0; x<xsize; 
x++, fx+=1.0f, dimg+=4, dz1+=4, dz2+=4, dm++, dz++) {
                                        if(*dm>1) {
+                                               float jfx = fx + 0.5f;
+                                               float jfy = fy + 0.5f;
                                                DrawBufPixel col;
                                                
                                                /* make vertices */
                                                if(nbd->curved) {       /* 
curved */
                                                        quad_bezier_2d(v1, dz1, 
dz1+2, ipodata);
-                                                       v1[0]+= fx; v1[1]+= fy; 
v1[2]= *dz;
+                                                       v1[0]+= jfx; v1[1]+= 
jfy; v1[2]= *dz;
 
                                                        quad_bezier_2d(v2, 
dz1+4, dz1+4+2, ipodata);
-                                                       v2[0]+= fx+1.0f; 
v2[1]+= fy; v2[2]= *dz;
+                                                       v2[0]+= jfx+1.0f; 
v2[1]+= jfy; v2[2]= *dz;
 
                                                        quad_bezier_2d(v3, 
dz2+4, dz2+4+2, ipodata);
-                                                       v3[0]+= fx+1.0f; 
v3[1]+= fy+1.0f; v3[2]= *dz;
+                                                       v3[0]+= jfx+1.0f; 
v3[1]+= jfy+1.0f; v3[2]= *dz;
                                                        
                                                        quad_bezier_2d(v4, dz2, 
dz2+2, ipodata);
-                                                       v4[0]+= fx; v4[1]+= 
fy+1.0f; v4[2]= *dz;
+                                                       v4[0]+= jfx; v4[1]+= 
jfy+1.0f; v4[2]= *dz;
                                                }
                                                else {
-                                                       v1[0]= 
speedfac*dz1[0]+fx;                      v1[1]= speedfac*dz1[1]+fy;             
         v1[2]= *dz;
-                                                       v2[0]= 
speedfac*dz1[4]+fx+1.0f;         v2[1]= speedfac*dz1[5]+fy;                     
 v2[2]= *dz;
-                                                       v3[0]= 
speedfac*dz2[4]+fx+1.0f;         v3[1]= speedfac*dz2[5]+fy+1.0f;         v3[2]= 
*dz;
-                                                       v4[0]= 
speedfac*dz2[0]+fx;                      v4[1]= speedfac*dz2[1]+fy+1.0f;        
 v4[2]= *dz;
+                                                       v1[0]= 
speedfac*dz1[0]+jfx;                     v1[1]= speedfac*dz1[1]+jfy;            
         v1[2]= *dz;
+                                                       v2[0]= 
speedfac*dz1[4]+jfx+1.0f;                v2[1]= speedfac*dz1[5]+jfy;            
         v2[2]= *dz;
+                                                       v3[0]= 
speedfac*dz2[4]+jfx+1.0f;                v3[1]= speedfac*dz2[5]+jfy+1.0f;       
         v3[2]= *dz;
+                                                       v4[0]= 
speedfac*dz2[0]+jfx;                     v4[1]= speedfac*dz2[1]+jfy+1.0f;       
         v4[2]= *dz;
                                                }
                                                if(*dm==255) col.alpha= 1.0f;
                                                else if(*dm<2) col.alpha= 0.0f;
@@ -3229,26 +3238,59 @@
                                dz1+=4;
                                dz2+=4;
                        }
-                       
+
+                       /* blend with a falloff. this fixes the ugly effect you 
get with
+                        * a fast moving object. then it looks like a solid 
object overlayed
+                        * over a very transparent moving version of itself. in 
reality, the
+                        * whole object should become transparent if it is 
moving fast, be
+                        * we don't know what is behind it so we don't do that. 
this hack
+                        * overestimates the contribution of foreground pixels 
but looks a
+                        * bit better without a sudden cutoff. */
+                       blendfac= ((samples - step)/(float)samples);
+                       /* smoothstep to make it look a bit nicer as well */
+                       blendfac= 3.0f*pow(blendfac, 2.0f) - 2.0f*pow(blendfac, 
3.0f);
+
                        /* accum */
-                       for(dr= rectdraw, dz2=newrect, x= xsize*ysize-1; x>=0; 
x--, dr++, dz2+=4) {
+                       rw= rectweight;
+                       rm= rectmax;
+                       for(dr= rectdraw, dz2=newrect, x= xsize*ysize-1; x>=0; 
x--, dr++, dz2+=4, rw++, rm++) {
                                if(dr->colpoin) {
-                                       float bfac= 
dr->alpha*blendfac*dr->colpoin[3];
-                                       float mf= 1.0f - bfac;
+                                       float bfac= dr->alpha*blendfac;
                                        
-                                       dz2[0]= mf*dz2[0] + bfac*dr->colpoin[0];
-                                       dz2[1]= mf*dz2[1] + bfac*dr->colpoin[1];
-                                       dz2[2]= mf*dz2[2] + bfac*dr->colpoin[2];
-                                       dz2[3]= mf*dz2[3] + bfac*dr->colpoin[3];
+                                       dz2[0] += bfac*dr->colpoin[0];
+                                       dz2[1] += bfac*dr->colpoin[1];
+                                       dz2[2] += bfac*dr->colpoin[2];
+                                       dz2[3] += bfac*dr->colpoin[3];
+
+                                       *rw += bfac;
+                                       *rm= MAX2(*rm, bfac);
                                }
                        }
                }
        }
        
+       /* blend between original images and accumulated image */
+       rw= rectweight;
+       rm= rectmax;
+       ro= imgrect;
+       dm= rectmove;
+       for(dz2=newrect, x= xsize*ysize-1; x>=0; x--, dz2+=4, ro+=4, rw++, 
rm++, dm++) {
+               float mfac = *rm;
+               float fac = (*rw == 0.0f)? 0.0f: mfac/(*rw);
+               float nfac = 1.0f - mfac;
+
+               dz2[0]= fac*dz2[0] + nfac*ro[0];
+               dz2[1]= fac*dz2[1] + nfac*ro[1];
+               dz2[2]= fac*dz2[2] + nfac*ro[2];
+               dz2[3]= fac*dz2[3] + nfac*ro[3];
+       }
+
        MEM_freeN(rectz);
        MEM_freeN(rectmove);
        MEM_freeN(rectdraw);
        MEM_freeN(rectvz);
+       MEM_freeN(rectweight);
+       MEM_freeN(rectmax);
        if(minvecbufrect) MEM_freeN(vecbufrect);  /* rects were swapped! */
        zbuf_free_span(&zspan);
 }


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to