2 * $Id: CMP_defocus.c 10741 2007-05-20 15:52:29Z eeshlo $
4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2006 Blender Foundation.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
30 #include "../CMP_util.h"
32 /* ************ qdn: Defocus node ****************** */
33 static bNodeSocketType cmp_node_defocus_in
[]= {
34 { SOCK_RGBA
, 1, "Image", 0.8f
, 0.8f
, 0.8f
, 1.0f
, 0.0f
, 1.0f
},
35 { SOCK_VALUE
, 1, "Z", 0.8f
, 0.8f
, 0.8f
, 1.0f
, 0.0f
, 1.0f
},
38 static bNodeSocketType cmp_node_defocus_out
[]= {
39 { SOCK_RGBA
, 0, "Image", 0.0f
, 0.0f
, 0.0f
, 1.0f
, 0.0f
, 1.0f
},
44 // line coefs for point sampling & scancon. data.
45 typedef struct BokehCoeffs
{
48 float min_x
, min_y
, max_x
, max_y
;
51 // returns array of BokehCoeffs
52 // returns length of array in 'len_bkh',
53 // radius squared of inscribed disk in 'inradsq', needed in getWeight() test,
54 // BKH[8] is the data returned for the bokeh shape & bkh_b[4] is it's 2d bound
55 static void makeBokeh(char bktype
, char ro
, int* len_bkh
, float* inradsq
, BokehCoeffs BKH
[8], float bkh_b
[4])
57 float x0
, x1
, y0
, y1
, dx
, dy
, iDxy
;
58 float w
= MAX2(1e-5f
, ro
)*M_PI
/180.f
; // never reported stangely enough, but a zero offset causes missing center line...
59 float wi
= (360.f
/bktype
)*M_PI
/180.f
;
62 // bktype must be at least 3 & <= 8
63 bktype
= (bktype
<3) ? 3 : ((bktype
>8) ? 8 : bktype
);
67 for (i
=0; i
<(*len_bkh
); i
++) {
74 // radius squared of inscribed disk
75 float idx
=(x0
+x1
)*0.5f
, idy
=(y0
+y1
)*0.5f
;
76 *inradsq
= idx
*idx
+ idy
*idy
;
80 dx
= x1
-x0
, dy
= y1
-y0
;
81 iDxy
= 1.f
/ sqrt(dx
*dx
+ dy
*dy
);
88 // precalc scanconversion data
89 // bokeh bound, not transformed, for scanconvert
90 bkh_b
[0] = bkh_b
[2] = 1e10f
; // xmin/ymin
91 bkh_b
[1] = bkh_b
[3] = -1e10f
; // xmax/ymax
93 for (nv
=0; nv
<(*len_bkh
); nv
++) {
94 bkh_b
[0] = MIN2(bkh_b
[0], BKH
[nv
].x0
); // xmin
95 bkh_b
[1] = MAX2(bkh_b
[1], BKH
[nv
].x0
); // xmax
96 bkh_b
[2] = MIN2(bkh_b
[2], BKH
[nv
].y0
); // ymin
97 bkh_b
[3] = MAX2(bkh_b
[3], BKH
[nv
].y0
); // ymax
98 BKH
[nv
].min_x
= MIN2(BKH
[ov
].x0
, BKH
[nv
].x0
);
99 BKH
[nv
].max_x
= MAX2(BKH
[ov
].x0
, BKH
[nv
].x0
);
100 BKH
[nv
].min_y
= MIN2(BKH
[ov
].y0
, BKH
[nv
].y0
);
101 BKH
[nv
].max_y
= MAX2(BKH
[ov
].y0
, BKH
[nv
].y0
);
102 dy
= BKH
[nv
].y0
- BKH
[ov
].y0
;
103 BKH
[nv
].ls_x
= (BKH
[nv
].x0
- BKH
[ov
].x0
) / ((dy
==0.f
) ? 1.f
: dy
);
104 BKH
[nv
].ls_y
= (BKH
[nv
].ls_x
==0.f
) ? 1.f
: (1.f
/BKH
[nv
].ls_x
);
109 // test if u/v inside shape & returns weight value
110 static float getWeight(BokehCoeffs
* BKH
, int len_bkh
, float u
, float v
, float rad
, float inradsq
)
112 BokehCoeffs
* bc
= BKH
;
113 float cdist
, irad
= (rad
==0.f
) ? 1.f
: (1.f
/rad
);
117 // early out test1: if point outside outer unit disk, it cannot be inside shape
119 if (cdist
>1.f
) return 0.f
;
121 // early out test2: if point inside or on inner disk, point must be inside shape
122 if (cdist
<=inradsq
) return 1.f
;
125 if ((bc
->dy
*(u
- bc
->x0
) - bc
->dx
*(v
- bc
->y0
)) > 0.f
) return 0.f
;
131 // QMC.seq. for sampling, A.Keller, EMS
132 static float RI_vdC(unsigned int bits
, unsigned int r
)
134 bits
= ( bits
<< 16) | ( bits
>> 16);
135 bits
= ((bits
& 0x00ff00ff) << 8) | ((bits
& 0xff00ff00) >> 8);
136 bits
= ((bits
& 0x0f0f0f0f) << 4) | ((bits
& 0xf0f0f0f0) >> 4);
137 bits
= ((bits
& 0x33333333) << 2) | ((bits
& 0xcccccccc) >> 2);
138 bits
= ((bits
& 0x55555555) << 1) | ((bits
& 0xaaaaaaaa) >> 1);
140 return (float)((double)bits
/ 4294967296.0);
143 // single channel IIR gaussian filtering
144 // much faster than anything else, constant time independent of width
145 // should extend to multichannel and make this a node, could be useful
146 static void IIR_gauss_single(CompBuf
* buf
, float sigma
)
148 double q
, q2
, sc
, cf
[4], tsM
[9], tsu
[3], tsv
[3];
152 // single channel only for now
153 if (buf
->type
!= CB_VAL
) return;
155 // <0.5 not valid, though can have a possibly useful sort of sharpening effect
156 if (sigma
< 0.5) return;
158 // see "Recursive Gabor Filtering" by Young/VanVliet
159 // all factors here in double.prec. Required, because for single.prec it seems to blow up if sigma > ~200
161 q
= 0.9804*(sigma
- 3.556) + 2.5091;
163 q
= (0.0561*sigma
+ 0.5784)*sigma
- 0.2568;
165 sc
= (1.1668 + q
)*(3.203729649 + (2.21566 + q
)*q
);
166 // no gabor filtering here, so no complex multiplies, just the regular coefs.
167 // all negated here, so as not to have to recalc Triggs/Sdika matrix
168 cf
[1] = q
*(5.788961737 + (6.76492 + 3.0*q
)*q
)/ sc
;
169 cf
[2] = -q2
*(3.38246 + 3.0*q
)/sc
;
172 cf
[0] = 1.0 - cf
[1] - cf
[2] - cf
[3];
174 // Triggs/Sdika border corrections,
175 // it seems to work, not entirely sure if it is actually totally correct,
176 // Besides J.M.Geusebroek's anigauss.c (see http://www.science.uva.nl/~mark),
177 // found one other implementation by Cristoph Lampert,
178 // but neither seem to be quite the same, result seems to be ok sofar anyway.
179 // Extra scale factor here to not have to do it in filter,
180 // though maybe this had something to with the precision errors
181 sc
= cf
[0]/((1.0 + cf
[1] - cf
[2] + cf
[3])*(1.0 - cf
[1] - cf
[2] - cf
[3])*(1.0 + cf
[2] + (cf
[1] - cf
[3])*cf
[3]));
182 tsM
[0] = sc
*(-cf
[3]*cf
[1] + 1.0 - cf
[3]*cf
[3] - cf
[2]);
183 tsM
[1] = sc
*((cf
[3] + cf
[1])*(cf
[2] + cf
[3]*cf
[1]));
184 tsM
[2] = sc
*(cf
[3]*(cf
[1] + cf
[3]*cf
[2]));
185 tsM
[3] = sc
*(cf
[1] + cf
[3]*cf
[2]);
186 tsM
[4] = sc
*(-(cf
[2] - 1.0)*(cf
[2] + cf
[3]*cf
[1]));
187 tsM
[5] = sc
*(-(cf
[3]*cf
[1] + cf
[3]*cf
[3] + cf
[2] - 1.0)*cf
[3]);
188 tsM
[6] = sc
*(cf
[3]*cf
[1] + cf
[2] + cf
[1]*cf
[1] - cf
[2]*cf
[2]);
189 tsM
[7] = sc
*(cf
[1]*cf
[2] + cf
[3]*cf
[2]*cf
[2] - cf
[1]*cf
[3]*cf
[3] - cf
[3]*cf
[3]*cf
[3] - cf
[3]*cf
[2] + cf
[3]);
190 tsM
[8] = sc
*(cf
[3]*(cf
[1] + cf
[3]*cf
[2]));
194 W[0] = cf[0]*X[0] + cf[1]*X[0] + cf[2]*X[0] + cf[3]*X[0];\
195 W[1] = cf[0]*X[1] + cf[1]*W[0] + cf[2]*X[0] + cf[3]*X[0];\
196 W[2] = cf[0]*X[2] + cf[1]*W[1] + cf[2]*W[0] + cf[3]*X[0];\
198 W[i] = cf[0]*X[i] + cf[1]*W[i-1] + cf[2]*W[i-2] + cf[3]*W[i-3];\
199 tsu[0] = W[L-1] - X[L-1];\
200 tsu[1] = W[L-2] - X[L-1];\
201 tsu[2] = W[L-3] - X[L-1];\
202 tsv[0] = tsM[0]*tsu[0] + tsM[1]*tsu[1] + tsM[2]*tsu[2] + X[L-1];\
203 tsv[1] = tsM[3]*tsu[0] + tsM[4]*tsu[1] + tsM[5]*tsu[2] + X[L-1];\
204 tsv[2] = tsM[6]*tsu[0] + tsM[7]*tsu[1] + tsM[8]*tsu[2] + X[L-1];\
205 Y[L-1] = cf[0]*W[L-1] + cf[1]*tsv[0] + cf[2]*tsv[1] + cf[3]*tsv[2];\
206 Y[L-2] = cf[0]*W[L-2] + cf[1]*Y[L-1] + cf[2]*tsv[0] + cf[3]*tsv[1];\
207 Y[L-3] = cf[0]*W[L-3] + cf[1]*Y[L-2] + cf[2]*Y[L-1] + cf[3]*tsv[0];\
208 for (i=L-4; i>=0; i--)\
209 Y[i] = cf[0]*W[i] + cf[1]*Y[i+1] + cf[2]*Y[i+2] + cf[3]*Y[i+3];\
212 // intermediate buffers
213 sz
= MAX2(buf
->x
, buf
->y
);
214 Y
= MEM_callocN(sz
*sizeof(float), "IIR_gauss Y buf");
215 W
= MEM_callocN(sz
*sizeof(float), "IIR_gauss W buf");
217 for (y
=0; y
<buf
->y
; y
++) {
218 X
= &buf
->rect
[y
*buf
->x
];
220 memcpy(X
, Y
, sizeof(float)*buf
->x
);
223 X
= MEM_callocN(buf
->y
*sizeof(float), "IIR_gauss X buf");
224 for (x
=0; x
<buf
->x
; x
++) {
225 for (y
=0; y
<buf
->y
; y
++)
226 X
[y
] = buf
->rect
[x
+ y
*buf
->x
];
228 for (y
=0; y
<buf
->y
; y
++)
229 buf
->rect
[x
+ y
*buf
->x
] = Y
[y
];
238 static void defocus_blur(bNode
*node
, CompBuf
*new, CompBuf
*img
, CompBuf
*zbuf
, float inpval
, int no_zbuf
)
240 NodeDefocus
*nqd
= node
->storage
;
241 CompBuf
*wts
; // weights buffer
242 CompBuf
*crad
; // CoC radius buffer
243 BokehCoeffs BKH
[8]; // bokeh shape data, here never > 8 pts.
244 float bkh_b
[4] = {0}; // shape 2D bound
245 unsigned int p
, px
, p4
, zp
, cp
, cp4
;
246 float *ctcol
, u
, v
, iZ
, ct_crad
, lwt
, wt
=0, cR2
=0;
247 float dof_sp
, maxfgc
, bk_hn_theta
=0, inradsq
=0;
248 float cam_fdist
=1, cam_invfdist
=1, cam_lens
=35;
249 int x
, y
, sx
, sy
, len_bkh
=0;
250 float aspect
, aperture
;
252 //float bcrad, nmaxc, scf;
254 // get some required params from the current scene camera
255 // (ton) this is wrong, needs fixed
256 Object
* camob
= G
.scene
->camera
;
257 if (camob
&& camob
->type
==OB_CAMERA
) {
258 Camera
* cam
= (Camera
*)camob
->data
;
259 cam_lens
= cam
->lens
;
260 cam_fdist
= (cam
->YF_dofdist
==0.f
) ? 1e10f
: cam
->YF_dofdist
;
261 cam_invfdist
= 1.f
/cam_fdist
;
264 // guess work here.. best match with raytraced result
265 minsz
= MIN2(img
->x
, img
->y
);
266 dof_sp
= (float)minsz
/ (16.f
/ cam_lens
); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov);
269 aspect
= (img
->x
> img
->y
) ? (img
->y
/ (float)img
->x
) : (img
->x
/ (float)img
->y
);
270 aperture
= 0.5f
*(cam_lens
/ (aspect
*32.f
)) / nqd
->fstop
;
272 // if not disk, make bokeh coefficients and other needed data
273 if (nqd
->bktype
!=0) {
274 makeBokeh(nqd
->bktype
, nqd
->rotation
, &len_bkh
, &inradsq
, BKH
, bkh_b
);
275 bk_hn_theta
= 0.5 * nqd
->bktype
* sin(2.0 * M_PI
/ nqd
->bktype
); // weight factor
278 // accumulated weights
279 wts
= alloc_compbuf(img
->x
, img
->y
, CB_VAL
, 1);
281 crad
= alloc_compbuf(img
->x
, img
->y
, CB_VAL
, 1);
283 // if 'no_zbuf' flag set (which is always set if input is not an image),
284 // values are instead interpreted directly as blur radius values
286 // to prevent *reaaallly* big radius values and impossible calculation times,
287 // limit the maximum to half the image width or height, whichever is smaller
288 float maxr
= 0.5f
*(float)MIN2(img
->x
, img
->y
);
289 for (p
=0; p
<(unsigned int)(img
->x
*img
->y
); p
++) {
290 crad
->rect
[p
] = zbuf
? (zbuf
->rect
[p
]*nqd
->scale
) : inpval
;
291 // bug #5921, limit minimum
292 crad
->rect
[p
] = MAX2(1e-5f
, crad
->rect
[p
]);
293 crad
->rect
[p
] = MIN2(crad
->rect
[p
], maxr
);
294 // if maxblur!=0, limit maximum
295 if (nqd
->maxblur
!= 0.f
) crad
->rect
[p
] = MIN2(crad
->rect
[p
], nqd
->maxblur
);
300 // separate foreground from background CoC's
301 // then blur background and blend in again with foreground,
302 // improves the 'blurred foreground overlapping in-focus midground' sharp boundary problem.
303 // wts buffer here used for blendmask
304 maxfgc
= 0.f
; // maximum foreground CoC radius
305 for (y
=0; y
<img
->y
; y
++) {
307 for (x
=0; x
<img
->x
; x
++) {
309 iZ
= (zbuf
->rect
[px
]==0.f
) ? 0.f
: (1.f
/zbuf
->rect
[px
]);
310 crad
->rect
[px
] = 0.5f
*(aperture
*(dof_sp
*(cam_invfdist
- iZ
) - 1.f
));
311 if (crad
->rect
[px
] <= 0.f
) {
313 crad
->rect
[px
] = -crad
->rect
[px
];
314 if (crad
->rect
[px
] > maxfgc
) maxfgc
= crad
->rect
[px
];
316 else crad
->rect
[px
] = wts
->rect
[px
] = 0;
321 // bug #6656 part 1, probably when previous node_composite.c was split into separate files, it was not properly updated
322 // to include recent cvs commits (well, at least not defocus node), so this part was missing...
324 IIR_gauss_single(crad
, wt
);
325 IIR_gauss_single(wts
, wt
);
327 // bug #6656 part 2a, although foreground blur is not based anymore on closest object,
328 // the rescaling op below was still based on that anyway, and unlike the comment in below code,
329 // the difference is therefore not always that small at all...
330 // so for now commented out, not sure if this is going to cause other future problems, lets just wait and see...
332 // find new maximum to scale it back to original
333 // (could skip this, not strictly necessary, in general, difference is quite small, but just in case...)
335 for (p=0; p<(img->x*img->y); p++)
336 if (crad->rect[p] > nmaxc) nmaxc = crad->rect[p];
338 scf = (nmaxc==0.f) ? 1.f: (maxfgc / nmaxc);
342 for (y
=0; y
<img
->y
; y
++) {
344 for (x
=0; x
<img
->x
; x
++) {
346 if (zbuf
->rect
[px
]!=0.f
) {
347 iZ
= (zbuf
->rect
[px
]==0.f
) ? 0.f
: (1.f
/zbuf
->rect
[px
]);
349 // bug #6656 part 2b, do not rescale
351 bcrad = 0.5f*fabs(aperture*(dof_sp*(cam_invfdist - iZ) - 1.f));
352 // scale crad back to original maximum and blend
353 crad->rect[px] = bcrad + wts->rect[px]*(scf*crad->rect[px] - bcrad);
355 crad
->rect
[px
] = 0.5f
*fabs(aperture
*(dof_sp
*(cam_invfdist
- iZ
) - 1.f
));
357 // 'bug' #6615, limit minimum radius to 1 pixel, not really a solution, but somewhat mitigates the problem
358 crad
->rect
[px
] = MAX2(crad
->rect
[px
], 0.5f
);
359 // if maxblur!=0, limit maximum
360 if (nqd
->maxblur
!= 0.f
) crad
->rect
[px
] = MIN2(crad
->rect
[px
], nqd
->maxblur
);
362 else crad
->rect
[px
] = 0.f
;
363 // clear weights for next part
366 // esc set by main calling process
367 if(node
->exec
& NODE_BREAK
)
372 //------------------------------------------------------------------
374 for (y
=0; y
<img
->y
; y
++) {
375 // some sort of visual feedback would be nice, or at least this text in the renderwin header
376 // but for now just print some info in the console every 8 scanlines.
377 if (((y
& 7)==0) || (y
==(img
->y
-1))) {
378 printf("\rdefocus: Processing Line %d of %d ... ", y
+1, img
->y
);
381 // esc set by main calling process
382 if(node
->exec
& NODE_BREAK
)
386 for (x
=0; x
<img
->x
; x
++) {
388 cp4
= cp
* img
->type
;
390 // Circle of Confusion radius for current pixel
391 cR2
= ct_crad
= crad
->rect
[cp
];
392 // skip if zero (border render)
394 // related to bug #5921, forgot output image when skipping 0 radius values
395 new->rect
[cp4
] = img
->rect
[cp4
];
396 if (new->type
!= CB_VAL
) {
397 new->rect
[cp4
+1] = img
->rect
[cp4
+1];
398 new->rect
[cp4
+2] = img
->rect
[cp4
+2];
399 new->rect
[cp4
+3] = img
->rect
[cp4
+3];
406 ctcol
= &img
->rect
[cp4
];
410 float lwt
, wtcol
[4] = {0}, aacol
[4] = {0};
413 if (nqd
->bktype
==0) // disk
414 wt
= 1.f
/((float)M_PI
*cR2
);
416 wt
= 1.f
/(cR2
*bk_hn_theta
);
419 wtcol
[0] = wt
*ctcol
[0];
420 if (new->type
!= CB_VAL
) {
421 wtcol
[1] = wt
*ctcol
[1];
422 wtcol
[2] = wt
*ctcol
[2];
423 wtcol
[3] = wt
*ctcol
[3];
426 // macro for background blur overlap test
427 // unfortunately, since this is done per pixel,
428 // it has a very significant negative impact on processing time...
429 // (eg. aa disk blur without test: 112 sec, vs with test: 176 sec...)
430 // iff center blur radius > threshold
431 // and if overlap pixel in focus, do nothing, else add color/weigbt
432 // (threshold constant is dependant on amount of blur)
433 #define TESTBG1(c, w) {\
434 if (ct_crad > nqd->bthresh) {\
435 if (crad->rect[p] > nqd->bthresh) {\
436 new->rect[p] += c[0];\
441 new->rect[p] += c[0];\
445 #define TESTBG4(c, w) {\
446 if (ct_crad > nqd->bthresh) {\
447 if (crad->rect[p] > nqd->bthresh) {\
448 new->rect[p4] += c[0];\
449 new->rect[p4+1] += c[1];\
450 new->rect[p4+2] += c[2];\
451 new->rect[p4+3] += c[3];\
456 new->rect[p4] += c[0];\
457 new->rect[p4+1] += c[1];\
458 new->rect[p4+2] += c[2];\
459 new->rect[p4+3] += c[3];\
463 if (nqd
->bktype
== 0) {
468 #define AAPIX(a, b) {\
470 if ((_ny >= 0) && (_ny < new->y)) {\
472 if ((_nx >=0) && (_nx < new->x)) {\
473 p = _ny*new->x + _nx;\
474 if (new->type==CB_VAL) {\
475 TESTBG1(aacol, lwt);\
479 TESTBG4(aacol, lwt);\
485 #define CSCAN(a, b) {\
487 if ((_ny >= 0) && (_ny < new->y)) {\
491 if (xe > new->x) xe = new->x;\
492 p = _ny*new->x + xs;\
493 if (new->type==CB_VAL) {\
494 for (_x=xs; _x<xe; _x++, p++) TESTBG1(wtcol, wt);\
498 for (_x=xs; _x<xe; _x++, p++, p4+=new->type) TESTBG4(wtcol, wt);\
506 Dj
= sqrt(cR2
- j
*j
);
509 if (Dj
> T
) { i
--; di
= 1; }
511 aacol
[0] = wtcol
[0]*Dj
;
512 if (new->type
!= CB_VAL
) {
513 aacol
[1] = wtcol
[1]*Dj
;
514 aacol
[2] = wtcol
[2]*Dj
;
515 aacol
[3] = wtcol
[3]*Dj
;
523 AAPIX(x
-j
, y
+i
); // BL
524 AAPIX(x
-j
, y
-i
); // TL
526 if (di
) { // only when i changed, interior of outer section
527 CSCAN(j
, i
); // bottom
533 if (i
) AAPIX(x
-i
, y
+j
);
538 if (i
) AAPIX(x
-i
, y
-j
);
549 float mind
, maxd
, lwt
;
550 ys
= MAX2((int)floor(bkh_b
[2]*ct_crad
+ y
), 0);
551 ye
= MIN2((int)ceil(bkh_b
[3]*ct_crad
+ y
), new->y
- 1);
552 for (sy
=ys
; sy
<=ye
; sy
++) {
553 float fxs
= 1e10f
, fxe
= -1e10f
;
554 float yf
= (sy
- y
)/ct_crad
;
558 for (nv
=0; nv
<len_bkh
; nv
++) {
559 if ((BKH
[nv
].max_y
>= yf
) && (BKH
[nv
].min_y
<= yf
)) {
560 float tx
= BKH
[ov
].x0
+ BKH
[nv
].ls_x
*(yf
- BKH
[ov
].y0
);
561 if (tx
< fxs
) { fxs
= tx
; mind
= BKH
[nv
].ls_x
; }
562 if (tx
> fxe
) { fxe
= tx
; maxd
= BKH
[nv
].ls_x
; }
563 if (++found
== 2) break;
568 fxs
= fxs
*ct_crad
+ x
;
569 fxe
= fxe
*ct_crad
+ x
;
570 xs
= (int)floor(fxs
), xe
= (int)ceil(fxe
);
571 // AA hack for first and last x pixel, near vertical edges only
572 if (fabs(mind
) <= 1.f
) {
573 if ((xs
>= 0) && (xs
< new->x
)) {
574 lwt
= 1.f
-(fxs
- xs
);
575 aacol
[0] = wtcol
[0]*lwt
;
577 if (new->type
==CB_VAL
) {
583 aacol
[1] = wtcol
[1]*lwt
;
584 aacol
[2] = wtcol
[2]*lwt
;
585 aacol
[3] = wtcol
[3]*lwt
;
591 if (fabs(maxd
) <= 1.f
) {
592 if ((xe
>= 0) && (xe
< new->x
)) {
593 lwt
= 1.f
-(xe
- fxe
);
594 aacol
[0] = wtcol
[0]*lwt
;
596 if (new->type
==CB_VAL
) {
602 aacol
[1] = wtcol
[1]*lwt
;
603 aacol
[2] = wtcol
[2]*lwt
;
604 aacol
[3] = wtcol
[3]*lwt
;
611 xe
= MIN2(xe
, new->x
);
612 // remaining interior scanline
614 if (new->type
==CB_VAL
) {
615 for (sx
=xs
; sx
<xe
; sx
++, p
++) TESTBG1(wtcol
, wt
);
619 for (sx
=xs
; sx
<xe
; sx
++, p
++, p4
+=new->type
) TESTBG4(wtcol
, wt
);
624 // now traverse in opposite direction, y scanlines,
625 // but this time only draw the near horizontal edges,
626 // applying same AA hack as above
627 xs
= MAX2((int)floor(bkh_b
[0]*ct_crad
+ x
), 0);
628 xe
= MIN2((int)ceil(bkh_b
[1]*ct_crad
+ x
), img
->x
- 1);
629 for (sx
=xs
; sx
<=xe
; sx
++) {
630 float xf
= (sx
- x
)/ct_crad
;
631 float fys
= 1e10f
, fye
= -1e10f
;
635 for (nv
=0; nv
<len_bkh
; nv
++) {
636 if ((BKH
[nv
].max_x
>= xf
) && (BKH
[nv
].min_x
<= xf
)) {
637 float ty
= BKH
[ov
].y0
+ BKH
[nv
].ls_y
*(xf
- BKH
[ov
].x0
);
638 if (ty
< fys
) { fys
= ty
; mind
= BKH
[nv
].ls_y
; }
639 if (ty
> fye
) { fye
= ty
; maxd
= BKH
[nv
].ls_y
; }
640 if (++found
== 2) break;
645 fys
= fys
*ct_crad
+ y
;
646 fye
= fye
*ct_crad
+ y
;
647 // near horizontal edges only, line slope <= 1
648 if (fabs(mind
) <= 1.f
) {
649 int iys
= (int)floor(fys
);
650 if ((iys
>= 0) && (iys
< new->y
)) {
651 lwt
= 1.f
- (fys
- iys
);
652 aacol
[0] = wtcol
[0]*lwt
;
654 if (new->type
==CB_VAL
) {
660 aacol
[1] = wtcol
[1]*lwt
;
661 aacol
[2] = wtcol
[2]*lwt
;
662 aacol
[3] = wtcol
[3]*lwt
;
668 if (fabs(maxd
) <= 1.f
) {
670 if ((iye
>= 0) && (iye
< new->y
)) {
671 lwt
= 1.f
- (iye
- fye
);
672 aacol
[0] = wtcol
[0]*lwt
;
674 if (new->type
==CB_VAL
) {
680 aacol
[1] = wtcol
[1]*lwt
;
681 aacol
[2] = wtcol
[2]*lwt
;
682 aacol
[3] = wtcol
[3]*lwt
;
697 // sampled, simple rejection sampling here, good enough
698 unsigned int maxsam
, s
, ui
= BLI_rand()*BLI_rand();
699 float wcor
, cpr
= BLI_frand();
701 maxsam
= nqd
->samples
; // no zbuffer input, use sample value directly
703 // depth adaptive sampling hack, the more out of focus, the more samples taken, 16 minimum.
704 maxsam
= (int)(0.5f
+ nqd
->samples
*(1.f
-(float)exp(-fabs(zbuf
->rect
[cp
] - cam_fdist
))));
705 if (maxsam
< 16) maxsam
= 16;
707 wcor
= 1.f
/(float)maxsam
;
708 for (s
=0; s
<maxsam
; ++s
) {
709 u
= ct_crad
*(2.f
*RI_vdC(s
, ui
) - 1.f
);
710 v
= ct_crad
*(2.f
*(s
+ cpr
)/(float)maxsam
- 1.f
);
711 sx
= (int)(x
+ u
+ 0.5f
), sy
= (int)(y
+ v
+ 0.5f
);
712 if ((sx
<0) || (sx
>= new->x
) || (sy
<0) || (sy
>= new->y
)) continue;
715 if (nqd
->bktype
==0) // Disk
716 lwt
= ((u
*u
+ v
*v
)<=cR2
) ? wcor
: 0.f
;
717 else // AA not needed here
718 lwt
= wcor
* getWeight(BKH
, len_bkh
, u
, v
, ct_crad
, inradsq
);
719 // prevent background bleeding onto in-focus pixels, user-option
720 if (ct_crad
> nqd
->bthresh
) { // if center blur > threshold
721 if (crad
->rect
[p
] > nqd
->bthresh
) { // if overlap pixel in focus, do nothing, else add color/weigbt
722 new->rect
[p4
] += ctcol
[0] * lwt
;
723 if (new->type
!= CB_VAL
) {
724 new->rect
[p4
+1] += ctcol
[1] * lwt
;
725 new->rect
[p4
+2] += ctcol
[2] * lwt
;
726 new->rect
[p4
+3] += ctcol
[3] * lwt
;
732 new->rect
[p4
] += ctcol
[0] * lwt
;
733 if (new->type
!= CB_VAL
) {
734 new->rect
[p4
+1] += ctcol
[1] * lwt
;
735 new->rect
[p4
+2] += ctcol
[2] * lwt
;
736 new->rect
[p4
+3] += ctcol
[3] * lwt
;
746 // finally, normalize
747 for (y
=0; y
<new->y
; y
++) {
750 for (x
=0; x
<new->x
; x
++) {
751 float dv
= (wts
->rect
[p
]==0.f
) ? 1.f
: (1.f
/wts
->rect
[p
]);
753 if (new->type
!=CB_VAL
) {
754 new->rect
[p4
+1] *= dv
;
755 new->rect
[p4
+2] *= dv
;
756 new->rect
[p4
+3] *= dv
;
770 static void node_composit_exec_defocus(void *data
, bNode
*node
, bNodeStack
**in
, bNodeStack
**out
)
772 CompBuf
*new, *old
, *zbuf_use
= NULL
, *img
= in
[0]->data
, *zbuf
= in
[1]->data
;
773 NodeDefocus
*nqd
= node
->storage
;
774 int no_zbuf
= nqd
->no_zbuf
;
776 if ((img
==NULL
) || (out
[0]->hasoutput
==0)) return;
778 // if image not valid type or fstop==infinite (128), nothing to do, pass in to out
779 if (((img
->type
!=CB_RGBA
) && (img
->type
!=CB_VAL
)) || ((no_zbuf
==0) && (nqd
->fstop
==128.f
))) {
780 out
[0]->data
= pass_on_compbuf(img
);
785 // Zbuf input, check to make sure, single channel, same size
786 // doesn't have to be actual zbuffer, but must be value type
787 if ((zbuf
->x
!= img
->x
) || (zbuf
->y
!= img
->y
)) {
788 // could do a scale here instead...
789 printf("Z input must be same size as image !\n");
792 zbuf_use
= typecheck_compbuf(zbuf
, CB_VAL
);
794 else no_zbuf
= 1; // no zbuffer input
799 // gamma correct, blender func is simplified, fixed value & RGBA only,
800 // should make user param. also depremul and premul afterwards, gamma
801 // correction can't work with premul alpha
802 old
= dupalloc_compbuf(img
);
803 premul_compbuf(old
, 1);
804 gamma_correct_compbuf(old
, 0);
805 premul_compbuf(old
, 0);
808 new = alloc_compbuf(old
->x
, old
->y
, old
->type
, 1);
809 defocus_blur(node
, new, old
, zbuf_use
, in
[1]->vec
[0]*nqd
->scale
, no_zbuf
);
812 premul_compbuf(new, 1);
813 gamma_correct_compbuf(new, 1);
814 premul_compbuf(new, 0);
817 if(node
->exec
& NODE_BREAK
) {
822 if (zbuf_use
&& (zbuf_use
!= zbuf
)) free_compbuf(zbuf_use
);
825 static void node_composit_init_defocus(bNode
* node
)
827 /* qdn: defocus node */
828 NodeDefocus
*nbd
= MEM_callocN(sizeof(NodeDefocus
), "node defocus data");
842 bNodeType cmp_node_defocus
= {
843 /* *next,*prev */ NULL
, NULL
,
844 /* type code */ CMP_NODE_DEFOCUS
,
845 /* name */ "Defocus",
846 /* width+range */ 150, 120, 200,
847 /* class+opts */ NODE_CLASS_OP_FILTER
, NODE_OPTIONS
,
848 /* input sock */ cmp_node_defocus_in
,
849 /* output sock */ cmp_node_defocus_out
,
850 /* storage */ "NodeDefocus",
851 /* execfunc */ node_composit_exec_defocus
,
853 /* initfunc */ node_composit_init_defocus
,
854 /* freestoragefunc */ node_free_standard_storage
,
855 /* copystoragefunc */ node_copy_standard_storage
,