diff options
author | Ton Roosendaal <ton@blender.org> | 2005-04-24 00:49:23 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2005-04-24 00:49:23 +0400 |
commit | 7fa7826da743a811e7b48247110684a13a52befb (patch) | |
tree | ac30359d7555ce7d67c44ed8d7aa4badb059c6c6 | |
parent | 0dcba86c6b631a31eadb5e8805c5c94222559e25 (diff) |
The zblur plugin (aka as DoF) integrated in render. Compared to patch
submitted by Alexander, changes/improvements are:
- Moved to new Panel in Scene buttons "Post Effects". Together with other
postprocessing options, such as Edge render. It is also not called DoF,
this because that's a bit pretending too much then. It's a zblur still!
- Made it render Alpha as well
- Made it use and deliver float buffers
- Huge cleanup of zblur.c code, was very messy. It was alling things in render
code without need even (win matrices, transform faces, etc)
- Fixed errors in using Z values (zbuffer is signed int)
- Removed very weird gamma corrections for front/back half
- Tweaked gaussian table, allow variable 'Sigma' to be set for gauss curve
- Didn't copy 'auto focus' yet. Use of this is very limited, and gives
false expectations, nor works for rendering anims with deamons well.
Main issue remains: it's not a very advanced feature... I still doubt
very much if this deserves to be released. Spent 2 days on trying to get
the key issues solved, with not much results.
- gauss filter code has weird side effects on large blur size
- having unsharp (blurred) in front also blurs what's around in back.
only blurred in back with sharp in front works a little bit
- severe aliasing errors... also due the code splitting in 2 halves
- doesnt work with unified yet
- won't work for halos, spot halos or transparant faces
Anyhoo... It was promised to be committed, so now artists can play with it.
Who knows it's useful after all, or some fixes can be implemented. :)
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 6 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 16 | ||||
-rw-r--r-- | source/blender/include/BIF_editview.h | 1 | ||||
-rw-r--r-- | source/blender/include/butspace.h | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_camera_types.h | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 6 | ||||
-rw-r--r-- | source/blender/render/SConscript | 1 | ||||
-rw-r--r-- | source/blender/render/intern/include/zblur.h | 48 | ||||
-rw-r--r-- | source/blender/render/intern/source/initrender.c | 5 | ||||
-rw-r--r-- | source/blender/render/intern/source/shadbuf.c | 1 | ||||
-rw-r--r-- | source/blender/render/intern/source/zblur.c | 817 | ||||
-rw-r--r-- | source/blender/render/intern/source/zbufferdatastruct.c | 2 | ||||
-rw-r--r-- | source/blender/src/butspace.c | 2 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 23 | ||||
-rw-r--r-- | source/blender/src/buttons_scene.c | 68 | ||||
-rw-r--r-- | source/blender/src/renderwin.c | 8 |
16 files changed, 971 insertions, 40 deletions
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index f5916fb17b0..aebfa54fe1e 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -172,6 +172,12 @@ Scene *add_scene(char *name) sce->r.posthue= 1.0; sce->r.postmul= 1.0; + sce->r.focus= 0.9; + sce->r.zgamma= 1.0; + sce->r.zsigma= 4.0; + sce->r.zblur= 10.0; + sce->r.zmin= 0.8; + sce->r.xplay= 640; sce->r.yplay= 480; sce->r.freqplay= 60; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index e1c65dba344..ff3953296df 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4641,6 +4641,13 @@ static void do_versions(Main *main) while(sce) { if(sce->r.postsat==0.0) sce->r.postsat= 1.0; + if(sce->r.zgamma==0.0) { + sce->r.focus= 0.9; + sce->r.zgamma= 1.0; + sce->r.zsigma= 4.0; + sce->r.zblur= 10.0; + sce->r.zmin= 0.8; + } sce= sce->id.next; } while(cam) { @@ -4701,15 +4708,6 @@ static void do_versions(Main *main) } } } - /*Camera *ca; - - for (ca= main->camera.first; ca; ca= ca->id.next) { - ca->focus= 0.9; - ca->zgamma= 1.0; - ca->zblur= 10.0; - ca->zmin= 0.8; - ca->flag |= CAM_AUTOFOCUS; - }*/ } /* don't forget to set version number in blender.c! */ diff --git a/source/blender/include/BIF_editview.h b/source/blender/include/BIF_editview.h index 1cbee01f99b..345f21cdb9e 100644 --- a/source/blender/include/BIF_editview.h +++ b/source/blender/include/BIF_editview.h @@ -35,6 +35,7 @@ struct Base; struct Object; +struct Camera; void arrows_move_cursor(unsigned short event); void borderselect(void); diff --git a/source/blender/include/butspace.h b/source/blender/include/butspace.h index 4b5f5a67258..755b5c127fa 100644 --- a/source/blender/include/butspace.h +++ b/source/blender/include/butspace.h @@ -77,6 +77,7 @@ extern void do_fontbuts(unsigned short event); extern void do_mballbuts(unsigned short event); extern void do_latticebuts(unsigned short event); extern void do_fpaintbuts(unsigned short event); +extern void do_cambuts(unsigned short event); extern char *get_vertexgroup_menustr(struct Object *ob); // used in object buttons /* shading */ @@ -281,6 +282,9 @@ void test_idbutton_cb(void *namev, void *arg2_unused); #define B_SWITCHRENDER 1641 #define B_FBUF_REDO 1642 +#define B_SET_EDGE 1643 +#define B_SET_ZBLUR 1644 + #ifdef __NLA /* *********************** */ enum { diff --git a/source/blender/makesdna/DNA_camera_types.h b/source/blender/makesdna/DNA_camera_types.h index 8b6f0eb369b..2041aae3429 100644 --- a/source/blender/makesdna/DNA_camera_types.h +++ b/source/blender/makesdna/DNA_camera_types.h @@ -54,7 +54,7 @@ typedef struct Camera { float YF_dofdist, YF_aperture; short YF_bkhtype, YF_bkhbias; float YF_bkhrot; - + struct Ipo *ipo; ScriptLink scriptlink; @@ -72,6 +72,7 @@ typedef struct Camera { /* yafray: dof sampling switch */ #define CAM_YF_NO_QMC 4 + #ifdef __cplusplus } #endif diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 8d6fed13b88..d285a46c3ae 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -215,7 +215,9 @@ typedef struct RenderData { /* Dither noise intensity */ float dither_intensity; - float pad_dither; + + /* Zblur settings */ + float zmin, focus, zgamma, zsigma, zblur; /* yafray: global panel params. TODO: move elsewhere */ short GIquality, GIcache, GImethod, GIphotons, GIdirect; @@ -303,6 +305,8 @@ typedef struct Scene { #define R_GAUSS 0x20000 #define R_FBUF 0x40000 #define R_THREADS 0x80000 +#define R_ZBLUR 0x100000 + /* yafray: renderer flag (not only exclusive to yafray) */ #define R_INTERN 0 diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript index 1537f402f7a..71be91f1be3 100644 --- a/source/blender/render/SConscript +++ b/source/blender/render/SConscript @@ -22,6 +22,7 @@ source_files = ['intern/source/RE_callbacks.c', 'intern/source/shadbuf.c', 'intern/source/texture.c', 'intern/source/vanillaRenderPipe.c', + 'intern/source/zblur.c', 'intern/source/zbuf.c', 'intern/source/zbufferdatastruct.c'] diff --git a/source/blender/render/intern/include/zblur.h b/source/blender/render/intern/include/zblur.h new file mode 100644 index 00000000000..a0e1c6a39ce --- /dev/null +++ b/source/blender/render/intern/include/zblur.h @@ -0,0 +1,48 @@ +/* + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef ZBLUR_H +#define ZBLUR_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*-----------------------------------------------------------*/ +/* Includes */ +/*-----------------------------------------------------------*/ + +/*-----------------------------------------------------------*/ +/* Function */ +/*-----------------------------------------------------------*/ + +void add_zblur(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index c4668a9f816..24f836688cf 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -99,6 +99,7 @@ #include "renderHelp.h" #include "jitter.h" #include "gammaCorrectionTables.h" +#include "zblur.h" /* Own includes */ #include "initrender.h" @@ -1065,6 +1066,10 @@ static void mainRenderLoop(void) /* here the PART and FIELD loops */ if(RE_local_test_break()==0) add_halo_flare(); } + if( (R.r.mode & R_ZBLUR)) { + if(RE_local_test_break()==0) add_zblur(); + } + if(R.r.mode & R_MBLUR) { add_to_blurbuf(blur); } diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c index 8510df2de3d..c942232bebb 100644 --- a/source/blender/render/intern/source/shadbuf.c +++ b/source/blender/render/intern/source/shadbuf.c @@ -522,6 +522,7 @@ float testshadowbuf(struct ShadBuf *shb, float *rco, float *dxco, float *dyco, f for(a=num;a>0;a--) { /* instead of jit i tried random: ugly! */ /* note: the plus 0.5 gives best sampling results, jit used to go from 0-1 */ + /* xs1 and ys1 are already corrected to be corner of sample area */ xs= xs1 + xres*(j[0] + 0.5); ys= ys1 + yres*(j[1] + 0.5); j+=2; diff --git a/source/blender/render/intern/source/zblur.c b/source/blender/render/intern/source/zblur.c new file mode 100644 index 00000000000..4cb1e010e83 --- /dev/null +++ b/source/blender/render/intern/source/zblur.c @@ -0,0 +1,817 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +/* + * This file is largely based on the focal blur plugin by onk, 8.99 + * + */ + +#include <math.h> +#include <string.h> +#include <limits.h> +#include <stdio.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_camera_types.h" +#include "DNA_scene_types.h" + +#include "BKE_global.h" +#include "BKE_utildefines.h" + +#include "RE_callbacks.h" + +#include "render.h" +#include "pixelblending.h" + +#include "blendef.h" + +//#include "BIF_gl.h" + +/* ------------------------------------------------- + * defines, protos */ + +typedef enum { I_GRAY, I_FLOAT, I_FLOAT4 } IMGTYPE; + +typedef struct { + int x, y; + int size, el_size; + IMGTYPE type; + char *data; +} Image; + +typedef struct { /* blur mask struct */ + int size; + float fac; + float *val; +} Mask; + +typedef Mask* Maskarray; + +/* don't change these */ +#define NMASKS_SHIFT 2 +#define NMASKS 64 + + +static Image *alloc_img(int x, int y, IMGTYPE type) +{ + Image *ret; + int size, typesize; + + switch (type) { + case I_GRAY: + typesize = 1; + break; + case I_FLOAT: + typesize = sizeof(float); + break; + case I_FLOAT4: + typesize = 4 * sizeof(float); + break; + default: + return 0; + } + + size = x * y; + + ret = (Image *) MEM_mallocN(sizeof(Image) + size*typesize, "zblur_img"); + if (ret) { + ret->x = x; + ret->y = y; + ret->size = size; + ret->el_size = typesize; + ret->type = type; + ret->data = (char *) (ret + 1); + size *= typesize; + memset(ret->data, 0, size); + } + + return ret; +} + +static int free_img(Image *img) +{ + MEM_freeN(img); + return 1; +} + +/* 32 bits (int) rect to float buf */ +static void recti2imgf(int *src, Image *dest, int x, int y) +{ + char *from; + float *to; + int i, ix, iy; + + if(dest->type != I_FLOAT4) return; + + from = (char *) src; + to = (float *) dest->data; + + if (R.r.mode & R_FIELDS) { /* double each scanline */ + for (iy=0; iy<y; iy++) { + for (ix=0; ix<x; ix++) { + *to++ = ((float)from[0])/255.0; + *to++ = ((float)from[1])/255.0; + *to++ = ((float)from[2])/255.0; + *to++ = ((float)from[3])/255.0; + from += 4; + } + + memcpy(to, to-4*sizeof(float)*x, 4*sizeof(float)*x); + to+= 4*x; + + iy++; + } + } + else { + i = x * y; + while(i--) { + *to++ = ((float)from[0])/255.0; + *to++ = ((float)from[1])/255.0; + *to++ = ((float)from[2])/255.0; + *to++ = ((float)from[3])/255.0; + from += 4; + } + } +} + +/* float rect to float buf */ +static void rectf2imgf(float *src, Image *dest, int x, int y) +{ + float *from; + float *to; + int i, iy; + + if(dest->type != I_FLOAT4) return; + + from = src; + to = (float *) dest->data; + + if (R.r.mode & R_FIELDS) { /* double each scanline */ + for (iy=0; iy<y; iy++) { + + memcpy(to, from, 4*sizeof(float)*x); + to+= 4*x; + memcpy(to, from, 4*sizeof(float)*x); + to+= 4*x; + + iy++; + from += 4*x; + } + } + else { + i = y; + while(i--) { + memcpy(to, from, 4*sizeof(float)*x); + from += 4*x; + to += 4*x; + } + } +} + +/* floatbuf back to 32 bits rect */ +static void imgf2recti(Image *src, int *dest) +{ + float *from; + char *to; + int i, ix, iy; + + if(src->type != I_FLOAT4) return; + + from = (float *) src->data; + to = (char *) dest; + + if (R.r.mode & R_FIELDS) { + for (iy=0; iy<src->y; iy++) { + for (ix=0; ix<src->x; ix++) { + *to++ = (char)(from[0]*255.0); + *to++ = (char)(from[1]*255.0); + *to++ = (char)(from[2]*255.0); + *to++ = (char)(from[3]*255.0); + from += 4; + } + iy++; + from+= 4*src->x; + } + } + else { + i = src->x * src->y; + while(i--) { + *to++ = (char)(from[0]*255.0); + *to++ = (char)(from[1]*255.0); + *to++ = (char)(from[2]*255.0); + *to++ = (char)(from[3]*255.0); + from += 4; + } + } +} + +/* floatbuf back to float rect */ +static void imgf2rectf(Image *src, float *dest) +{ + float *from; + float *to; + int i, iy; + + if(src->type != I_FLOAT4) return; + + from = (float *) src->data; + to = dest; + + if (R.r.mode & R_FIELDS) { + for (iy=0; iy<src->y; iy++) { + + memcpy(to, from, 4*sizeof(float)*src->x); + + iy++; + to+= 4*src->x; + from+= 8*src->x; + } + } + else { + i = src->x * src->y; + memcpy(to, from, 4*sizeof(float)*i); + } +} + + +static void imgf_gamma(Image *src, float gamma) +{ + float *to; + int i; + + if(gamma==1.0) return; + + i = 4 * src->x * src->y; + to= (float *) src->data; + while(i--) { + *to = powf(*to, gamma); + to++; + } +} + +#if 0 +/* create new image with alpha & color zero where mask is zero */ +static Image *imgf_apply_mask(Image *src, Image *zmask) +{ + Image *dest; + float *from, *to; + int i; + char *zptr; + + dest = alloc_img(src->x, src->y, I_FLOAT4); + + i= src->x * src->y; + from= (float *) src->data; + to= (float *) dest->data; + zptr= (char *)zmask->data; + + while(i--) { + if(*zptr) { + to[0]= from[0]; + to[1]= from[1]; + to[2]= from[2]; + to[3]= from[3]; + } + else { + to[0]= to[1]= to[2]= to[3]= 0.0f; + } + zptr++; + to+= 4; + from+= 4; + } + + return dest; +} + +static void imgf_alpha_over(Image *dest, Image *src) +{ + float *from, *to; + int i; + + i= src->x * src->y; + from= (float *) src->data; + to= (float *) dest->data; + + while(i--) { + addAlphaOverFloat(to, from); + to+= 4; + from+= 4; + } +} + +#endif + +/* --------------------------------------------------------------------- */ +/* mask routines */ + +static Mask *alloc_mask(int size) +{ + Mask *m; + int memsize; + + memsize = (sizeof(Mask) + (2 * size +1) * (2 * size +1) * sizeof(float)); + + m = (Mask*) MEM_mallocN(memsize, "zblur_mask"); + m->size = size; + m->val = (float *) (m + 1); + + return m; +} + +static void free_mask(Mask *m) +{ + int memsize; + + memsize = 2 * m->size + 1; + memsize *= memsize * sizeof(float); + memsize += sizeof(Mask); + + MEM_freeN(m); +} + +/* normalize mask to 1 */ + +static void norm_mask(Mask *m) +{ + float fac; + int size; + float *v; + + fac = m->fac; + size = (2 * m->size +1)*(2 * m->size +1); + + v = m->val; + while(size--) { + *v++ *= fac; + } + m->fac = 1.0; +} + +/* filters a grayvalue image with a gaussian IIR filter with blur radius "rad" + * For large blurs, it's more efficient to call the routine several times + * instead of using big blur radii. + * The original image is changed */ + + +static void gauss_blur(Image *img, float rad) +{ + Image *new; + register float sum, val; + float gval; + float *gausstab, *v; + int r, n, m; + int x, y; + int i; + int step, bigstep; + char *src, *dest; + + r = (1.5 * rad + 1.5); + n = 2 * r + 1; + + /* ugly : */ + if ((img->x <= n) || (img->y <= n)) { + return; + } + + gausstab = (float *) MEM_mallocN(n * sizeof(float), "zblur_gauss"); + if (!gausstab) { + return; + } + + sum = 0.0; + v = gausstab; + for (x = -r; x <= r; x++) { + + val = exp(-4*(float ) (x*x)/ (float) (r*r)); + sum += val; + *v++ = val; + } + + i = n; + v = gausstab; + while (i--) { + *v++ /= sum; + } + + new = alloc_img(img->x, img->y, I_GRAY); + if (!new) { + return; + } + + /* horizontal */ + + step = (n - 1); + + for (y = 0; y < img->y; y++) { + src = (char *)img->data + (y * img->x); + dest = (char *)new->data + (y * img->x); + + for (x = r; x > 0 ; x--) { + m = n - x; + gval = 0.0; + sum = 0.0; + v = gausstab + x; + for (i = 0; i < m; i++) { + val = *v++; + sum += val; + gval += val * (*src++); + } + *dest++ = gval / sum; + src -= m; + } + + for (x = 0; x <= (img->x - n); x++) { + gval = 0.0; + v = gausstab; + + for (i = 0; i < n; i++) { + val = *v++; + gval += val * (*src++); + } + *dest++ = gval; + src -= step; + } + + for (x = 1; x <= r ; x++) { + m = n - x; + gval = 0.0; + sum = 0.0; + v = gausstab; + for (i = 0; i < m; i++) { + val = *v++; + sum += val; + gval += val * (*src++); + } + *dest++ = gval / sum; + src -= (m - 1); + } + } + + /* vertical */ + + step = img->x; + bigstep = (n - 1) * step; + for (x = 0; x < step ; x++) { + src = new->data + x; + dest = img->data + x; + + for (y = r; y > 0; y--) { + m = n - y; + gval = 0.0; + sum = 0.0; + v = gausstab + y; + for (i = 0; i < m; i++) { + val = *v++; + sum += val; + gval += val * src[0]; + src += step; + } + dest[0] = gval / sum; + src -= m * step; + dest+= step; + } + for (y = 0; y <= (img->y - n); y++) { + gval = 0.0; + v = gausstab; + for (i = 0; i < n; i++) { + val = *v++; + gval += val * src[0]; + src += step; + } + dest[0] = gval; + dest += step; + src -= bigstep; + } + for (y = 1; y <= r ; y++) { + m = n - y; + gval = 0.0; + sum = 0.0; + v = gausstab; + for (i = 0; i < m; i++) { + val = *v++; + sum += val; + gval += val * src[0]; + src += step; + } + dest[0] = gval / sum; + dest += step; + src -= (m - 1) * step; + } + } + MEM_freeN(gausstab); + free_img(new); +} + +static float zigma(float x, float sigma, float sigma4) +{ + //return 1.0/(1.0+pow(x, sigma)); + + if(x < sigma) { + x*= sigma; + return 1.0/exp(x*x) - sigma4; + } + return 0.0; +} + + +static Mask *gauss_mask(float rad, float sigma) +{ + Mask *m; + float sum, val, *v, fac, radsq= rad*rad; + float sigma4; + int r; + int ix, iy; + + r = (1.0 * rad + 1.0); + m = alloc_mask(r); + v = m->val; + sum = 0.0; + + sigma4= 1.0/exp(sigma*sigma*sigma*sigma); + + for (iy = -r; iy <= r; iy++) { + for (ix = -r; ix <= r; ix++) { + + fac= ((float)(ix*ix + iy*iy))/(radsq); + val = zigma(fac, sigma, sigma4); + + // val = exp(-(float) (ix*ix + iy*iy)/(rad * rad)); + sum += val; + *v++ = val; + } + } + + m->fac = 1.0 / sum; + + norm_mask(m); + return m; +} + +/* generates #num masks with the maximal blur radius 'rad' + * */ +static Maskarray *init_masks(int num, float rad, float sigma) +{ + int i; + float r, step; + Maskarray *maskarray; + + maskarray = (Maskarray*) MEM_mallocN(num * sizeof (Maskarray), "zblur_masks"); + step = rad / num; + r = 0.1; + for (i = 0; i < num; i++) { + maskarray[i] = gauss_mask(r, sigma); + r += step; + } + return maskarray; +} + + +/* ********************* Do the blur ******************************** */ + +static Image *zblur(Image *src, Image *zbuf, float radius, float sigma) +{ + Image *dest; + Maskarray *mar; + Mask *m; + float *sptr, *dptr; + float *mval; /* mask value pointer */ + float rval, gval, bval, aval; + float norm, fac; + int tmp; + int zval; + int size; + int row; + int mrow; + int x, y; + int i; + int sx, sy, ex, ey; + int mx, my; + char *zptr; + + if(src->type != I_FLOAT4) return NULL; + + dest = alloc_img(src->x, src->y, I_FLOAT4); + row = src->x * 4; + + mar = init_masks(NMASKS, radius, sigma); + + for (y = 0; y < src->y ; y++) { + for (x = 0; x < src->x; x++) { + dptr = (float *) (dest->data + ((y * src->x + x) * src->el_size)); + zptr = zbuf->data + (y * src->x + x); + zval = *zptr; + sptr = (float *) (src->data + ((y *src->x + x )* src->el_size)); + + m = mar[zval >> NMASKS_SHIFT]; + + size = m->size; + + if(size==0 || zval==0) { + dptr[0] = sptr[0]; + dptr[1] = sptr[1]; + dptr[2] = sptr[2]; + dptr[3] = sptr[3]; + continue; + } + + ex = src->x - x; + ey = src->y - y; + + sx = (x < size) ? x : size; + sy = (y < size) ? y : size; + ex = (ex <= size) ? ex - 1: size; + ey = (ey <= size) ? ey - 1: size; + + sptr -= sy *src->x * 4; + zptr -= sy * src->x; + mrow = (size << 1) + 1; + mval = m->val + (size - sy) * mrow + size; + + norm = rval = gval = bval = aval= 0.0; + + for (my = -sy; my <= ey; my++) { + for (mx = -sx; mx <= ex; mx++) { + if( zptr[mx] ) { + tmp = 4 * mx; + fac = mval[mx] * (float) zptr[mx] /255.0 ; + + norm += fac; + rval += fac * sptr[tmp]; + gval += fac * sptr[tmp + 1]; + bval += fac * sptr[tmp + 2]; + aval += fac * sptr[tmp + 3]; + } + } + mval += mrow; + sptr += row; + zptr += src->x; + } + + dptr[0] = rval / norm; + dptr[1] = gval / norm; + dptr[2] = bval / norm; + dptr[3] = aval / norm; + } + if(!(y % 4) && RE_local_test_break()) break; + } + + for (i= 0; i < NMASKS; i++) { + free_mask(mar[i]); + } + + MEM_freeN(mar); + + return dest; +} + + +/* this splits the z-buffer into 2 gray-images (background, foreground) +* which are used for the weighted blur */ + +static void zsplit(int *zptr, Image *fg, Image *bg, int zfocus, int zmax, int zmin, int x, int y) +{ + char *p, *q; + int i, ix, iy; + float fdist; + float fgnorm, bgnorm; + + p = fg->data; + q = bg->data; + bgnorm = 255.0 / ((float) zmax - (float) zfocus); + fgnorm = 255.0 / ((float) zfocus - (float) zmin); + + if (R.r.mode & R_FIELDS) { + for (iy=0; iy<y; iy++) { + for (ix=0; ix<x; ix++) { + fdist = (float) (*zptr++); + if (fdist < zmin) fdist = zmin; + + fdist -= zfocus; + + if (fdist < 0) { + *p = (char) (-fdist * fgnorm); + *q = 0; + } + else { + *q = (char) (fdist * bgnorm); + *p = 0; + } + p++, q++; + } + iy++; + p+= x; + q+= x; + } + } + else { + i = x * y; + while(i--) { + fdist = (float) (*zptr++); + if (fdist < zmin) fdist = zmin; + + fdist -= zfocus; + + if (fdist < 0) { + *p = (char) (-fdist * fgnorm); + *q = 0; + } + else { + *q = (char) (fdist * bgnorm); + *p = 0; + } + p++, q++; + } + } +} + +void add_zblur(void) +{ + Image *orig, *zfront, *work, *zback; + float zblurr; + int zfocus; + int x, y, zmin; + + if (R.rectz == NULL) return; + + x= R.rectx; + y= R.recty; + + zblurr= (R.r.zblur*R.r.size)/100; + + if (R.r.mode & R_FIELDS) { + y *= 2; + zblurr *= 2; + } + + zmin= INT_MAX*( 2.0*R.r.zmin - 1.0); // R.r.zmin ranges 0 - 1 + zfocus = INT_MAX*( 2.0*R.r.focus - 1.0); + + if(zmin>zfocus) zmin= zfocus; + + zfront = alloc_img(x, y, I_GRAY); + zback = alloc_img(x, y, I_GRAY); + orig = alloc_img(x, y, I_FLOAT4); + + if(R.rectftot) rectf2imgf(R.rectftot, orig, x, y); + else recti2imgf(R.rectot, orig, x, y); + + imgf_gamma(orig, R.r.zgamma); // pregamma correct if required + + + /* split up z buffer into 2 gray images */ + zsplit(R.rectz, zfront, zback, zfocus, INT_MAX, zmin, x, y); + +// glDrawBuffer(GL_FRONT); +// glRasterPos2i(0, 0); +// glDrawPixels(x, y, GL_RED, GL_UNSIGNED_BYTE, zback->data); +// glFlush(); +// glDrawBuffer(GL_BACK); + + gauss_blur(zback, 1.0); + gauss_blur(zfront, zblurr); + + /* blur back part */ + work = zblur(orig, zback, zblurr, R.r.zsigma); + free_img(orig); + + /* blur front part */ + orig = zblur(work, zfront, zblurr, R.r.zsigma); + + imgf_gamma(orig, 1.0/R.r.zgamma); // pregamma correct if required + + if(R.rectftot) imgf2rectf(orig, R.rectftot); + else imgf2recti(orig, R.rectot); + + free_img(work); + free_img(orig); + free_img(zfront); + free_img(zback); + + /* make new display rect */ + if(R.rectftot) RE_floatbuffer_to_output(); +} + + diff --git a/source/blender/render/intern/source/zbufferdatastruct.c b/source/blender/render/intern/source/zbufferdatastruct.c index 4ab8a401c20..d237b7d64f4 100644 --- a/source/blender/render/intern/source/zbufferdatastruct.c +++ b/source/blender/render/intern/source/zbufferdatastruct.c @@ -262,7 +262,7 @@ void insertFlatObjectNoOsa(RE_APixstrExt *ap, int dist, int mask) { - int counter; + int counter=0; while(ap) { if(ap->t[0] == RE_NONE) { diff --git a/source/blender/src/butspace.c b/source/blender/src/butspace.c index 0c5b07d4b38..b0917a1123d 100644 --- a/source/blender/src/butspace.c +++ b/source/blender/src/butspace.c @@ -288,7 +288,7 @@ void do_butspace(unsigned short event) do_fontbuts(event); } else if(event<=B_CAMBUTS) { - ; + do_cambuts(event); } else if(event<=B_MBALLBUTS) { do_mballbuts(event); diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 92275e67950..c55574d9791 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -1344,10 +1344,10 @@ static void editing_panel_camera_type(Object *ob, Camera *cam) uiDefButF(block, NUM,REDRAWVIEW3D, "DrawSize:", 470,90,160,20, &cam->drawsize, 0.1*grid, 10.0, 10, 0, "Specify the drawsize of the camera"); - uiDefButS(block, TOG, REDRAWVIEW3D, "Ortho", 470,49,61,40, &cam->type, 0, 0, 0, 0, "Render orthogonally"); + uiDefButS(block, TOG, REDRAWVIEW3D, "Ortho", 470,29,61,60, &cam->type, 0, 0, 0, 0, "Render orthogonally"); uiBlockBeginAlign(block); - uiDefButS(block, TOG|BIT|0,REDRAWVIEW3D, "ShowLimits", 533,69,97,20, &cam->flag, 0, 0, 0, 0, "Draw the field of view"); - uiDefButS(block, TOG|BIT|1,REDRAWVIEW3D, "Show Mist", 533,49,97,20, &cam->flag, 0, 0, 0, 0, "Draw a line that indicates the mist area"); + uiDefButS(block, TOG|BIT|0,REDRAWVIEW3D, "ShowLimits", 533,59,97,30, &cam->flag, 0, 0, 0, 0, "Draw the field of view"); + uiDefButS(block, TOG|BIT|1,REDRAWVIEW3D, "Show Mist", 533,29,97,30, &cam->flag, 0, 0, 0, 0, "Draw a line that indicates the mist area"); uiBlockEndAlign(block); } @@ -1379,6 +1379,23 @@ static void editing_panel_camera_yafraydof(Object *ob, Camera *cam) } +/* **************************** CAMERA *************************** */ + +void do_cambuts(unsigned short event) +{ + Object *ob; + Camera *cam; + + ob= OBACT; + if (ob==0) return; + cam= ob->data; + + switch(event) { + case 0: + ; + break; + } +} /* *************************** MBALL ******************************** */ diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 2db758f35fb..8072262839a 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -763,6 +763,14 @@ void do_render_panels(unsigned short event) BIF_redraw_render_rect(); } break; + case B_SET_EDGE: + G.scene->r.mode &= ~R_ZBLUR; + allqueue(REDRAWBUTSSCENE, 0); + break; + case B_SET_ZBLUR: + G.scene->r.mode &= ~R_EDGE; + allqueue(REDRAWBUTSSCENE, 0); + break; } } @@ -1031,23 +1039,6 @@ static void render_panel_output(void) uiDefButS(block, TOG|BIT|4, 0, "Extensions", 205, 10, 105, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds extensions to the output when rendering animations"); - /* Dither control */ - uiDefButF(block, NUM,B_DIFF, "Dither:", 205,31,105,19, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)"); - - /* Toon shading buttons */ - uiBlockBeginAlign(block); - uiDefButI(block, TOG|BIT|5, 0,"Edge", 100, 94, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon edge shading"); - uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 170, 94, 140, 20, "Display edge settings"); - - /* postprocess render buttons */ - uiBlockBeginAlign(block); - if(R.rectftot) - uiDefIconTextButI(block, TOG|BIT|18, B_NOP, ICON_IMAGE_DEHLT," Fbuf", 100, 68, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render; buffer available"); - else - uiDefButI(block, TOG|BIT|18, 0,"Fbuf", 100, 68, 70, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render, no buffer available now"); - uiDefBlockBut(block, post_render_menu, NULL, "Post process", 170, 68, 140, 20, "Applies on RGBA floats while render or with Fbuf available"); - uiBlockEndAlign(block); - /* removed, for time being unified and normal render will use same gamma for blending (2.0) */ //if (G.scene->r.mode & R_GAMMA) { // uiDefButF(block, NUMSLI, 0,"Gamma:", 10, 68, 142, 20, @@ -1093,7 +1084,7 @@ static void render_panel_render(void) uiDefButS(block, ROW,800,"Premul", 405,13,50,20,&G.scene->r.alphamode,3.0,1.0, 0, 0, "Multiply alpha in advance"); uiDefButS(block, ROW,800,"Key", 456,13,35,20,&G.scene->r.alphamode,3.0,2.0, 0, 0, "Alpha and colour values remain unchanged"); uiBlockEndAlign(block); - + if(G.scene->r.mode & R_RAYTRACE) uiDefButS(block, MENU, B_DIFF,"Octree resolution %t|64 %x64|128 %x128|256 %x256|512 %x512", 496,13,64,20,&G.scene->r.ocres,0.0,0.0, 0, 0, "Octree resolution for ray tracing"); @@ -1317,12 +1308,12 @@ static void render_panel_yafrayGlobal() uiDefButF(block, NUMSLI, B_DIFF,"Bi ", 5,35,150,20, &(G.scene->r.YF_raybias), 0.0, 10.0 ,0,0, "Shadow ray bias to avoid self shadowing"); - uiDefButI(block, NUM, B_DIFF, "Raydepth ", 5,60,150,20, + uiDefButI(block, NUM, B_DIFF, "Raydepth ", 5,60,150,20, &G.scene->r.YF_raydepth, 1.0, 80.0, 10, 10, "Maximum render ray depth from the camera"); uiDefButF(block, NUMSLI, B_DIFF, "Gam ", 5,10,150,20, &G.scene->r.YF_gamma, 0.001, 5.0, 0, 0, "Gamma correction, 1 is off"); uiDefButF(block, NUMSLI, B_DIFF, "Exp ", 160,10,150,20,&G.scene->r.YF_exposure, 0.0, 10.0, 0, 0, "Exposure adjustment, 0 is off"); - uiDefButI(block, NUM, B_DIFF, "Processors:", 160,35,150,20, + uiDefButI(block, NUM, B_DIFF, "Processors:", 160,35,150,20, &G.scene->r.YF_numprocs, 1.0, 8.0, 10, 10, "Number of processors to use"); /*AA Settings*/ @@ -1339,11 +1330,48 @@ static void render_panel_yafrayGlobal() } } +static void render_panel_sfx(void) +{ + uiBlock *block; + + block= uiNewBlock(&curarea->uiblocks, "editing_panel_camera_dof", UI_EMBOSS, UI_HELV, curarea->win); + uiNewPanelTabbed("Output", "Render"); + if(uiNewPanel(curarea, block, "Post Effects", "Render", 320, 0, 318, 204)==0) return; + + uiBlockBeginAlign(block); + uiDefButI(block, TOG|BIT|20,B_SET_ZBLUR,"Zblur", 10,180,140,20,&G.scene->r.mode,0,0, 0, 0, "Apply blur based on depth values in z-buffer"); + uiDefButF(block, NUM,B_DIFF, "ZMin:", 10,160,140,20, &G.scene->r.zmin, 0.0, 1.0, 0, 0, "Specify the start distance with maximum blur"); + uiDefButF(block, NUM,B_DIFF, "Focus:", 10,140,140,20, &G.scene->r.focus, 0.0, 1.0, 0, 0, "Specify the focus distance (not blurred)"); + uiDefButF(block, NUM,B_DIFF, "Blur:", 10,120,140,20, &G.scene->r.zblur, 1.0, 100.0, 0, 0, "Specify the maximum blur radius"); + uiDefButF(block, NUM,B_DIFF, "Gamma:", 10,100,140,20, &G.scene->r.zgamma, 0.05, 2.0, 0, 0, "Use Gamma corrected addition of colors"); + uiDefButF(block, NUM,B_DIFF, "Sigma:", 10,80,140,20, &G.scene->r.zsigma, 1.0, 20.0, 0, 0, "Filter type control, higher value is stronger gaussian"); + + /* Toon shading buttons */ + uiBlockBeginAlign(block); + uiDefButI(block, TOG|BIT|5, B_SET_EDGE, "Edge", 160, 180, 150, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon edge shading"); + uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 160, 160, 150, 20, "Display edge settings"); + + /* postprocess render buttons */ + uiBlockBeginAlign(block); + if(R.rectftot) + uiDefIconTextButI(block, TOG|BIT|18, B_NOP, ICON_IMAGE_DEHLT," Fbuf", 160, 130, 150, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render; buffer available"); + else + uiDefButI(block, TOG|BIT|18, 0,"Fbuf", 160, 130, 150, 20, &G.scene->r.mode, 0, 0, 0, 0, "Keep RGBA float buffer after render, no buffer available now"); + uiDefBlockBut(block, post_render_menu, NULL, "Post process", 160, 110, 150, 20, "Applies on RGBA floats while render or with Fbuf available"); + uiBlockEndAlign(block); + + /* Dither control */ + uiDefButF(block, NUM,B_DIFF, "Dither:", 160,80,150,20, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)"); + +} + + void render_panels() { render_panel_output(); + render_panel_sfx(); render_panel_render(); render_panel_anim(); render_panel_format(); diff --git a/source/blender/src/renderwin.c b/source/blender/src/renderwin.c index 07d95d2c1b3..ffa917530b0 100644 --- a/source/blender/src/renderwin.c +++ b/source/blender/src/renderwin.c @@ -365,15 +365,15 @@ static void renderwin_mouse_moved(RenderWin *rw) if (rw->flags & RW_FLAGS_PIXEL_EXAMINING) { int imgco[2]; char buf[64]; - unsigned int *pxl2; - unsigned char *pxl; + int *pxlz; // zbuffer is signed + char *pxl; if (R.rectot && renderwin_win_to_image_co(rw, rw->lmouse, imgco)) { pxl= (char*) &R.rectot[R.rectx*imgco[1] + imgco[0]]; if (R.rectz) { - pxl2= &R.rectz[R.rectx*imgco[1] + imgco[0]]; - sprintf(buf, "R: %d, G: %d, B: %d, A: %d, Z: %f", pxl[0], pxl[1], pxl[2], pxl[3], (float)(((float)*pxl2-(float)INT_MIN)/(float)UINT_MAX)); + pxlz= &R.rectz[R.rectx*imgco[1] + imgco[0]]; + sprintf(buf, "R: %d, G: %d, B: %d, A: %d, Z: %f", pxl[0], pxl[1], pxl[2], pxl[3], 0.5+0.5*( ((float)*pxlz)/(float)INT_MAX) ); } else { sprintf(buf, "R: %d, G: %d, B: %d, A: %d", pxl[0], pxl[1], pxl[2], pxl[3]); |