2 * $Id: rendercore.c 12781 2007-12-04 15:11:33Z blendix $
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) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * Contributors: Hos, Robert Wenzlaff.
24 * Contributors: 2004/2005/2006 Blender Foundation, full recode
26 * ***** END GPL LICENSE BLOCK *****
34 /* External modules: */
35 #include "MEM_guardedalloc.h"
37 #include "BLI_arithb.h"
38 #include "BLI_blenlib.h"
39 #include "BLI_jitter.h"
41 #include "BLI_threads.h"
43 #include "BKE_utildefines.h"
45 #include "DNA_image_types.h"
46 #include "DNA_lamp_types.h"
47 #include "DNA_material_types.h"
48 #include "DNA_meshdata_types.h"
50 #include "BKE_global.h"
51 #include "BKE_image.h"
54 #include "BKE_texture.h"
56 #include "IMB_imbuf_types.h"
57 #include "IMB_imbuf.h"
60 #include "renderpipeline.h"
61 #include "render_types.h"
62 #include "renderdatabase.h"
63 #include "pixelblending.h"
64 #include "pixelshading.h"
73 #include "rendercore.h"
76 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
77 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
78 /* only to be used here in this file, it's for speed */
79 extern struct Render R
;
80 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
82 /* x and y are current pixels in rect to be rendered */
83 /* do not normalize! */
84 void calc_view_vector(float *view
, float x
, float y
)
87 view
[2]= -ABS(R
.clipsta
);
89 if(R
.r
.mode
& R_ORTHO
) {
90 view
[0]= view
[1]= 0.0f
;
94 if(R
.r
.mode
& R_PANORAMA
)
97 /* move x and y to real viewplane coords */
99 view
[0]= R
.viewplane
.xmin
+ x
*(R
.viewplane
.xmax
- R
.viewplane
.xmin
);
101 y
= (y
/(float)R
.winy
);
102 view
[1]= R
.viewplane
.ymin
+ y
*(R
.viewplane
.ymax
- R
.viewplane
.ymin
);
104 // if(R.flag & R_SEC_FIELD) {
105 // if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor;
106 // else view[1]= (y+R.ystart+1.0)*R.ycor;
108 // else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor;
110 if(R
.r
.mode
& R_PANORAMA
) {
111 float u
= view
[0] + R
.panodxv
; float v
= view
[2];
112 view
[0]= R
.panoco
*u
+ R
.panosi
*v
;
113 view
[2]= -R
.panosi
*u
+ R
.panoco
*v
;
118 void calc_renderco_ortho(float *co
, float x
, float y
, int z
)
120 /* x and y 3d coordinate can be derived from pixel coord and winmat */
121 float fx
= 2.0f
/(R
.winx
*R
.winmat
[0][0]);
122 float fy
= 2.0f
/(R
.winy
*R
.winmat
[1][1]);
125 co
[0]= (x
- 0.5f
*R
.winx
)*fx
- R
.winmat
[3][0]/R
.winmat
[0][0];
126 co
[1]= (y
- 0.5f
*R
.winy
)*fy
- R
.winmat
[3][1]/R
.winmat
[1][1];
128 zco
= ((float)z
)/2147483647.0f
;
129 co
[2]= R
.winmat
[3][2]/( R
.winmat
[2][3]*zco
- R
.winmat
[2][2] );
132 void calc_renderco_zbuf(float *co
, float *view
, int z
)
136 /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
137 zco
= ((float)z
)/2147483647.0f
;
138 co
[2]= R
.winmat
[3][2]/( R
.winmat
[2][3]*zco
- R
.winmat
[2][2] );
145 /* also used in zbuf.c and shadbuf.c */
146 int count_mask(unsigned short mask
)
149 return (R
.samples
->cmask
[mask
& 255]+R
.samples
->cmask
[mask
>>8]);
153 static int calchalo_z(HaloRen
*har
, int zz
)
156 if(har
->type
& HA_ONLYSKY
) {
157 if(zz
!=0x7FFFFFFF) zz
= - 0x7FFFFF;
165 static void halo_pixelstruct(HaloRen
*har
, float *rb
, float dist
, float xn
, float yn
, PixStr
*ps
)
167 float col
[4], accol
[4], fac
;
168 int amount
, amountm
, zz
, flarec
;
171 accol
[0]=accol
[1]=accol
[2]=accol
[3]= 0.0f
;
175 amountm
= count_mask(ps
->mask
);
178 zz
= calchalo_z(har
, ps
->z
);
179 if((zz
> har
->zs
) && (har
->mat
->mode
& MA_HALO_SOFT
)) {
180 if (shadeHaloFloat(har
, col
, zz
, dist
, xn
, yn
, flarec
)) {
183 fac
= ((float)amountm
)/(float)R
.osa
;
184 accol
[0]+= fac
*col
[0];
185 accol
[1]+= fac
*col
[1];
186 accol
[2]+= fac
*col
[2];
187 accol
[3]+= fac
*col
[3];
193 /* now do the sky sub-pixels */
194 amount
= R
.osa
-amount
;
196 if (shadeHaloFloat(har
, col
, 0x7FFFFF, dist
, xn
, yn
, flarec
)) {
197 fac
= ((float)amount
)/(float)R
.osa
;
198 accol
[0]+= fac
*col
[0];
199 accol
[1]+= fac
*col
[1];
200 accol
[2]+= fac
*col
[2];
201 accol
[3]+= fac
*col
[3];
209 addalphaAddfacFloat(rb
, col
, har
->add
);
213 static void halo_tile(RenderPart
*pa
, float *pass
, unsigned int lay
)
216 rcti disprect
= pa
->disprect
, testrect
= pa
->disprect
;
217 float dist
, xsq
, ysq
, xn
, yn
, *rb
;
221 short minx
, maxx
, miny
, maxy
, x
;
223 /* we don't render halos in the cropped area, gives errors in flare counter */
225 testrect
.xmin
+= pa
->crop
;
226 testrect
.xmax
-= pa
->crop
;
227 testrect
.ymin
+= pa
->crop
;
228 testrect
.ymax
-= pa
->crop
;
231 for(a
=0; a
<R
.tothalo
; a
++) {
236 /* layer test, clip halo with y */
237 if((har
->lay
& lay
)==0);
238 else if(testrect
.ymin
> har
->maxy
);
239 else if(testrect
.ymax
< har
->miny
);
242 minx
= floor(har
->xs
-har
->rad
);
243 maxx
= ceil(har
->xs
+har
->rad
);
245 if(testrect
.xmin
> maxx
);
246 else if(testrect
.xmax
< minx
);
249 minx
= MAX2(minx
, testrect
.xmin
);
250 maxx
= MIN2(maxx
, testrect
.xmax
);
252 miny
= MAX2(har
->miny
, testrect
.ymin
);
253 maxy
= MIN2(har
->maxy
, testrect
.ymax
);
255 for(y
=miny
; y
<maxy
; y
++) {
256 int rectofs
= (y
-disprect
.ymin
)*pa
->rectx
+ (minx
- disprect
.xmin
);
257 rb
= pass
+ 4*rectofs
;
258 rz
= pa
->rectz
+ rectofs
;
261 rd
= pa
->rectdaps
+ rectofs
;
263 yn
= (y
-har
->ys
)*R
.ycor
;
266 for(x
=minx
; x
<maxx
; x
++, rb
+=4, rz
++) {
270 if(dist
<har
->radsq
) {
272 halo_pixelstruct(har
, rb
, dist
, xn
, yn
, (PixStr
*)*rd
);
275 zz
= calchalo_z(har
, *rz
);
276 if((zz
> har
->zs
) || (har
->mat
->mode
& MA_HALO_SOFT
)) {
277 if(shadeHaloFloat(har
, col
, zz
, dist
, xn
, yn
, har
->flarec
))
278 addalphaAddfacFloat(rb
, col
, har
->add
);
287 if(R
.test_break() ) break;
291 static void lamphalo_tile(RenderPart
*pa
, RenderLayer
*rl
)
294 float *pass
= rl
->rectf
;
296 long *rd
= pa
->rectdaps
;
297 int x
, y
, *rz
= pa
->rectz
;
299 shade_input_initialize(&shi
, pa
, rl
, 0);
301 for(y
=pa
->disprect
.ymin
; y
<pa
->disprect
.ymax
; y
++) {
302 for(x
=pa
->disprect
.xmin
; x
<pa
->disprect
.xmax
; x
++, rz
++, pass
+=4) {
304 calc_view_vector(shi
.view
, x
, y
);
307 PixStr
*ps
= (PixStr
*)*rd
;
308 int samp
, totsamp
= 0;
311 if(R
.r
.mode
& R_ORTHO
)
312 calc_renderco_ortho(shi
.co
, (float)x
, (float)y
, ps
->z
);
314 calc_renderco_zbuf(shi
.co
, shi
.view
, ps
->z
);
316 totsamp
+= samp
= count_mask(ps
->mask
);
317 fac
= ((float)samp
)/(float)R
.osa
;
318 renderspothalo(&shi
, pass
, fac
);
322 fac
= ((float)R
.osa
-totsamp
)/(float)R
.osa
;
324 renderspothalo(&shi
, pass
, fac
);
328 if(R
.r
.mode
& R_ORTHO
)
329 calc_renderco_ortho(shi
.co
, (float)x
, (float)y
, *rz
);
331 calc_renderco_zbuf(shi
.co
, shi
.view
, *rz
);
333 renderspothalo(&shi
, pass
, 1.0f
);
339 if(R
.test_break()) break;
344 /* ********************* MAINLOOPS ******************** */
347 static void add_filt_passes(RenderLayer
*rl
, int curmask
, int rectx
, int offset
, ShadeInput
*shi
, ShadeResult
*shr
)
351 for(rpass
= rl
->passes
.first
; rpass
; rpass
= rpass
->next
) {
352 float *fp
, *col
= NULL
;
355 switch(rpass
->passtype
) {
360 case SCE_PASS_DIFFUSE
:
366 case SCE_PASS_SHADOW
:
372 case SCE_PASS_REFLECT
:
375 case SCE_PASS_REFRACT
:
381 case SCE_PASS_NORMAL
:
385 /* box filter only, gauss will screwup UV too much */
387 float mult
= (float)count_mask(curmask
)/(float)R
.osa
;
388 fp
= rpass
->rect
+ 3*offset
;
389 fp
[0]+= mult
*(0.5f
+ 0.5f
*shi
->uv
[0].uv
[0]);
390 fp
[1]+= mult
*(0.5f
+ 0.5f
*shi
->uv
[0].uv
[1]);
394 case SCE_PASS_INDEXOB
:
397 fp
= rpass
->rect
+ offset
;
399 *fp
= (float)shi
->vlr
->ob
->index
;
402 case SCE_PASS_INDEXMAT
:
405 fp
= rpass
->rect
+ offset
;
407 *fp
= (float)shi
->vlr
->mat
->index
;
416 case SCE_PASS_VECTOR
:
418 /* add minimum speed in pixel, no filter */
419 fp
= rpass
->rect
+ 4*offset
;
420 if( (ABS(shr
->winspeed
[0]) + ABS(shr
->winspeed
[1]))< (ABS(fp
[0]) + ABS(fp
[1])) ) {
421 fp
[0]= shr
->winspeed
[0];
422 fp
[1]= shr
->winspeed
[1];
424 if( (ABS(shr
->winspeed
[2]) + ABS(shr
->winspeed
[3]))< (ABS(fp
[2]) + ABS(fp
[3])) ) {
425 fp
[2]= shr
->winspeed
[2];
426 fp
[3]= shr
->winspeed
[3];
432 fp
= rpass
->rect
+ pixsize
*offset
;
433 add_filt_fmask_pixsize(curmask
, col
, fp
, rectx
, pixsize
);
438 /* non-osa version */
439 static void add_passes(RenderLayer
*rl
, int offset
, ShadeInput
*shi
, ShadeResult
*shr
)
443 for(rpass
= rl
->passes
.first
; rpass
; rpass
= rpass
->next
) {
444 float *fp
, *col
= NULL
, uvcol
[3];
447 switch(rpass
->passtype
) {
452 case SCE_PASS_DIFFUSE
:
458 case SCE_PASS_SHADOW
:
464 case SCE_PASS_REFLECT
:
467 case SCE_PASS_REFRACT
:
473 case SCE_PASS_NORMAL
:
478 uvcol
[0]= 0.5f
+ 0.5f
*shi
->uv
[0].uv
[0];
479 uvcol
[1]= 0.5f
+ 0.5f
*shi
->uv
[0].uv
[1];
484 case SCE_PASS_VECTOR
:
488 case SCE_PASS_INDEXOB
:
490 fp
= rpass
->rect
+ offset
;
491 *fp
= (float)shi
->vlr
->ob
->index
;
494 case SCE_PASS_INDEXMAT
:
496 fp
= rpass
->rect
+ offset
;
497 *fp
= (float)shi
->vlr
->mat
->index
;
501 fp
= rpass
->rect
+ offset
;
506 fp
= rpass
->rect
+ pixsize
*offset
;
507 for(a
=0; a
<pixsize
; a
++)
513 /* only do sky, is default in the solid layer (shade_tile) btw */
514 static void sky_tile(RenderPart
*pa
, float *pass
)
519 if(R
.r
.alphamode
!=R_ADDSKY
)
522 for(y
=pa
->disprect
.ymin
; y
<pa
->disprect
.ymax
; y
++) {
523 for(x
=pa
->disprect
.xmin
; x
<pa
->disprect
.xmax
; x
++, pass
+=4) {
526 shadeSkyPixel(pass
, x
, y
);
528 shadeSkyPixel(col
, x
, y
);
529 addAlphaOverFloat(col
, pass
);
536 if(R
.test_break()) break;
540 static void shadeDA_tile(RenderPart
*pa
, RenderLayer
*rl
)
542 RenderResult
*rr
= pa
->result
;
544 float *fcol
, *rf
, *rectf
= rl
->rectf
;
545 long *rd
, *rectdaps
= pa
->rectdaps
;
547 int x
, y
, seed
, crop
=0, offs
=0, od
, addpassflag
;
549 if(R
.test_break()) return;
551 /* irregular shadowb buffer creation */
552 if(R
.r
.mode
& R_SHADOW
)
553 ISB_create(pa
, NULL
);
555 /* we set per pixel a fixed seed, for random AO and shadow samples */
556 seed
= pa
->rectx
*pa
->disprect
.ymin
;
558 /* general shader info, passes */
559 shade_sample_initialize(&ssamp
, pa
, rl
);
560 addpassflag
= rl
->passflag
& ~(SCE_PASS_Z
|SCE_PASS_COMBINED
);
562 /* filtered render, for now we assume only 1 filter size */
565 rectf
+= 4*(pa
->rectx
+ 1);
566 rectdaps
+= pa
->rectx
+ 1;
570 /* scanline updates have to be 2 lines behind */
572 rr
->renrect
.ymax
= -2*crop
;
575 for(y
=pa
->disprect
.ymin
+crop
; y
<pa
->disprect
.ymax
-crop
; y
++, rr
->renrect
.ymax
++) {
580 for(x
=pa
->disprect
.xmin
+crop
; x
<pa
->disprect
.xmax
-crop
; x
++, rd
++, rf
+=4, od
++) {
581 BLI_thread_srandom(pa
->thread
, seed
++);
584 if(shade_samples(&ssamp
, (PixStr
*)(*rd
), x
, y
)) {
585 for(samp
=0; samp
<ssamp
.tot
; samp
++) {
587 fcol
= ssamp
.shr
[samp
].combined
;
588 add_filt_fmask(ssamp
.shi
[samp
].mask
, fcol
, rf
, pa
->rectx
);
591 add_filt_passes(rl
, ssamp
.shi
[samp
].mask
, pa
->rectx
, od
, &ssamp
.shi
[samp
], &ssamp
.shr
[samp
]);
598 rectdaps
+= pa
->rectx
;
601 if(y
&1) if(R
.test_break()) break;
604 /* disable scanline updating */
607 if(R
.r
.mode
& R_SHADOW
)
611 /* ************* pixel struct ******** */
614 static PixStrMain
*addpsmain(ListBase
*lb
)
618 psm
= (PixStrMain
*)MEM_mallocN(sizeof(PixStrMain
),"pixstrMain");
619 BLI_addtail(lb
, psm
);
621 psm
->ps
= (PixStr
*)MEM_mallocN(4096*sizeof(PixStr
),"pixstr");
627 static void freeps(ListBase
*lb
)
629 PixStrMain
*psm
, *psmnext
;
631 for(psm
= lb
->first
; psm
; psm
= psmnext
) {
637 lb
->first
= lb
->last
= NULL
;
640 static void addps(ListBase
*lb
, long *rd
, int facenr
, int z
, unsigned short mask
)
643 PixStr
*ps
, *last
= NULL
;
649 if( ps
->facenr
== facenr
) {
658 /* make new PS (pixel struct) */
661 if(psm
->counter
==4095)
664 ps
= psm
->ps
+ psm
->counter
++;
666 if(last
) last
->next
= ps
;
676 static void make_pixelstructs(RenderPart
*pa
, ListBase
*lb
)
678 long *rd
= pa
->rectdaps
;
682 int mask
= 1<<pa
->sample
;
684 for(y
=0; y
<pa
->recty
; y
++) {
685 for(x
=0; x
<pa
->rectx
; x
++, rd
++, rp
++) {
687 addps(lb
, rd
, *rp
, *(rz
+x
), mask
);
694 static void edge_enhance_add(RenderPart
*pa
, float *rectf
, float *arect
)
702 for(pix
= pa
->rectx
*pa
->recty
; pix
>0; pix
--, arect
++, rectf
+=4) {
704 addcol
[0]= *arect
* R
.r
.edgeR
;
705 addcol
[1]= *arect
* R
.r
.edgeG
;
706 addcol
[2]= *arect
* R
.r
.edgeB
;
708 addAlphaOverFloat(rectf
, addcol
);
714 static void convert_to_key_alpha(RenderPart
*pa
, float *rectf
)
718 for(y
= pa
->rectx
*pa
->recty
; y
>0; y
--, rectf
+=4) {
719 if(rectf
[3] >= 1.0f
);
720 else if(rectf
[3] > 0.0f
) {
721 rectf
[0] /= rectf
[3];
722 rectf
[1] /= rectf
[3];
723 rectf
[2] /= rectf
[3];
728 /* adds only alpha values */
729 static void edge_enhance_tile(RenderPart
*pa
, float *rectf
)
731 /* use zbuffer to define edges, add it to the image */
732 int y
, x
, col
, *rz
, *rz1
, *rz2
, *rz3
;
733 int zval1
, zval2
, zval3
;
736 /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */
740 for(y
=0; y
<pa
->recty
; y
++)
741 for(x
=0; x
<pa
->rectx
; x
++, rz
++) (*rz
)>>= 4;
747 rf
= rectf
+pa
->rectx
+1;
749 for(y
=0; y
<pa
->recty
-2; y
++) {
750 for(x
=0; x
<pa
->rectx
-2; x
++, rz1
++, rz2
++, rz3
++, rf
++) {
752 /* prevent overflow with sky z values */
753 zval1
= rz1
[0] + 2*rz1
[1] + rz1
[2];
754 zval2
= 2*rz2
[0] + 2*rz2
[2];
755 zval3
= rz3
[0] + 2*rz3
[1] + rz3
[2];
757 col
= ( 4*rz2
[1] - (zval1
+ zval2
+ zval3
)/3 );
761 if(col
> (1<<16)) col
= (1<<16);
762 else col
= (R
.r
.edgeint
*col
)>>8;
767 if(col
>255) fcol
= 1.0f
;
768 else fcol
= (float)col
/255.0f
;
771 *rf
+= fcol
/(float)R
.osa
;
782 /* shift back zbuf values, we might need it still */
784 for(y
=0; y
<pa
->recty
; y
++)
785 for(x
=0; x
<pa
->rectx
; x
++, rz
++) (*rz
)<<= 4;
789 static void reset_sky_speed(RenderPart
*pa
, RenderLayer
*rl
)
791 /* for all pixels with max speed, set to zero */
795 fp
= RE_RenderLayerGetPass(rl
, SCE_PASS_VECTOR
);
798 for(a
= 4*pa
->rectx
*pa
->recty
- 1; a
>=0; a
--)
799 if(fp
[a
] == PASS_VECTOR_MAX
) fp
[a
]= 0.0f
;
803 static unsigned short *make_solid_mask(RenderPart
*pa
)
805 long *rd
= pa
->rectdaps
;
806 unsigned short *solidmask
, *sp
;
809 if(rd
==NULL
) return NULL
;
811 sp
=solidmask
= MEM_mallocN(sizeof(short)*pa
->rectx
*pa
->recty
, "solidmask");
813 for(x
=pa
->rectx
*pa
->recty
; x
>0; x
--, rd
++, sp
++) {
815 PixStr
*ps
= (PixStr
*)*rd
;
818 for(ps
= ps
->next
; ps
; ps
= ps
->next
)
828 static void addAlphaOverFloatMask(float *dest
, float *source
, unsigned short dmask
, unsigned short smask
)
830 unsigned short shared
= dmask
& smask
;
831 float mul
= 1.0 - source
[3];
833 if(shared
) { /* overlapping masks */
835 /* masks differ, we make a mixture of 'add' and 'over' */
837 float shared_bits
= (float)count_mask(shared
); /* alpha over */
838 float tot_bits
= (float)count_mask(smask
|dmask
); /* alpha add */
840 float add
= (tot_bits
- shared_bits
)/tot_bits
; /* add level */
841 mul
= add
+ (1.0f
-add
)*mul
;
844 else if(dmask
&& smask
) {
845 /* works for premul only, of course */
854 dest
[0]= (mul
*dest
[0]) + source
[0];
855 dest
[1]= (mul
*dest
[1]) + source
[1];
856 dest
[2]= (mul
*dest
[2]) + source
[2];
857 dest
[3]= (mul
*dest
[3]) + source
[3];
861 /* main call for shading Delta Accum, for OSA */
862 /* supposed to be fully threadable! */
863 void zbufshadeDA_tile(RenderPart
*pa
)
865 RenderResult
*rr
= pa
->result
;
867 ListBase psmlist
= {NULL
, NULL
};
868 float *edgerect
= NULL
;
870 set_part_zbuf_clipflag(pa
);
872 /* allocate the necessary buffers */
873 /* zbuffer inits these rects */
874 pa
->rectp
= MEM_mallocN(sizeof(int)*pa
->rectx
*pa
->recty
, "rectp");
875 pa
->rectz
= MEM_mallocN(sizeof(int)*pa
->rectx
*pa
->recty
, "rectz");
877 for(rl
= rr
->layers
.first
; rl
; rl
= rl
->next
) {
879 /* initialize pixelstructs and edge buffer */
881 pa
->rectdaps
= MEM_callocN(sizeof(long)*pa
->rectx
*pa
->recty
+4, "zbufDArectd");
883 if(rl
->layflag
& SCE_LAY_EDGE
)
884 if(R
.r
.mode
& R_EDGE
)
885 edgerect
= MEM_callocN(sizeof(float)*pa
->rectx
*pa
->recty
, "rectedge");
887 /* always fill visibility */
888 for(pa
->sample
=0; pa
->sample
<R
.osa
; pa
->sample
++) {
889 zbuffer_solid(pa
, rl
->lay
, rl
->layflag
);
890 make_pixelstructs(pa
, &psmlist
);
892 if(rl
->layflag
& SCE_LAY_EDGE
)
893 if(R
.r
.mode
& R_EDGE
)
894 edge_enhance_tile(pa
, edgerect
);
896 if(R
.test_break()) break;
900 if(rl
->layflag
& SCE_LAY_SOLID
)
901 shadeDA_tile(pa
, rl
);
903 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
904 if(R
.flag
& R_LAMPHALO
)
905 if(rl
->layflag
& SCE_LAY_HALO
)
906 lamphalo_tile(pa
, rl
);
908 /* halo before ztra, because ztra fills in zbuffer now */
910 if(rl
->layflag
& SCE_LAY_HALO
)
911 halo_tile(pa
, rl
->rectf
, rl
->lay
);
914 if(R
.flag
& R_ZTRA
) {
915 if(rl
->layflag
& SCE_LAY_ZTRA
) {
916 unsigned short *ztramask
, *solidmask
= NULL
; /* 16 bits, MAX_OSA */
918 /* allocate, but not free here, for asynchronous display of this rect in main thread */
919 rl
->acolrect
= MEM_callocN(4*sizeof(float)*pa
->rectx
*pa
->recty
, "alpha layer");
921 /* swap for live updates, and it is used in zbuf.c!!! */
922 SWAP(float *, rl
->acolrect
, rl
->rectf
);
923 ztramask
= zbuffer_transp_shade(pa
, rl
, rl
->rectf
);
924 SWAP(float *, rl
->acolrect
, rl
->rectf
);
926 /* zbuffer transp only returns ztramask if there's solid rendered */
928 solidmask
= make_solid_mask(pa
);
930 if(ztramask
&& solidmask
) {
931 unsigned short *sps
= solidmask
, *spz
= ztramask
;
932 unsigned short fullmask
= (1<<R
.osa
)-1;
933 float *fcol
= rl
->rectf
; float *acol
= rl
->acolrect
;
936 for(x
=pa
->rectx
*pa
->recty
; x
>0; x
--, acol
+=4, fcol
+=4, sps
++, spz
++) {
938 addAlphaOverFloat(fcol
, acol
);
940 addAlphaOverFloatMask(fcol
, acol
, *sps
, *spz
);
944 float *fcol
= rl
->rectf
; float *acol
= rl
->acolrect
;
946 for(x
=pa
->rectx
*pa
->recty
; x
>0; x
--, acol
+=4, fcol
+=4) {
947 addAlphaOverFloat(fcol
, acol
);
950 if(solidmask
) MEM_freeN(solidmask
);
951 if(ztramask
) MEM_freeN(ztramask
);
954 /* sky before edge */
955 if(rl
->layflag
& SCE_LAY_SKY
)
956 sky_tile(pa
, rl
->rectf
);
959 if(rl
->layflag
& SCE_LAY_EDGE
)
960 if(R
.r
.mode
& R_EDGE
)
961 edge_enhance_add(pa
, rl
->rectf
, edgerect
);
963 if(rl
->passflag
& SCE_PASS_Z
)
964 convert_zbuf_to_distbuf(pa
, rl
);
966 if(rl
->passflag
& SCE_PASS_VECTOR
)
967 reset_sky_speed(pa
, rl
);
969 /* de-premul alpha */
970 if(R
.r
.alphamode
& R_ALPHAKEY
)
971 convert_to_key_alpha(pa
, rl
->rectf
);
973 /* free stuff within loop! */
974 MEM_freeN(pa
->rectdaps
); pa
->rectdaps
= NULL
;
977 if(edgerect
) MEM_freeN(edgerect
);
982 MEM_freeN(pa
->rectp
); pa
->rectp
= NULL
;
983 MEM_freeN(pa
->rectz
); pa
->rectz
= NULL
;
984 MEM_freeN(pa
->clipflag
); pa
->clipflag
= NULL
;
986 /* display active layer */
987 rr
->renrect
.ymin
=rr
->renrect
.ymax
= 0;
988 rr
->renlay
= render_get_active_layer(&R
, rr
);
992 /* ------------------------------------------------------------------------ */
994 /* non OSA case, full tile render */
995 /* supposed to be fully threadable! */
996 void zbufshade_tile(RenderPart
*pa
)
999 RenderResult
*rr
= pa
->result
;
1002 float *edgerect
= NULL
;
1005 /* fake pixel struct, to comply to osa render */
1009 set_part_zbuf_clipflag(pa
);
1011 /* zbuffer code clears/inits rects */
1012 pa
->rectp
= MEM_mallocN(sizeof(int)*pa
->rectx
*pa
->recty
, "rectp");
1013 pa
->rectz
= MEM_mallocN(sizeof(int)*pa
->rectx
*pa
->recty
, "rectz");
1015 for(rl
= rr
->layers
.first
; rl
; rl
= rl
->next
) {
1017 /* general shader info, passes */
1018 shade_sample_initialize(&ssamp
, pa
, rl
);
1019 addpassflag
= rl
->passflag
& ~(SCE_PASS_Z
|SCE_PASS_COMBINED
);
1021 zbuffer_solid(pa
, rl
->lay
, rl
->layflag
);
1023 if(!R
.test_break()) { /* NOTE: this if() is not consistant */
1025 /* edges only for solid part, ztransp doesn't support it yet anti-aliased */
1026 if(rl
->layflag
& SCE_LAY_EDGE
) {
1027 if(R
.r
.mode
& R_EDGE
) {
1028 edgerect
= MEM_callocN(sizeof(float)*pa
->rectx
*pa
->recty
, "rectedge");
1029 edge_enhance_tile(pa
, edgerect
);
1033 /* initialize scanline updates for main thread */
1034 rr
->renrect
.ymin
= 0;
1037 if(rl
->layflag
& SCE_LAY_SOLID
) {
1038 float *fcol
= rl
->rectf
;
1039 int x
, y
, *rp
= pa
->rectp
, *rz
= pa
->rectz
, offs
=0, seed
;
1041 /* we set per pixel a fixed seed, for random AO and shadow samples */
1042 seed
= pa
->rectx
*pa
->disprect
.ymin
;
1044 /* irregular shadowb buffer creation */
1045 if(R
.r
.mode
& R_SHADOW
)
1046 ISB_create(pa
, NULL
);
1048 for(y
=pa
->disprect
.ymin
; y
<pa
->disprect
.ymax
; y
++, rr
->renrect
.ymax
++) {
1049 for(x
=pa
->disprect
.xmin
; x
<pa
->disprect
.xmax
; x
++, rz
++, rp
++, fcol
+=4, offs
++) {
1050 /* per pixel fixed seed */
1051 BLI_thread_srandom(pa
->thread
, seed
++);
1056 if(shade_samples(&ssamp
, &ps
, x
, y
)) {
1057 QUATCOPY(fcol
, ssamp
.shr
[0].combined
);
1061 add_passes(rl
, offs
, ssamp
.shi
, ssamp
.shr
);
1066 if(R
.test_break()) break;
1069 if(R
.r
.mode
& R_SHADOW
)
1073 /* disable scanline updating */
1077 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
1078 if(R
.flag
& R_LAMPHALO
)
1079 if(rl
->layflag
& SCE_LAY_HALO
)
1080 lamphalo_tile(pa
, rl
);
1082 /* halo before ztra, because ztra fills in zbuffer now */
1084 if(rl
->layflag
& SCE_LAY_HALO
)
1085 halo_tile(pa
, rl
->rectf
, rl
->lay
);
1087 if(R
.flag
& R_ZTRA
) {
1088 if(rl
->layflag
& SCE_LAY_ZTRA
) {
1092 /* allocate, but not free here, for asynchronous display of this rect in main thread */
1093 rl
->acolrect
= MEM_callocN(4*sizeof(float)*pa
->rectx
*pa
->recty
, "alpha layer");
1095 /* swap for live updates */
1096 SWAP(float *, rl
->acolrect
, rl
->rectf
);
1097 zbuffer_transp_shade(pa
, rl
, rl
->rectf
);
1098 SWAP(float *, rl
->acolrect
, rl
->rectf
);
1100 fcol
= rl
->rectf
; acol
= rl
->acolrect
;
1101 for(x
=pa
->rectx
*pa
->recty
; x
>0; x
--, acol
+=4, fcol
+=4) {
1102 addAlphaOverFloat(fcol
, acol
);
1107 /* sky before edge */
1108 if(rl
->layflag
& SCE_LAY_SKY
)
1109 sky_tile(pa
, rl
->rectf
);
1111 if(!R
.test_break()) {
1112 if(rl
->layflag
& SCE_LAY_EDGE
)
1113 if(R
.r
.mode
& R_EDGE
)
1114 edge_enhance_add(pa
, rl
->rectf
, edgerect
);
1117 if(rl
->passflag
& SCE_PASS_Z
)
1118 convert_zbuf_to_distbuf(pa
, rl
);
1120 if(rl
->passflag
& SCE_PASS_VECTOR
)
1121 reset_sky_speed(pa
, rl
);
1123 /* de-premul alpha */
1124 if(R
.r
.alphamode
& R_ALPHAKEY
)
1125 convert_to_key_alpha(pa
, rl
->rectf
);
1127 if(edgerect
) MEM_freeN(edgerect
);
1131 /* display active layer */
1132 rr
->renrect
.ymin
=rr
->renrect
.ymax
= 0;
1133 rr
->renlay
= render_get_active_layer(&R
, rr
);
1135 MEM_freeN(pa
->rectp
); pa
->rectp
= NULL
;
1136 MEM_freeN(pa
->rectz
); pa
->rectz
= NULL
;
1137 MEM_freeN(pa
->clipflag
); pa
->clipflag
= NULL
;
1140 /* SSS preprocess tile render, fully threadable */
1141 typedef struct ZBufSSSHandle
{
1147 static void addps_sss(void *cb_handle
, int facenr
, int x
, int y
, int z
)
1149 ZBufSSSHandle
*handle
= cb_handle
;
1150 RenderPart
*pa
= handle
->pa
;
1152 /* extra border for filter gives double samples on part edges,
1154 if(x
<pa
->crop
|| x
>=pa
->rectx
-pa
->crop
)
1156 if(y
<pa
->crop
|| y
>=pa
->recty
-pa
->crop
)
1160 long *rs
= pa
->rectall
+ pa
->rectx
*y
+ x
;
1162 addps(&handle
->psmlist
, rs
, facenr
, z
, 0);
1166 int *rz
= pa
->rectz
+ pa
->rectx
*y
+ x
;
1167 int *rp
= pa
->rectp
+ pa
->rectx
*y
+ x
;
1177 int *rz
= pa
->rectbackz
+ pa
->rectx
*y
+ x
;
1178 int *rp
= pa
->rectbackp
+ pa
->rectx
*y
+ x
;
1189 static void shade_sample_sss(ShadeSample
*ssamp
, Material
*mat
, VlakRen
*vlr
, int quad
, float x
, float y
, float z
, float *co
, float *color
, float *area
)
1191 ShadeInput
*shi
= ssamp
->shi
;
1193 float texfac
, orthoarea
, nor
[3];
1195 /* normal flipping must be disabled to make back scattering work, so that
1196 backside faces actually face any lighting from the back */
1199 /* cache for shadow */
1203 shade_input_set_triangle_i(shi
, vlr
, 0, 2, 3);
1205 shade_input_set_triangle_i(shi
, vlr
, 0, 1, 2);
1207 /* we don't want flipped normals, they screw up back scattering */
1208 if(vlr
->noflag
& R_FLIPPED_NO
)
1209 VecMulf(shi
->facenor
, -1.0f
);
1215 /* we estimate the area here using shi->dxco and shi->dyco. we need to
1216 enabled shi->osatex these are filled. we compute two areas, one with
1217 the normal pointed at the camera and one with the original normal, and
1218 then clamp to avoid a too large contribution from a single pixel */
1221 VECCOPY(nor
, shi
->facenor
);
1222 calc_view_vector(shi
->facenor
, x
, y
);
1223 Normalize(shi
->facenor
);
1224 shade_input_set_viewco(shi
, x
, y
, z
);
1225 orthoarea
= VecLength(shi
->dxco
)*VecLength(shi
->dyco
);
1227 VECCOPY(shi
->facenor
, nor
);
1228 shade_input_set_viewco(shi
, x
, y
, z
);
1229 *area
= VecLength(shi
->dxco
)*VecLength(shi
->dyco
);
1230 *area
= MIN2(*area
, 2.0f
*orthoarea
);
1232 shade_input_set_uv(shi
);
1233 shade_input_set_normals(shi
);
1235 /* not a pretty solution, but fixes common cases */
1236 if(vlr
->ob
&& vlr
->ob
->transflag
& OB_NEG_SCALE
) {
1237 VecMulf(shi
->vn
, -1.0f
);
1238 VecMulf(shi
->vno
, -1.0f
);
1241 /* if nodetree, use the material that we are currently preprocessing
1242 instead of the node material */
1243 if(shi
->mat
->nodetree
&& shi
->mat
->use_nodes
)
1246 /* init material vars */
1247 // note, keep this synced with render_types.h
1248 memcpy(&shi
->r
, &shi
->mat
->r
, 23*sizeof(float));
1249 shi
->har
= shi
->mat
->har
;
1252 shade_input_set_shade_texco(shi
);
1254 shade_samples_do_AO(ssamp
);
1255 shade_material_loop(shi
, &shr
);
1257 VECCOPY(co
, shi
->co
);
1258 VECCOPY(color
, shr
.combined
);
1260 /* texture blending */
1261 texfac
= shi
->mat
->sss_texfac
;
1263 if(texfac
== 0.0f
) {
1264 if(shr
.col
[0]!=0.0f
) color
[0] /= shr
.col
[0];
1265 if(shr
.col
[1]!=0.0f
) color
[1] /= shr
.col
[1];
1266 if(shr
.col
[2]!=0.0f
) color
[2] /= shr
.col
[2];
1268 else if(texfac
!= 1.0f
) {
1269 if(shr
.col
[0]!=0.0f
) color
[0] *= pow(shr
.col
[0], texfac
)/shr
.col
[0];
1270 if(shr
.col
[1]!=0.0f
) color
[1] *= pow(shr
.col
[1], texfac
)/shr
.col
[1];
1271 if(shr
.col
[2]!=0.0f
) color
[2] *= pow(shr
.col
[2], texfac
)/shr
.col
[2];
1275 static void zbufshade_sss_free(RenderPart
*pa
)
1277 MEM_freeN(pa
->clipflag
); pa
->clipflag
= NULL
;
1279 MEM_freeN(pa
->rectall
); pa
->rectall
= NULL
;
1280 freeps(&handle
.psmlist
);
1282 MEM_freeN(pa
->rectz
); pa
->rectz
= NULL
;
1283 MEM_freeN(pa
->rectp
); pa
->rectp
= NULL
;
1284 MEM_freeN(pa
->rectbackz
); pa
->rectbackz
= NULL
;
1285 MEM_freeN(pa
->rectbackp
); pa
->rectbackp
= NULL
;
1289 void zbufshade_sss_tile(RenderPart
*pa
)
1293 ZBufSSSHandle handle
;
1294 RenderResult
*rr
= pa
->result
;
1295 RenderLayer
*rl
= rr
->layers
.first
;
1297 Material
*mat
= re
->sss_mat
;
1298 float (*co
)[3], (*color
)[3], *area
, *fcol
= rl
->rectf
;
1299 int x
, y
, seed
, quad
, totpoint
, display
= !(re
->r
.scemode
& R_PREVIEWBUTS
);
1300 int *rz
, *rp
, *rbz
, *rbp
;
1307 set_part_zbuf_clipflag(pa
);
1309 /* setup pixelstr list and buffer for zbuffering */
1314 handle
.psmlist
.first
= handle
.psmlist
.last
= NULL
;
1315 addpsmain(&handle
.psmlist
);
1317 pa
->rectall
= MEM_callocN(sizeof(long)*pa
->rectx
*pa
->recty
+4, "rectall");
1319 pa
->rectp
= MEM_mallocN(sizeof(int)*pa
->rectx
*pa
->recty
, "rectp");
1320 pa
->rectz
= MEM_mallocN(sizeof(int)*pa
->rectx
*pa
->recty
, "rectz");
1321 pa
->rectbackp
= MEM_mallocN(sizeof(int)*pa
->rectx
*pa
->recty
, "rectbackp");
1322 pa
->rectbackz
= MEM_mallocN(sizeof(int)*pa
->rectx
*pa
->recty
, "rectbackz");
1325 /* create the pixelstrs to be used later */
1326 zbuffer_sss(pa
, rl
->lay
, &handle
, addps_sss
);
1328 if(handle
.totps
==0) {
1329 zbufshade_sss_free(pa
);
1333 co
= MEM_mallocN(sizeof(float)*3*handle
.totps
, "SSSCo");
1334 color
= MEM_mallocN(sizeof(float)*3*handle
.totps
, "SSSColor");
1335 area
= MEM_mallocN(sizeof(float)*handle
.totps
, "SSSArea");
1338 /* create ISB (does not work currently!) */
1339 if(re
->r
.mode
& R_SHADOW
)
1340 ISB_create(pa
, NULL
);
1343 /* setup shade sample with correct passes */
1344 memset(&ssamp
, 0, sizeof(ssamp
));
1345 shade_sample_initialize(&ssamp
, pa
, rl
);
1346 ssamp
.shi
[0].passflag
= SCE_PASS_DIFFUSE
|SCE_PASS_AO
|SCE_PASS_RADIO
;
1347 ssamp
.shi
[0].passflag
|= SCE_PASS_RGBA
;
1348 ssamp
.shi
[0].combinedflag
= ~(SCE_PASS_SPEC
);
1352 /* initialize scanline updates for main thread */
1353 rr
->renrect
.ymin
= 0;
1357 seed
= pa
->rectx
*pa
->disprect
.ymin
;
1368 for(y
=pa
->disprect
.ymin
; y
<pa
->disprect
.ymax
; y
++, rr
->renrect
.ymax
++) {
1369 for(x
=pa
->disprect
.xmin
; x
<pa
->disprect
.xmax
; x
++, fcol
+=4) {
1370 /* per pixel fixed seed */
1371 BLI_thread_srandom(pa
->thread
, seed
++);
1375 /* for each sample in this pixel, shade it */
1376 for(ps
=(PixStr
*)*rs
; ps
; ps
=ps
->next
) {
1377 vlr
= RE_findOrAddVlak(re
, (ps
->facenr
-1) & RE_QUAD_MASK
);
1378 quad
= (ps
->facenr
& RE_QUAD_OFFS
);
1381 shade_sample_sss(&ssamp
, mat
, vlr
, quad
, x
, y
, z
,
1382 co
[totpoint
], color
[totpoint
], &area
[totpoint
]);
1386 VECADD(fcol
, fcol
, color
);
1396 vlr
= RE_findOrAddVlak(re
, (*rp
-1) & RE_QUAD_MASK
);
1397 quad
= ((*rp
) & RE_QUAD_OFFS
);
1399 shade_sample_sss(&ssamp
, mat
, vlr
, quad
, x
, y
, *rz
,
1400 co
[totpoint
], color
[totpoint
], &area
[totpoint
]);
1402 VECADD(fcol
, fcol
, color
[totpoint
]);
1411 if(*rbp
!= 0 && *rbp
!= *(rp
-1)) {
1413 vlr
= RE_findOrAddVlak(re
, (*rbp
-1) & RE_QUAD_MASK
);
1414 quad
= ((*rbp
) & RE_QUAD_OFFS
);
1416 shade_sample_sss(&ssamp
, mat
, vlr
, quad
, x
, y
, *rbz
,
1417 co
[totpoint
], color
[totpoint
], &area
[totpoint
]);
1419 /* to indicate this is a back sample */
1420 area
[totpoint
]= -area
[totpoint
];
1422 VECADD(fcol
, fcol
, color
[totpoint
]);
1433 if(re
->test_break()) break;
1436 /* note: after adding we do not free these arrays, sss keeps them */
1438 sss_add_points(re
, co
, color
, area
, totpoint
);
1447 if(re
->r
.mode
& R_SHADOW
)
1452 /* display active layer */
1453 rr
->renrect
.ymin
=rr
->renrect
.ymax
= 0;
1454 rr
->renlay
= render_get_active_layer(&R
, rr
);
1457 zbufshade_sss_free(pa
);
1460 /* ------------------------------------------------------------------------ */
1462 static void renderhalo_post(RenderResult
*rr
, float *rectf
, HaloRen
*har
) /* postprocess version */
1464 float dist
, xsq
, ysq
, xn
, yn
, colf
[4], *rectft
, *rtf
;
1465 float haloxs
, haloys
;
1466 int minx
, maxx
, miny
, maxy
, x
, y
;
1468 /* calculate the disprect mapped coordinate for halo. note: rectx is disprect corrected */
1469 haloxs
= har
->xs
- R
.disprect
.xmin
;
1470 haloys
= har
->ys
- R
.disprect
.ymin
;
1472 har
->miny
= miny
= haloys
- har
->rad
/R
.ycor
;
1473 har
->maxy
= maxy
= haloys
+ har
->rad
/R
.ycor
;
1476 else if(rr
->recty
<miny
);
1478 minx
= floor(haloxs
-har
->rad
);
1479 maxx
= ceil(haloxs
+har
->rad
);
1482 else if(rr
->rectx
<minx
);
1486 if(maxx
>=rr
->rectx
) maxx
= rr
->rectx
-1;
1488 if(maxy
>rr
->recty
) maxy
= rr
->recty
;
1490 rectft
= rectf
+ 4*rr
->rectx
*miny
;
1492 for(y
=miny
; y
<maxy
; y
++) {
1496 yn
= (y
- haloys
)*R
.ycor
;
1499 for(x
=minx
; x
<=maxx
; x
++) {
1503 if(dist
<har
->radsq
) {
1505 if(shadeHaloFloat(har
, colf
, 0x7FFFFF, dist
, xn
, yn
, har
->flarec
))
1506 addalphaAddfacFloat(rtf
, colf
, har
->add
);
1511 rectft
+= 4*rr
->rectx
;
1513 if(R
.test_break()) break;
1518 /* ------------------------------------------------------------------------ */
1520 static void renderflare(RenderResult
*rr
, float *rectf
, HaloRen
*har
)
1522 extern float hashvectf
[];
1525 float *rc
, rad
, alfa
, visifac
, vec
[3];
1529 fla
.linec
= fla
.ringc
= fla
.flarec
= 0;
1534 visifac
= R
.ycor
*(har
->pixels
);
1535 /* all radials added / r^3 == 1.0f! */
1536 visifac
/= (har
->rad
*har
->rad
*har
->rad
);
1541 /* first halo: just do */
1543 har
->rad
= rad
*ma
->flaresize
*visifac
;
1544 har
->radsq
= har
->rad
*har
->rad
;
1547 har
->alfa
= alfa
*visifac
;
1549 renderhalo_post(rr
, rectf
, har
);
1551 /* next halo's: the flares */
1552 rc
= hashvectf
+ ma
->seed2
;
1554 for(b
=1; b
<har
->flarec
; b
++) {
1559 fla
.alfa
= ma
->flareboost
*fabs(alfa
*visifac
*rc
[3]);
1560 fla
.hard
= 20.0f
+ fabs(70*rc
[7]);
1563 type
= (int)(fabs(3.9*rc
[6]));
1565 fla
.rad
= ma
->subsize
*sqrt(fabs(2.0f
*har
->rad
*rc
[4]));
1569 fla
.rad
+= R
.rectx
/10;
1572 fla
.radsq
= fla
.rad
*fla
.rad
;
1574 vec
[0]= 1.4*rc
[5]*(har
->xs
-R
.winx
/2);
1575 vec
[1]= 1.4*rc
[5]*(har
->ys
-R
.winy
/2);
1576 vec
[2]= 32.0f
*sqrt(vec
[0]*vec
[0] + vec
[1]*vec
[1] + 1.0f
);
1578 fla
.xs
= R
.winx
/2 + vec
[0] + (1.2+rc
[8])*R
.rectx
*vec
[0]/vec
[2];
1579 fla
.ys
= R
.winy
/2 + vec
[1] + (1.2+rc
[8])*R
.rectx
*vec
[1]/vec
[2];
1581 if(R
.flag
& R_SEC_FIELD
) {
1582 if(R
.r
.mode
& R_ODDFIELD
) fla
.ys
+= 0.5;
1585 if(type
& 1) fla
.type
= HA_FLARECIRC
;
1587 renderhalo_post(rr
, rectf
, &fla
);
1590 if(type
& 2) fla
.type
= HA_FLARECIRC
;
1592 renderhalo_post(rr
, rectf
, &fla
);
1598 /* needs recode... integrate this better! */
1599 void add_halo_flare(Render
*re
)
1601 RenderResult
*rr
= re
->result
;
1603 HaloRen
*har
= NULL
;
1604 int a
, mode
, do_draw
=0;
1606 /* for now, we get the first renderlayer in list with halos set */
1607 for(rl
= rr
->layers
.first
; rl
; rl
= rl
->next
)
1608 if(rl
->layflag
& SCE_LAY_HALO
)
1611 if(rl
==NULL
|| rl
->rectf
==NULL
)
1615 R
.r
.mode
&= ~R_PANORAMA
;
1617 project_renderdata(&R
, projectverto
, 0, 0);
1619 for(a
=0; a
<R
.tothalo
; a
++) {
1620 if((a
& 255)==0) har
= R
.bloha
[a
>>8];
1625 renderflare(rr
, rl
->rectf
, har
);
1630 /* weak... the display callback wants an active renderlayer pointer... */
1632 re
->display_draw(rr
, NULL
);
1638 /* ************************* used for shaded view ************************ */
1640 /* if *re, then initialize, otherwise execute */
1641 void RE_shade_external(Render
*re
, ShadeInput
*shi
, ShadeResult
*shr
)
1649 /* fake render face */
1650 memset(&vlr
, 0, sizeof(VlakRen
));
1657 if(shi
->mat
->nodetree
&& shi
->mat
->use_nodes
)
1658 ntreeShaderExecTree(shi
->mat
->nodetree
, shi
, shr
);
1660 /* copy all relevant material vars, note, keep this synced with render_types.h */
1661 memcpy(&shi
->r
, &shi
->mat
->r
, 23*sizeof(float));
1662 shi
->har
= shi
->mat
->har
;
1664 shade_material_loop(shi
, shr
);
1668 /* ************************* bake ************************ */
1670 #define FTOCHAR(val) val<=0.0f?0: (val>=1.0f?255: (char)(255.0f*val))
1672 typedef struct BakeShade
{
1680 int rectx
, recty
, quad
, type
, vdone
, ready
;
1686 static void do_bake_shade(void *handle
, int x
, int y
, float u
, float v
)
1688 BakeShade
*bs
= handle
;
1689 ShadeSample
*ssamp
= &bs
->ssamp
;
1690 ShadeInput
*shi
= ssamp
->shi
;
1692 VlakRen
*vlr
= bs
->vlr
;
1693 float l
, *v1
, *v2
, *v3
;
1695 /* fast threadsafe break test */
1699 /* setup render coordinates */
1714 shi
->co
[0]= l
*v3
[0]+u
*v1
[0]+v
*v2
[0];
1715 shi
->co
[1]= l
*v3
[1]+u
*v1
[1]+v
*v2
[1];
1716 shi
->co
[2]= l
*v3
[2]+u
*v1
[2]+v
*v2
[2];
1718 /* set up view vector */
1719 VECCOPY(shi
->view
, shi
->co
);
1720 Normalize(shi
->view
);
1722 /* no face normal flip */
1725 /* cache for shadow */
1729 shade_input_set_triangle_i(shi
, vlr
, 0, 2, 3);
1731 shade_input_set_triangle_i(shi
, vlr
, 0, 1, 2);
1738 shade_input_set_normals(shi
);
1740 /* init material vars */
1741 memcpy(&shi
->r
, &shi
->mat
->r
, 23*sizeof(float)); // note, keep this synced with render_types.h
1742 shi
->har
= shi
->mat
->har
;
1744 if(bs
->type
==RE_BAKE_AO
) {
1745 ambient_occlusion(shi
);
1746 ambient_occlusion_to_diffuse(shi
, shr
.combined
);
1750 shade_input_set_shade_texco(shi
);
1752 shade_samples_do_AO(ssamp
);
1754 if(shi
->mat
->nodetree
&& shi
->mat
->use_nodes
) {
1755 ntreeShaderExecTree(shi
->mat
->nodetree
, shi
, &shr
);
1756 shi
->mat
= vlr
->mat
; /* shi->mat is being set in nodetree */
1759 shade_material_loop(shi
, &shr
);
1761 if(bs
->type
==RE_BAKE_NORMALS
) {
1762 shr
.combined
[0]= shi
->vn
[0]/2.0f
+ 0.5f
;
1763 shr
.combined
[1]= 0.5f
- shi
->vn
[1]/2.0f
;
1764 shr
.combined
[2]= shi
->vn
[2]/2.0f
+ 0.5f
;
1766 else if(bs
->type
==RE_BAKE_TEXTURE
) {
1767 shr
.combined
[0]= shi
->r
;
1768 shr
.combined
[1]= shi
->g
;
1769 shr
.combined
[2]= shi
->b
;
1774 char *col
= (char *)(bs
->rect
+ bs
->rectx
*y
+ x
);
1775 col
[0]= FTOCHAR(shr
.combined
[0]);
1776 col
[1]= FTOCHAR(shr
.combined
[1]);
1777 col
[2]= FTOCHAR(shr
.combined
[2]);
1781 float *col
= bs
->rect_float
+ 4*(bs
->rectx
*y
+ x
);
1782 VECCOPY(col
, shr
.combined
);
1787 static int get_next_bake_face(BakeShade
*bs
)
1791 static int v
= 0, vdone
= 0;
1799 BLI_lock_thread(LOCK_CUSTOM1
);
1801 for(; v
<R
.totvlak
; v
++) {
1802 vlr
= RE_findOrAddVlak(&R
, v
);
1804 if(vlr
->ob
->flag
& SELECT
) {
1805 tface
= RE_vlakren_get_tface(&R
, vlr
, 0, NULL
, 0);
1807 if(tface
&& tface
->tpage
) {
1808 Image
*ima
= tface
->tpage
;
1809 ImBuf
*ibuf
= BKE_image_get_ibuf(ima
, NULL
);
1810 float vec
[4]= {0.0f
, 0.0f
, 0.0f
, 0.0f
};
1815 if(ibuf
->rect
==NULL
&& ibuf
->rect_float
==NULL
)
1818 if(ibuf
->rect_float
&& !(ibuf
->channels
==0 || ibuf
->channels
==4))
1821 /* find the image for the first time? */
1822 if(ima
->id
.flag
& LIB_DOIT
) {
1823 ima
->id
.flag
&= ~LIB_DOIT
;
1825 /* we either fill in float or char, this ensures things go fine */
1826 if(ibuf
->rect_float
)
1827 imb_freerectImBuf(ibuf
);
1829 if(R
.r
.bake_flag
& R_BAKE_CLEAR
)
1830 IMB_rectfill(ibuf
, vec
);
1832 /* might be read by UI to set active image for display */
1838 bs
->vdone
++; /* only for error message if nothing was rendered */
1841 BLI_unlock_thread(LOCK_CUSTOM1
);
1847 BLI_unlock_thread(LOCK_CUSTOM1
);
1851 /* already have tested for tface and ima and zspan */
1852 static void shade_tface(BakeShade
*bs
)
1854 VlakRen
*vlr
= bs
->vlr
;
1855 MTFace
*tface
= RE_vlakren_get_tface(&R
, vlr
, 0, NULL
, 0);
1856 Image
*ima
= tface
->tpage
;
1860 /* check valid zspan */
1863 bs
->ibuf
= BKE_image_get_ibuf(ima
, NULL
);
1864 /* note, these calls only free/fill contents of zspan struct, not zspan itself */
1865 zbuf_free_span(bs
->zspan
);
1866 zbuf_alloc_span(bs
->zspan
, bs
->ibuf
->x
, bs
->ibuf
->y
);
1869 bs
->rectx
= bs
->ibuf
->x
;
1870 bs
->recty
= bs
->ibuf
->y
;
1871 bs
->rect
= bs
->ibuf
->rect
;
1872 bs
->rect_float
= bs
->ibuf
->rect_float
;
1875 /* get pixel level vertex coordinates */
1876 for(a
=0; a
<4; a
++) {
1877 vec
[a
][0]= tface
->uv
[a
][0]*(float)bs
->rectx
- 0.5f
;
1878 vec
[a
][1]= tface
->uv
[a
][1]*(float)bs
->recty
- 0.5f
;
1881 /* UV indices have to be corrected for possible quad->tria splits */
1882 i1
= 0; i2
= 1; i3
= 2;
1883 vlr_set_uv_indices(vlr
, &i1
, &i2
, &i3
);
1884 zspan_scanconvert(bs
->zspan
, bs
, vec
[i1
], vec
[i2
], vec
[i3
], do_bake_shade
);
1888 zspan_scanconvert(bs
->zspan
, bs
, vec
[0], vec
[2], vec
[3], do_bake_shade
);
1892 static void *do_bake_thread(void *bs_v
)
1894 BakeShade
*bs
= bs_v
;
1896 while(get_next_bake_face(bs
)) {
1899 /* fast threadsafe break test */
1908 /* using object selection tags, the faces with UV maps get baked */
1909 /* render should have been setup */
1910 /* returns 0 if nothing was handled */
1911 int RE_bake_shade_all_selected(Render
*re
, int type
)
1913 BakeShade handles
[BLENDER_MAX_THREADS
];
1918 /* initialize static vars */
1919 get_next_bake_face(NULL
);
1921 /* baker uses this flag to detect if image was initialized */
1922 for(ima
= G
.main
->image
.first
; ima
; ima
= ima
->id
.next
)
1923 ima
->id
.flag
|= LIB_DOIT
;
1925 /* initialize render global */
1929 BLI_init_threads(&threads
, do_bake_thread
, re
->r
.threads
);
1931 /* get the threads running */
1932 for(a
=0; a
<re
->r
.threads
; a
++) {
1933 /* set defaults in handles */
1934 memset(&handles
[a
], 0, sizeof(BakeShade
));
1936 handles
[a
].ssamp
.shi
[0].lay
= re
->scene
->lay
;
1937 handles
[a
].ssamp
.shi
[0].passflag
= SCE_PASS_COMBINED
;
1938 handles
[a
].ssamp
.shi
[0].combinedflag
= ~(SCE_PASS_SPEC
);
1939 handles
[a
].ssamp
.shi
[0].thread
= a
;
1940 handles
[a
].ssamp
.tot
= 1;
1942 handles
[a
].type
= type
;
1943 handles
[a
].zspan
= MEM_callocN(sizeof(ZSpan
), "zspan for bake");
1945 BLI_insert_thread(&threads
, &handles
[a
]);
1948 /* wait for everything to be done */
1950 while(a
!=re
->r
.threads
) {
1954 for(a
=0; a
<re
->r
.threads
; a
++)
1955 if(handles
[a
].ready
==0)
1960 for(ima
= G
.main
->image
.first
; ima
; ima
= ima
->id
.next
) {
1961 if((ima
->id
.flag
& LIB_DOIT
)==0) {
1962 ImBuf
*ibuf
= BKE_image_get_ibuf(ima
, NULL
);
1963 for(a
=0; a
<re
->r
.bake_filter
; a
++)
1964 IMB_filter_extend(ibuf
);
1965 ibuf
->userflags
|= IB_BITMAPDIRTY
;
1969 /* calculate return value */
1970 for(a
=0; a
<re
->r
.threads
; a
++) {
1971 vdone
+= handles
[a
].vdone
;
1973 zbuf_free_span(handles
[a
].zspan
);
1974 MEM_freeN(handles
[a
].zspan
);
1977 BLI_end_threads(&threads
);
1981 struct Image
*RE_bake_shade_get_image(void)