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:
authorAndre Susano Pinto <andresusanopinto@gmail.com>2008-09-19 18:15:36 +0400
committerAndre Susano Pinto <andresusanopinto@gmail.com>2008-09-19 18:15:36 +0400
commit656ee61718d85f9366115756ba28e4b53f36d6b2 (patch)
treecca1c89160ea2facf62675bfd9313a0c6a052d30 /source/blender/render/intern
parent2f9f0710d140466f3b8030b66f4637b7f12b9d4a (diff)
Merge from trunk
(The last time there was some files missing due to failed connection to svn server while merging.. thats why this stuff of reverting last merge and redoing it) svn merge -r 16231:16608 https://svn.blender.org/svnroot/bf-blender/trunk/blender
Diffstat (limited to 'source/blender/render/intern')
-rw-r--r--source/blender/render/intern/include/render_types.h3
-rw-r--r--source/blender/render/intern/source/convertblender.c20
-rw-r--r--source/blender/render/intern/source/imagetexture.c8
-rw-r--r--source/blender/render/intern/source/pipeline.c27
-rw-r--r--source/blender/render/intern/source/rayshade.c5
-rw-r--r--source/blender/render/intern/source/rendercore.c32
-rw-r--r--source/blender/render/intern/source/renderdatabase.c14
-rw-r--r--source/blender/render/intern/source/shadbuf.c4
-rw-r--r--source/blender/render/intern/source/shadeoutput.c16
-rw-r--r--source/blender/render/intern/source/zbuf.c92
10 files changed, 154 insertions, 67 deletions
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index f83bbd7e8b2..7e2194549cc 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -418,7 +418,8 @@ typedef struct LampRen {
float xs, ys, dist;
float co[3];
- short type, mode;
+ short type;
+ int mode;
float r, g, b, k;
float energy, haint;
int lay;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index e4a5ad67631..322d2066a6c 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -1565,7 +1565,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0);
float adapt_angle=0.0, adapt_pix=0.0, random, simplify[2];
int i, a, k, max_k=0, totpart, totuv=0, totcol=0, override_uv=-1, dosimplify = 0, dosurfacecache = 0;
- int path_possible=0, keys_possible=0, baked_keys=0, totchild=psys->totchild;
+ int path_possible=0, keys_possible=0, baked_keys=0, totchild=0;
int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}, num;
int totface, *origindex = 0;
char **uv_name=0;
@@ -1573,6 +1573,8 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
/* 1. check that everything is ok & updated */
if(psys==NULL)
return 0;
+
+ totchild=psys->totchild;
part=psys->part;
pars=psys->particles;
@@ -1764,7 +1766,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem
psys->lattice=psys_get_lattice(ob,psys);
/* 3. start creating renderable things */
- for(a=0,pa=pars; a<totpart+totchild; a++, pa++) {
+ for(a=0,pa=pars; a<totpart+totchild; a++, pa++, seed++) {
random = rng_getFloat(rng);
if(a<totpart){
@@ -4576,17 +4578,19 @@ static int allow_render_object(Object *ob, int nolamps, int onlyselected, Object
static int allow_render_dupli_instance(Render *re, DupliObject *dob, Object *obd)
{
ParticleSystem *psys;
- Material ***material;
+ Material *ma;
short a, *totmaterial;
- /* don't allow objects with halos */
+ /* don't allow objects with halos. we need to have
+ * all halo's to sort them globally in advance */
totmaterial= give_totcolp(obd);
- material= give_matarar(obd);
- if(totmaterial && material) {
- for(a= 0; a<*totmaterial; a++)
- if((*material)[a] && (*material)[a]->mode & MA_HALO)
+ if(totmaterial) {
+ for(a= 0; a<*totmaterial; a++) {
+ ma= give_current_material(obd, a);
+ if(ma && (ma->mode & MA_HALO))
return 0;
+ }
}
for(psys=obd->particlesystem.first; psys; psys=psys->next)
diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c
index c2d27f8f3a7..b9a2acb8b1c 100644
--- a/source/blender/render/intern/source/imagetexture.c
+++ b/source/blender/render/intern/source/imagetexture.c
@@ -577,10 +577,10 @@ static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float max
if(texres->talpha==0) texres->ta= 1.0;
if(alphaclip!=1.0) {
- /* this is for later investigation, premul or not? */
- /* texres->tr*= alphaclip; */
- /* texres->tg*= alphaclip; */
- /* texres->tb*= alphaclip; */
+ /* premul it all */
+ texres->tr*= alphaclip;
+ texres->tg*= alphaclip;
+ texres->tb*= alphaclip;
texres->ta*= alphaclip;
}
}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 3cd7bdc6772..bf2a72b4f9b 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -138,7 +138,7 @@ static void print_error(char *str) {printf("ERROR: %s\n", str);}
static void stats_background(RenderStats *rs)
{
- extern uintptr_t mem_in_use;
+ uintptr_t mem_in_use= MEM_get_memory_in_use();
float megs_used_memory= mem_in_use/(1024.0*1024.0);
char str[400], *spos= str;
@@ -1889,6 +1889,7 @@ static void do_render_fields_blur_3d(Render *re)
re->result->tilerect= re->disprect;
/* this copying sequence could become function? */
+ /* weak is: it chances disprect from border */
re->disprect.xmin= re->disprect.ymin= 0;
re->disprect.xmax= re->winx;
re->disprect.ymax= re->winy;
@@ -2346,6 +2347,12 @@ static int is_rendering_allowed(Render *re)
if(re->osa==0)
re->r.scemode &= ~R_FULL_SAMPLE;
+ /* no fullsample and edge */
+ if((re->r.scemode & R_FULL_SAMPLE) && (re->r.mode & R_EDGE)) {
+ re->error("Full Sample doesn't support Edge Enhance");
+ return 0;
+ }
+
}
else
re->r.scemode &= ~R_FULL_SAMPLE; /* clear to be sure */
@@ -2407,7 +2414,7 @@ static int is_rendering_allowed(Render *re)
}
/* evaluating scene options for general Blender render */
-static int render_initialize_from_scene(Render *re, Scene *scene)
+static int render_initialize_from_scene(Render *re, Scene *scene, int anim)
{
int winx, winy;
rcti disprect;
@@ -2435,6 +2442,12 @@ static int render_initialize_from_scene(Render *re, Scene *scene)
re->scene= scene;
+ /* not too nice, but it survives anim-border render */
+ if(anim) {
+ re->disprect= disprect;
+ return 1;
+ }
+
/* check all scenes involved */
tag_scenes_for_render(re);
@@ -2466,7 +2479,7 @@ void RE_BlenderFrame(Render *re, Scene *scene, int frame)
scene->r.cfra= frame;
- if(render_initialize_from_scene(re, scene)) {
+ if(render_initialize_from_scene(re, scene, 0)) {
do_render_all_options(re);
}
@@ -2551,8 +2564,8 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype);
int cfrao= scene->r.cfra;
- /* do not call for each frame, it initializes & pops output window */
- if(!render_initialize_from_scene(re, scene))
+ /* do not fully call for each frame, it initializes & pops output window */
+ if(!render_initialize_from_scene(re, scene, 0))
return;
/* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */
@@ -2580,6 +2593,10 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra)
} else {
for(scene->r.cfra= sfra; scene->r.cfra<=efra; scene->r.cfra++) {
char name[FILE_MAX];
+
+ /* only border now, todo: camera lens. (ton) */
+ render_initialize_from_scene(re, scene, 1);
+
if (scene->r.mode & (R_NO_OVERWRITE | R_TOUCH) ) {
BKE_makepicstring(name, scene->r.pic, scene->r.cfra, scene->r.imtype);
}
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index c352a83d0f4..0fd9365477c 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -2056,7 +2056,10 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float *shadfac)
if(shi->mat->mode & MA_SHADOW_TRA) isec.mode= RE_RAY_SHADOW_TRA;
else isec.mode= RE_RAY_SHADOW;
- if(lar->mode & LA_LAYER) isec.lay= lar->lay; else isec.lay= -1;
+ if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW))
+ isec.lay= lar->lay;
+ else
+ isec.lay= -1;
/* only when not mir tracing, first hit optimm */
if(shi->depth==0) {
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 4a2ad995b39..bda02bea8d7 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -158,7 +158,7 @@ static int calchalo_z(HaloRen *har, int zz)
{
if(har->type & HA_ONLYSKY) {
- if(zz!=0x7FFFFFFF) zz= - 0x7FFFFF;
+ if(zz < 0x7FFFFFF0) zz= - 0x7FFFFF; /* edge render messes zvalues */
}
else {
zz= (zz>>8);
@@ -931,17 +931,23 @@ static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
}
}
-
-static void convert_to_key_alpha(RenderPart *pa, float *rectf)
+static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl)
{
- int y;
-
- for(y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
- if(rectf[3] >= 1.0f);
- else if(rectf[3] > 0.0f) {
- rectf[0] /= rectf[3];
- rectf[1] /= rectf[3];
- rectf[2] /= rectf[3];
+ RenderLayer *rlpp[RE_MAX_OSA];
+ int y, sample, totsample;
+
+ totsample= get_sample_layers(pa, rl, rlpp);
+
+ for(sample= 0; sample<totsample; sample++) {
+ float *rectf= rlpp[sample]->rectf;
+
+ for(y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
+ if(rectf[3] >= 1.0f);
+ else if(rectf[3] > 0.0f) {
+ rectf[0] /= rectf[3];
+ rectf[1] /= rectf[3];
+ rectf[2] /= rectf[3];
+ }
}
}
}
@@ -1229,7 +1235,7 @@ void zbufshadeDA_tile(RenderPart *pa)
/* de-premul alpha */
if(R.r.alphamode & R_ALPHAKEY)
- convert_to_key_alpha(pa, rl->rectf);
+ convert_to_key_alpha(pa, rl);
/* free stuff within loop! */
MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
@@ -1393,7 +1399,7 @@ void zbufshade_tile(RenderPart *pa)
/* de-premul alpha */
if(R.r.alphamode & R_ALPHAKEY)
- convert_to_key_alpha(pa, rl->rectf);
+ convert_to_key_alpha(pa, rl);
if(edgerect) MEM_freeN(edgerect);
edgerect= NULL;
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 98b1426e8ff..d44b49cc706 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -483,16 +483,16 @@ void RE_set_customdata_names(ObjectRen *obr, CustomData *data)
DerivedMesh which stores the layers is freed */
CustomDataLayer *layer;
- int numlayers, i, mtfn, mcn;
+ int numtf = 0, numcol = 0, i, mtfn, mcn;
if (CustomData_has_layer(data, CD_MTFACE)) {
- numlayers= CustomData_number_of_layers(data, CD_MTFACE);
- obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numlayers, "mtfacenames");
+ numtf= CustomData_number_of_layers(data, CD_MTFACE);
+ obr->mtface= MEM_callocN(sizeof(*obr->mtface)*numtf, "mtfacenames");
}
if (CustomData_has_layer(data, CD_MCOL)) {
- numlayers= CustomData_number_of_layers(data, CD_MCOL);
- obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numlayers, "mcolnames");
+ numcol= CustomData_number_of_layers(data, CD_MCOL);
+ obr->mcol= MEM_callocN(sizeof(*obr->mcol)*numcol, "mcolnames");
}
for (i=0, mtfn=0, mcn=0; i < data->totlayer; i++) {
@@ -500,12 +500,12 @@ void RE_set_customdata_names(ObjectRen *obr, CustomData *data)
if (layer->type == CD_MTFACE) {
strcpy(obr->mtface[mtfn++], layer->name);
- obr->actmtface= layer->active_rnd;
+ obr->actmtface= CLAMPIS(layer->active_rnd, 0, numtf);
obr->bakemtface= layer->active;
}
else if (layer->type == CD_MCOL) {
strcpy(obr->mcol[mcn++], layer->name);
- obr->actmcol= layer->active_rnd;
+ obr->actmcol= CLAMPIS(layer->active_rnd, 0, numcol);
}
}
}
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index f477df3ed8c..c53a2b68c9c 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -296,7 +296,7 @@ static void shadowbuf_autoclip(Render *re, LampRen *lar)
minz= 1.0e30f; maxz= -1.0e30f;
Mat4CpyMat4(viewmat, lar->shb->viewmat);
- if(lar->mode & LA_LAYER) lay= lar->lay;
+ if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) lay= lar->lay;
maxtotvert= 0;
for(obr=re->objecttable.first; obr; obr=obr->next)
@@ -1520,7 +1520,7 @@ static void isb_bsp_fillfaces(Render *re, LampRen *lar, ISBBranch *root)
minmaxf[2]= (2.0f*root->box.ymin - size-2.0f)/size;
minmaxf[3]= (2.0f*root->box.ymax - size+2.0f)/size;
- if(lar->mode & LA_LAYER) lay= lar->lay;
+ if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) lay= lar->lay;
/* (ab)use zspan, since we use zbuffer clipping code */
zbuf_alloc_span(&zspan, size, size, re->clipcrop);
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 5b69323667e..5a80173d1f1 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -1761,7 +1761,21 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
if(shi->combinedflag & SCE_PASS_SPEC)
VECADD(shr->combined, shr->combined, shr->spec);
+ /* modulate by the object color */
+ if((ma->shade_flag & MA_OBCOLOR) && shi->obr->ob) {
+ if(!(ma->sss_flag & MA_DIFF_SSS) || !has_sss_tree(&R, ma)) {
+ float obcol[4];
+
+ QUATCOPY(obcol, shi->obr->ob->col);
+ CLAMP(obcol[3], 0.0f, 1.0f);
+
+ shr->combined[0] *= obcol[0];
+ shr->combined[1] *= obcol[1];
+ shr->combined[2] *= obcol[2];
+ shr->alpha *= obcol[3];
+ }
+ }
+
shr->combined[3]= shr->alpha;
}
-
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 29aa6e3be29..76a47a11338 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -2410,7 +2410,7 @@ void zbuffer_shadow(Render *re, float winmat[][4], LampRen *lar, int *rectz, int
float obwinmat[4][4], ho1[4], ho2[4], ho3[4], ho4[4];
int a, b, c, i, c1, c2, c3, c4, ok=1, lay= -1;
- if(lar->mode & LA_LAYER) lay= lar->lay;
+ if(lar->mode & (LA_LAYER|LA_LAYER_SHADOW)) lay= lar->lay;
/* 1.0f for clipping in clippyra()... bad stuff actually */
zbuf_alloc_span(&zspan, size, size, 1.0f);
@@ -2981,10 +2981,11 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
{
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 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
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 @@ 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 || 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 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
/* 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 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
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 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
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 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
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);
}