The zblur plugin (aka as DoF) integrated in render. Compared to patch
authorTon Roosendaal <ton@blender.org>
Sat, 23 Apr 2005 20:49:23 +0000 (20:49 +0000)
committerTon Roosendaal <ton@blender.org>
Sat, 23 Apr 2005 20:49:23 +0000 (20:49 +0000)
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. :)

16 files changed:
source/blender/blenkernel/intern/scene.c
source/blender/blenloader/intern/readfile.c
source/blender/include/BIF_editview.h
source/blender/include/butspace.h
source/blender/makesdna/DNA_camera_types.h
source/blender/makesdna/DNA_scene_types.h
source/blender/render/SConscript
source/blender/render/intern/include/zblur.h [new file with mode: 0644]
source/blender/render/intern/source/initrender.c
source/blender/render/intern/source/shadbuf.c
source/blender/render/intern/source/zblur.c [new file with mode: 0644]
source/blender/render/intern/source/zbufferdatastruct.c
source/blender/src/butspace.c
source/blender/src/buttons_editing.c
source/blender/src/buttons_scene.c
source/blender/src/renderwin.c

index f5916fb17b02144dc0712b41fbe43a43f8f222fa..aebfa54fe1e9cd187f88221e4adc0dccd7a1cf45 100644 (file)
@@ -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;
index e1c65dba34476c7c0c6047cd06a733fe56a027c2..ff3953296dfc4285e6648b7091be1a473fbe2708 100644 (file)
@@ -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! */
index 1cbee01f99bb3533529a1f41bfc97637158c2e36..345f21cdb9e5b263da2607aa24e1b1051892d4c4 100644 (file)
@@ -35,6 +35,7 @@
 
 struct Base;
 struct Object;
+struct Camera;
 
 void   arrows_move_cursor(unsigned short event);
 void   borderselect(void);
index 4b5f5a672589026b37cfe9c1932b5bff352ae56c..755b5c127fa5b44e65ba013ee91451dfb00ba7b6 100644 (file)
@@ -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 {
index 8b6f0eb369b7052989f61968f8c27a473055883d..2041aae3429b0f517de20de65a2af2de3ad72b3b 100644 (file)
@@ -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
index 8d6fed13b883857b22661e70cb969ca3cb7b7781..d285a46c3ae9f74c55c360c90a162625ea8ac496 100644 (file)
@@ -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
index 1537f402f7a82b9ce7e32ab0bd74686634afe163..71be91f1be3398a6f49a86be5f4d4756c1d17a9b 100644 (file)
@@ -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 (file)
index 0000000..a0e1c6a
--- /dev/null
@@ -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
+
index c4668a9f816f02f990406cdf0cbec6a5ebed6234..24f836688cf2602780f296ce178957536e364449 100644 (file)
@@ -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);
                        }
index 8510df2de3d10f207b15cba0b7d5315e4f667cf9..c942232bebba0ddfef6d879a49cfbbfab0a2ab4a 100644 (file)
@@ -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 (file)
index 0000000..4cb1e01
--- /dev/null
@@ -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();
+}
+
+
index 4ab8a401c2092a36d21ad9eec772c283aac3dca0..d237b7d64f474c7ebfb8d0c75a23662ec8932a2c 100644 (file)
@@ -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) {
index 0c5b07d4b3889b90b79851609aed548373793f28..b0917a1123db08dfa2b2ca7734ff7302b7919913 100644 (file)
@@ -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);
index 92275e679502dd824f9d86fd04dce8deb6fb6d01..c55574d97915216243799134c32ca05ef883cbed 100644 (file)
@@ -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 ******************************** */
 
index 2db758f35fb309c695345132ff23e067184f887e..8072262839aa8d0309057f3846064ba5a7f12bf7 100644 (file)
@@ -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();
index 07d95d2c1b31b3a89c9c47b5fffe9f5ac863bec5..ffa917530b0f898875fc36778eda15ac1956e8d7 100644 (file)
@@ -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]);