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 *****
35 /* External modules: */
36 #include "MEM_guardedalloc.h"
38 #include "BLI_arithb.h"
39 #include "BLI_blenlib.h"
40 #include "BLI_jitter.h"
42 #include "BLI_threads.h"
44 #include "BKE_utildefines.h"
46 #include "DNA_image_types.h"
47 #include "DNA_lamp_types.h"
48 #include "DNA_material_types.h"
49 #include "DNA_meshdata_types.h"
50 #include "DNA_group_types.h"
52 #include "BKE_global.h"
53 #include "BKE_image.h"
56 #include "BKE_texture.h"
58 #include "IMB_imbuf_types.h"
59 #include "IMB_imbuf.h"
62 #include "renderpipeline.h"
63 #include "render_types.h"
64 #include "renderdatabase.h"
65 #include "occlusion.h"
66 #include "pixelblending.h"
67 #include "pixelshading.h"
72 #include "RE_raytrace.h"
77 #include "rendercore.h"
80 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
81 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
82 /* only to be used here in this file, it's for speed */
83 extern struct Render R;
84 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
86 /* x and y are current pixels in rect to be rendered */
87 /* do not normalize! */
88 void calc_view_vector(float *view, float x, float y)
91 view[2]= -ABS(R.clipsta);
93 if(R.r.mode & R_ORTHO) {
94 view[0]= view[1]= 0.0f;
98 if(R.r.mode & R_PANORAMA)
101 /* move x and y to real viewplane coords */
102 x= (x/(float)R.winx);
103 view[0]= R.viewplane.xmin + x*(R.viewplane.xmax - R.viewplane.xmin);
105 y= (y/(float)R.winy);
106 view[1]= R.viewplane.ymin + y*(R.viewplane.ymax - R.viewplane.ymin);
108 // if(R.flag & R_SEC_FIELD) {
109 // if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor;
110 // else view[1]= (y+R.ystart+1.0)*R.ycor;
112 // else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor;
114 if(R.r.mode & R_PANORAMA) {
115 float u= view[0] + R.panodxv; float v= view[2];
116 view[0]= R.panoco*u + R.panosi*v;
117 view[2]= -R.panosi*u + R.panoco*v;
122 void calc_renderco_ortho(float *co, float x, float y, int z)
124 /* x and y 3d coordinate can be derived from pixel coord and winmat */
125 float fx= 2.0f/(R.winx*R.winmat[0][0]);
126 float fy= 2.0f/(R.winy*R.winmat[1][1]);
129 co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
130 co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
132 zco= ((float)z)/2147483647.0f;
133 co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
136 void calc_renderco_zbuf(float *co, float *view, int z)
140 /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
141 zco= ((float)z)/2147483647.0f;
142 co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
149 /* also used in zbuf.c and shadbuf.c */
150 int count_mask(unsigned short mask)
153 return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]);
157 static int calchalo_z(HaloRen *har, int zz)
160 if(har->type & HA_ONLYSKY) {
161 if(zz < 0x7FFFFFF0) zz= - 0x7FFFFF; /* edge render messes zvalues */
171 static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, int od, float dist, float xn, float yn, PixStr *ps)
173 float col[4], accol[4], fac;
174 int amount, amountm, zz, flarec, sample, fullsample, mask=0;
176 fullsample= (totsample > 1);
178 accol[0]=accol[1]=accol[2]=accol[3]= 0.0f;
182 amountm= count_mask(ps->mask);
185 zz= calchalo_z(har, ps->z);
186 if((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) {
187 if(shadeHaloFloat(har, col, zz, dist, xn, yn, flarec)) {
191 for(sample=0; sample<totsample; sample++)
192 if(ps->mask & (1 << sample))
193 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
196 fac= ((float)amountm)/(float)R.osa;
197 accol[0]+= fac*col[0];
198 accol[1]+= fac*col[1];
199 accol[2]+= fac*col[2];
200 accol[3]+= fac*col[3];
209 /* now do the sky sub-pixels */
210 amount= R.osa-amount;
212 if(shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec)) {
214 fac= ((float)amount)/(float)R.osa;
215 accol[0]+= fac*col[0];
216 accol[1]+= fac*col[1];
217 accol[2]+= fac*col[2];
218 accol[3]+= fac*col[3];
224 for(sample=0; sample<totsample; sample++)
225 if(!(mask & (1 << sample)))
226 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
234 for(sample=0; sample<totsample; sample++)
235 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
239 static void halo_tile(RenderPart *pa, RenderLayer *rl)
241 RenderLayer *rlpp[RE_MAX_OSA];
243 rcti disprect= pa->disprect, testrect= pa->disprect;
244 float dist, xsq, ysq, xn, yn;
247 int a, *rz, zz, y, sample, totsample, od;
248 short minx, maxx, miny, maxy, x;
249 unsigned int lay= rl->lay;
251 /* we don't render halos in the cropped area, gives errors in flare counter */
253 testrect.xmin+= pa->crop;
254 testrect.xmax-= pa->crop;
255 testrect.ymin+= pa->crop;
256 testrect.ymax-= pa->crop;
259 totsample= get_sample_layers(pa, rl, rlpp);
261 for(a=0; a<R.tothalo; a++) {
262 har= R.sortedhalos[a];
264 /* layer test, clip halo with y */
265 if((har->lay & lay)==0);
266 else if(testrect.ymin > har->maxy);
267 else if(testrect.ymax < har->miny);
270 minx= floor(har->xs-har->rad);
271 maxx= ceil(har->xs+har->rad);
273 if(testrect.xmin > maxx);
274 else if(testrect.xmax < minx);
277 minx= MAX2(minx, testrect.xmin);
278 maxx= MIN2(maxx, testrect.xmax);
280 miny= MAX2(har->miny, testrect.ymin);
281 maxy= MIN2(har->maxy, testrect.ymax);
283 for(y=miny; y<maxy; y++) {
284 int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin);
285 rz= pa->rectz + rectofs;
289 rd= pa->rectdaps + rectofs;
291 yn= (y-har->ys)*R.ycor;
294 for(x=minx; x<maxx; x++, rz++, od++) {
298 if(dist<har->radsq) {
300 halo_pixelstruct(har, rlpp, totsample, od, dist, xn, yn, (PixStr *)*rd);
303 zz= calchalo_z(har, *rz);
304 if((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) {
305 if(shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) {
306 for(sample=0; sample<totsample; sample++)
307 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
317 if(R.test_break(R.tbh) ) break;
321 static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
323 RenderLayer *rlpp[RE_MAX_OSA];
327 intptr_t *rd= pa->rectdaps;
329 int x, y, sample, totsample, fullsample, od;
331 totsample= get_sample_layers(pa, rl, rlpp);
332 fullsample= (totsample > 1);
334 shade_input_initialize(&shi, pa, rl, 0); /* this zero's ShadeInput for us */
336 for(od=0, y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
337 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, od++) {
339 calc_view_vector(shi.view, x, y);
342 PixStr *ps= (PixStr *)*rd;
343 int count, totsamp= 0, mask= 0;
346 if(R.r.mode & R_ORTHO)
347 calc_renderco_ortho(shi.co, (float)x, (float)y, ps->z);
349 calc_renderco_zbuf(shi.co, shi.view, ps->z);
351 totsamp+= count= count_mask(ps->mask);
354 col[0]= col[1]= col[2]= col[3]= 0.0f;
355 renderspothalo(&shi, col, 1.0f);
358 for(sample=0; sample<totsample; sample++) {
359 if(ps->mask & (1 << sample)) {
360 pass= rlpp[sample]->rectf + od*4;
365 if(pass[3]>1.0f) pass[3]= 1.0f;
370 fac= ((float)count)/(float)R.osa;
371 pass= rl->rectf + od*4;
372 pass[0]+= fac*col[0];
373 pass[1]+= fac*col[1];
374 pass[2]+= fac*col[2];
375 pass[3]+= fac*col[3];
376 if(pass[3]>1.0f) pass[3]= 1.0f;
385 col[0]= col[1]= col[2]= col[3]= 0.0f;
386 renderspothalo(&shi, col, 1.0f);
389 for(sample=0; sample<totsample; sample++) {
390 if(!(mask & (1 << sample))) {
391 pass= rlpp[sample]->rectf + od*4;
396 if(pass[3]>1.0f) pass[3]= 1.0f;
401 fac= ((float)R.osa-totsamp)/(float)R.osa;
402 pass= rl->rectf + od*4;
403 pass[0]+= fac*col[0];
404 pass[1]+= fac*col[1];
405 pass[2]+= fac*col[2];
406 pass[3]+= fac*col[3];
407 if(pass[3]>1.0f) pass[3]= 1.0f;
412 if(R.r.mode & R_ORTHO)
413 calc_renderco_ortho(shi.co, (float)x, (float)y, *rz);
415 calc_renderco_zbuf(shi.co, shi.view, *rz);
417 col[0]= col[1]= col[2]= col[3]= 0.0f;
418 renderspothalo(&shi, col, 1.0f);
420 for(sample=0; sample<totsample; sample++) {
421 pass= rlpp[sample]->rectf + od*4;
426 if(pass[3]>1.0f) pass[3]= 1.0f;
433 if(R.test_break(R.tbh)) break;
438 /* ********************* MAINLOOPS ******************** */
441 static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr)
446 add_filt_fmask(curmask, shr->combined, rl->rectf + 4*offset, rectx);
448 for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
449 float *fp, *col= NULL;
452 switch(rpass->passtype) {
454 fp= rpass->rect + offset;
461 case SCE_PASS_DIFFUSE:
467 case SCE_PASS_SHADOW:
473 case SCE_PASS_REFLECT:
476 case SCE_PASS_REFRACT:
482 case SCE_PASS_NORMAL:
486 /* box filter only, gauss will screwup UV too much */
488 float mult= (float)count_mask(curmask)/(float)R.osa;
489 fp= rpass->rect + 3*offset;
490 fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
491 fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
495 case SCE_PASS_INDEXOB:
498 fp= rpass->rect + offset;
500 *fp= (float)shi->obr->ob->index;
509 case SCE_PASS_VECTOR:
511 /* add minimum speed in pixel, no filter */
512 fp= rpass->rect + 4*offset;
513 if( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
514 fp[0]= shr->winspeed[0];
515 fp[1]= shr->winspeed[1];
517 if( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
518 fp[2]= shr->winspeed[2];
519 fp[3]= shr->winspeed[3];
525 fp= rpass->rect + pixsize*offset;
526 add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize);
531 /* non-osa version */
532 static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *shr)
537 fp= rl->rectf + 4*offset;
538 QUATCOPY(fp, shr->combined);
540 for(rpass= rl->passes.first; rpass; rpass= rpass->next) {
541 float *col= NULL, uvcol[3];
544 switch(rpass->passtype) {
546 fp= rpass->rect + offset;
553 case SCE_PASS_DIFFUSE:
559 case SCE_PASS_SHADOW:
565 case SCE_PASS_REFLECT:
568 case SCE_PASS_REFRACT:
574 case SCE_PASS_NORMAL:
579 uvcol[0]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
580 uvcol[1]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
585 case SCE_PASS_VECTOR:
589 case SCE_PASS_INDEXOB:
591 fp= rpass->rect + offset;
592 *fp= (float)shi->obr->ob->index;
596 fp= rpass->rect + offset;
601 fp= rpass->rect + pixsize*offset;
602 for(a=0; a<pixsize; a++)
608 int get_sample_layers(RenderPart *pa, RenderLayer *rl, RenderLayer **rlpp)
611 if(pa->fullresult.first) {
612 int sample, nr= BLI_findindex(&pa->result->layers, rl);
614 for(sample=0; sample<R.osa; sample++) {
615 RenderResult *rr= BLI_findlink(&pa->fullresult, sample);
617 rlpp[sample]= BLI_findlink(&rr->layers, nr);
628 /* only do sky, is default in the solid layer (shade_tile) btw */
629 static void sky_tile(RenderPart *pa, RenderLayer *rl)
631 RenderLayer *rlpp[RE_MAX_OSA];
632 int x, y, od=0, totsample;
634 if(R.r.alphamode!=R_ADDSKY)
637 totsample= get_sample_layers(pa, rl, rlpp);
639 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
640 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od+=4) {
644 for(sample= 0; sample<totsample; sample++) {
645 float *pass= rlpp[sample]->rectf + od;
650 shadeSkyPixel(col, x, y, pa->thread);
658 addAlphaUnderFloat(pass, col);
665 if(R.test_break(R.tbh)) break;
669 static void atm_tile(RenderPart *pa, RenderLayer *rl)
674 RenderLayer *rlpp[RE_MAX_OSA];
678 totsample= get_sample_layers(pa, rl, rlpp);
680 /* check that z pass is enabled */
681 if(pa->rectz==NULL) return;
682 for(zpass= rl->passes.first; zpass; zpass= zpass->next)
683 if(zpass->passtype==SCE_PASS_Z)
686 if(zpass==NULL) return;
688 /* check for at least one sun lamp that its atmosphere flag is is enabled */
689 for(go=R.lights.first; go; go= go->next) {
691 if(lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_AP))
694 /* do nothign and return if there is no sun lamp */
698 /* for each x,y and each sample, and each sun lamp*/
699 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
700 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od++) {
703 for(sample=0; sample<totsample; sample++) {
704 float *zrect= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_Z) + od;
705 float *rgbrect = rlpp[sample]->rectf + 4*od;
709 for(go=R.lights.first; go; go= go->next) {
713 if(lar->type==LA_SUN && lar->sunsky) {
715 /* if it's sky continue and don't apply atmosphere effect on it */
716 if(*zrect >= 9.9e10 || rgbrect[3]==0.0f) {
720 if((lar->sunsky->effect_type & LA_SUN_EFFECT_AP)) {
723 VECCOPY(tmp_rgb, rgbrect);
724 if(rgbrect[3]!=1.0f) { /* de-premul */
725 float div= 1.0f/rgbrect[3];
726 VECMUL(tmp_rgb, div);
728 shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect);
729 if(rgbrect[3]!=1.0f) { /* premul */
730 VECMUL(tmp_rgb, rgbrect[3]);
734 VECCOPY(rgb, tmp_rgb);
738 rgb[0] = 0.5f*rgb[0] + 0.5f*tmp_rgb[0];
739 rgb[1] = 0.5f*rgb[1] + 0.5f*tmp_rgb[1];
740 rgb[2] = 0.5f*rgb[2] + 0.5f*tmp_rgb[2];
746 /* if at least for one sun lamp aerial perspective was applied*/
748 VECCOPY(rgbrect, rgb);
755 static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
757 RenderResult *rr= pa->result;
759 intptr_t *rd, *rectdaps= pa->rectdaps;
761 int x, y, seed, crop=0, offs=0, od;
763 if(R.test_break(R.tbh)) return;
765 /* irregular shadowb buffer creation */
766 if(R.r.mode & R_SHADOW)
767 ISB_create(pa, NULL);
769 /* we set per pixel a fixed seed, for random AO and shadow samples */
770 seed= pa->rectx*pa->disprect.ymin;
772 /* general shader info, passes */
773 shade_sample_initialize(&ssamp, pa, rl);
775 /* occlusion caching */
777 cache_occ_samples(&R, pa, &ssamp);
779 /* filtered render, for now we assume only 1 filter size */
782 rectdaps+= pa->rectx + 1;
786 /* scanline updates have to be 2 lines behind */
788 rr->renrect.ymax= -2*crop;
791 for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
795 for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, od++) {
796 BLI_thread_srandom(pa->thread, seed++);
799 if(shade_samples(&ssamp, (PixStr *)(*rd), x, y)) {
801 /* multisample buffers or filtered mask filling? */
802 if(pa->fullresult.first) {
804 for(samp=0; samp<ssamp.tot; samp++) {
805 int smask= ssamp.shi[samp].mask;
806 for(a=0; a<R.osa; a++) {
809 add_passes(ssamp.rlpp[a], od, &ssamp.shi[samp], &ssamp.shr[samp]);
814 for(samp=0; samp<ssamp.tot; samp++)
815 add_filt_passes(rl, ssamp.shi[samp].mask, pa->rectx, od, &ssamp.shi[samp], &ssamp.shr[samp]);
821 rectdaps+= pa->rectx;
824 if(y&1) if(R.test_break(R.tbh)) break;
827 /* disable scanline updating */
830 if(R.r.mode & R_SHADOW)
834 free_occ_samples(&R, pa);
837 /* ************* pixel struct ******** */
840 static PixStrMain *addpsmain(ListBase *lb)
844 psm= (PixStrMain *)MEM_mallocN(sizeof(PixStrMain),"pixstrMain");
845 BLI_addtail(lb, psm);
847 psm->ps= (PixStr *)MEM_mallocN(4096*sizeof(PixStr),"pixstr");
853 static void freeps(ListBase *lb)
855 PixStrMain *psm, *psmnext;
857 for(psm= lb->first; psm; psm= psmnext) {
863 lb->first= lb->last= NULL;
866 static void addps(ListBase *lb, intptr_t *rd, int obi, int facenr, int z, int maskz, unsigned short mask)
869 PixStr *ps, *last= NULL;
875 if( ps->obi == obi && ps->facenr == facenr ) {
884 /* make new PS (pixel struct) */
887 if(psm->counter==4095)
890 ps= psm->ps + psm->counter++;
892 if(last) last->next= ps;
893 else *rd= (intptr_t)ps;
904 static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
912 for(pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) {
914 addcol[0]= *arect * R.r.edgeR;
915 addcol[1]= *arect * R.r.edgeG;
916 addcol[2]= *arect * R.r.edgeB;
918 addAlphaOverFloat(rectf, addcol);
923 static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl)
925 RenderLayer *rlpp[RE_MAX_OSA];
926 int y, sample, totsample;
928 totsample= get_sample_layers(pa, rl, rlpp);
930 for(sample= 0; sample<totsample; sample++) {
931 float *rectf= rlpp[sample]->rectf;
933 for(y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
934 if(rectf[3] >= 1.0f);
935 else if(rectf[3] > 0.0f) {
936 rectf[0] /= rectf[3];
937 rectf[1] /= rectf[3];
938 rectf[2] /= rectf[3];
944 /* adds only alpha values */
945 void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz)
947 /* use zbuffer to define edges, add it to the image */
948 int y, x, col, *rz, *rz1, *rz2, *rz3;
949 int zval1, zval2, zval3;
952 /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */
956 for(y=0; y<pa->recty; y++)
957 for(x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4;
963 rf= rectf+pa->rectx+1;
965 for(y=0; y<pa->recty-2; y++) {
966 for(x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) {
968 /* prevent overflow with sky z values */
969 zval1= rz1[0] + 2*rz1[1] + rz1[2];
970 zval2= 2*rz2[0] + 2*rz2[2];
971 zval3= rz3[0] + 2*rz3[1] + rz3[2];
973 col= ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 );
977 if(col > (1<<16)) col= (1<<16);
978 else col= (R.r.edgeint*col)>>8;
983 if(col>255) fcol= 1.0f;
984 else fcol= (float)col/255.0f;
987 *rf+= fcol/(float)R.osa;
998 /* shift back zbuf values, we might need it still */
1000 for(y=0; y<pa->recty; y++)
1001 for(x=0; x<pa->rectx; x++, rz++) (*rz)<<= 4;
1005 static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
1007 /* for all pixels with max speed, set to zero */
1008 RenderLayer *rlpp[RE_MAX_OSA];
1010 int a, sample, totsample;
1012 totsample= get_sample_layers(pa, rl, rlpp);
1014 for(sample= 0; sample<totsample; sample++) {
1015 fp= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_VECTOR);
1018 for(a= 4*pa->rectx*pa->recty - 1; a>=0; a--)
1019 if(fp[a] == PASS_VECTOR_MAX) fp[a]= 0.0f;
1023 static unsigned short *make_solid_mask(RenderPart *pa)
1025 intptr_t *rd= pa->rectdaps;
1026 unsigned short *solidmask, *sp;
1029 if(rd==NULL) return NULL;
1031 sp=solidmask= MEM_mallocN(sizeof(short)*pa->rectx*pa->recty, "solidmask");
1033 for(x=pa->rectx*pa->recty; x>0; x--, rd++, sp++) {
1035 PixStr *ps= (PixStr *)*rd;
1038 for(ps= ps->next; ps; ps= ps->next)
1048 static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dmask, unsigned short smask)
1050 unsigned short shared= dmask & smask;
1051 float mul= 1.0 - source[3];
1053 if(shared) { /* overlapping masks */
1055 /* masks differ, we make a mixture of 'add' and 'over' */
1057 float shared_bits= (float)count_mask(shared); /* alpha over */
1058 float tot_bits= (float)count_mask(smask|dmask); /* alpha add */
1060 float add= (tot_bits - shared_bits)/tot_bits; /* add level */
1061 mul= add + (1.0f-add)*mul;
1064 else if(dmask && smask) {
1065 /* works for premul only, of course */
1066 dest[0]+= source[0];
1067 dest[1]+= source[1];
1068 dest[2]+= source[2];
1069 dest[3]+= source[3];
1074 dest[0]= (mul*dest[0]) + source[0];
1075 dest[1]= (mul*dest[1]) + source[1];
1076 dest[2]= (mul*dest[2]) + source[2];
1077 dest[3]= (mul*dest[3]) + source[3];
1080 typedef struct ZbufSolidData {
1086 void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
1088 ZbufSolidData *sdata= (ZbufSolidData*)data;
1089 ListBase *lb= sdata->psmlist;
1090 intptr_t *rd= pa->rectdaps;
1091 int *ro= zspan->recto;
1092 int *rp= zspan->rectp;
1093 int *rz= zspan->rectz;
1094 int *rm= zspan->rectmask;
1096 int mask= 1<<sample;
1098 for(y=0; y<pa->recty; y++) {
1099 for(x=0; x<pa->rectx; x++, rd++, rp++, ro++, rz++, rm++) {
1101 addps(lb, rd, *ro, *rp, *rz, (zspan->rectmask)? *rm: 0, mask);
1106 if(sdata->rl->layflag & SCE_LAY_EDGE)
1107 if(R.r.mode & R_EDGE)
1108 edge_enhance_tile(pa, sdata->edgerect, zspan->rectz);
1111 /* main call for shading Delta Accum, for OSA */
1112 /* supposed to be fully threadable! */
1113 void zbufshadeDA_tile(RenderPart *pa)
1115 RenderResult *rr= pa->result;
1117 ListBase psmlist= {NULL, NULL};
1118 float *edgerect= NULL;
1120 /* allocate the necessary buffers */
1121 /* zbuffer inits these rects */
1122 pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1123 pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1124 pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1125 for(rl= rr->layers.first; rl; rl= rl->next) {
1126 if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
1127 pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
1129 /* initialize pixelstructs and edge buffer */
1130 addpsmain(&psmlist);
1131 pa->rectdaps= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "zbufDArectd");
1133 if(rl->layflag & SCE_LAY_EDGE)
1134 if(R.r.mode & R_EDGE)
1135 edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
1137 /* always fill visibility */
1138 for(pa->sample=0; pa->sample<R.osa; pa->sample+=4) {
1139 ZbufSolidData sdata;
1142 sdata.psmlist= &psmlist;
1143 sdata.edgerect= edgerect;
1144 zbuffer_solid(pa, rl, make_pixelstructs, &sdata);
1145 if(R.test_break(R.tbh)) break;
1149 if(rl->layflag & SCE_LAY_SOLID)
1150 shadeDA_tile(pa, rl);
1152 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
1153 if(R.flag & R_LAMPHALO)
1154 if(rl->layflag & SCE_LAY_HALO)
1155 lamphalo_tile(pa, rl);
1157 /* halo before ztra, because ztra fills in zbuffer now */
1159 if(rl->layflag & SCE_LAY_HALO)
1163 if(R.flag & R_ZTRA || R.totstrand) {
1164 if(rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
1165 if(pa->fullresult.first) {
1166 zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
1169 unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */
1171 /* allocate, but not free here, for asynchronous display of this rect in main thread */
1172 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
1174 /* swap for live updates, and it is used in zbuf.c!!! */
1175 SWAP(float *, rl->acolrect, rl->rectf);
1176 ztramask= zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
1177 SWAP(float *, rl->acolrect, rl->rectf);
1179 /* zbuffer transp only returns ztramask if there's solid rendered */
1181 solidmask= make_solid_mask(pa);
1183 if(ztramask && solidmask) {
1184 unsigned short *sps= solidmask, *spz= ztramask;
1185 unsigned short fullmask= (1<<R.osa)-1;
1186 float *fcol= rl->rectf; float *acol= rl->acolrect;
1189 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) {
1190 if(*sps == fullmask)
1191 addAlphaOverFloat(fcol, acol);
1193 addAlphaOverFloatMask(fcol, acol, *sps, *spz);
1197 float *fcol= rl->rectf; float *acol= rl->acolrect;
1199 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
1200 addAlphaOverFloat(fcol, acol);
1203 if(solidmask) MEM_freeN(solidmask);
1204 if(ztramask) MEM_freeN(ztramask);
1210 if(rl->layflag & SCE_LAY_SKY)
1213 /* sky before edge */
1214 if(rl->layflag & SCE_LAY_SKY)
1218 if(rl->layflag & SCE_LAY_EDGE)
1219 if(R.r.mode & R_EDGE)
1220 edge_enhance_add(pa, rl->rectf, edgerect);
1222 if(rl->passflag & SCE_PASS_VECTOR)
1223 reset_sky_speed(pa, rl);
1225 /* de-premul alpha */
1226 if(R.r.alphamode & R_ALPHAKEY)
1227 convert_to_key_alpha(pa, rl);
1229 /* free stuff within loop! */
1230 MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
1233 if(edgerect) MEM_freeN(edgerect);
1237 MEM_freeN(pa->rectmask);
1243 MEM_freeN(pa->recto); pa->recto= NULL;
1244 MEM_freeN(pa->rectp); pa->rectp= NULL;
1245 MEM_freeN(pa->rectz); pa->rectz= NULL;
1247 /* display active layer */
1248 rr->renrect.ymin=rr->renrect.ymax= 0;
1249 rr->renlay= render_get_active_layer(&R, rr);
1253 /* ------------------------------------------------------------------------ */
1255 /* non OSA case, full tile render */
1256 /* supposed to be fully threadable! */
1257 void zbufshade_tile(RenderPart *pa)
1260 RenderResult *rr= pa->result;
1263 float *edgerect= NULL;
1265 /* fake pixel struct, to comply to osa render */
1269 /* zbuffer code clears/inits rects */
1270 pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1271 pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1272 pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1274 for(rl= rr->layers.first; rl; rl= rl->next) {
1275 if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
1276 pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
1278 /* general shader info, passes */
1279 shade_sample_initialize(&ssamp, pa, rl);
1281 zbuffer_solid(pa, rl, NULL, NULL);
1283 if(!R.test_break(R.tbh)) { /* NOTE: this if() is not consistant */
1285 /* edges only for solid part, ztransp doesn't support it yet anti-aliased */
1286 if(rl->layflag & SCE_LAY_EDGE) {
1287 if(R.r.mode & R_EDGE) {
1288 edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
1289 edge_enhance_tile(pa, edgerect, pa->rectz);
1293 /* initialize scanline updates for main thread */
1294 rr->renrect.ymin= 0;
1297 if(rl->layflag & SCE_LAY_SOLID) {
1298 float *fcol= rl->rectf;
1299 int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz;
1300 int x, y, offs=0, seed;
1302 /* we set per pixel a fixed seed, for random AO and shadow samples */
1303 seed= pa->rectx*pa->disprect.ymin;
1305 /* irregular shadowb buffer creation */
1306 if(R.r.mode & R_SHADOW)
1307 ISB_create(pa, NULL);
1310 cache_occ_samples(&R, pa, &ssamp);
1312 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1313 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) {
1314 /* per pixel fixed seed */
1315 BLI_thread_srandom(pa->thread, seed++);
1321 if(shade_samples(&ssamp, &ps, x, y)) {
1322 /* combined and passes */
1323 add_passes(rl, offs, ssamp.shi, ssamp.shr);
1328 if(R.test_break(R.tbh)) break;
1332 free_occ_samples(&R, pa);
1334 if(R.r.mode & R_SHADOW)
1338 /* disable scanline updating */
1342 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
1343 if(R.flag & R_LAMPHALO)
1344 if(rl->layflag & SCE_LAY_HALO)
1345 lamphalo_tile(pa, rl);
1347 /* halo before ztra, because ztra fills in zbuffer now */
1349 if(rl->layflag & SCE_LAY_HALO)
1352 if(R.flag & R_ZTRA || R.totstrand) {
1353 if(rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
1357 /* allocate, but not free here, for asynchronous display of this rect in main thread */
1358 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
1360 /* swap for live updates */
1361 SWAP(float *, rl->acolrect, rl->rectf);
1362 zbuffer_transp_shade(pa, rl, rl->rectf, NULL);
1363 SWAP(float *, rl->acolrect, rl->rectf);
1365 fcol= rl->rectf; acol= rl->acolrect;
1366 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
1367 addAlphaOverFloat(fcol, acol);
1373 if(rl->layflag & SCE_LAY_SKY)
1376 /* sky before edge */
1377 if(rl->layflag & SCE_LAY_SKY)
1380 if(!R.test_break(R.tbh)) {
1381 if(rl->layflag & SCE_LAY_EDGE)
1382 if(R.r.mode & R_EDGE)
1383 edge_enhance_add(pa, rl->rectf, edgerect);
1386 if(rl->passflag & SCE_PASS_VECTOR)
1387 reset_sky_speed(pa, rl);
1389 /* de-premul alpha */
1390 if(R.r.alphamode & R_ALPHAKEY)
1391 convert_to_key_alpha(pa, rl);
1393 if(edgerect) MEM_freeN(edgerect);
1397 MEM_freeN(pa->rectmask);
1402 /* display active layer */
1403 rr->renrect.ymin=rr->renrect.ymax= 0;
1404 rr->renlay= render_get_active_layer(&R, rr);
1406 MEM_freeN(pa->recto); pa->recto= NULL;
1407 MEM_freeN(pa->rectp); pa->rectp= NULL;
1408 MEM_freeN(pa->rectz); pa->rectz= NULL;
1411 /* SSS preprocess tile render, fully threadable */
1412 typedef struct ZBufSSSHandle {
1418 static void addps_sss(void *cb_handle, int obi, int facenr, int x, int y, int z)
1420 ZBufSSSHandle *handle = cb_handle;
1421 RenderPart *pa= handle->pa;
1423 /* extra border for filter gives double samples on part edges,
1425 if(x<pa->crop || x>=pa->rectx-pa->crop)
1427 if(y<pa->crop || y>=pa->recty-pa->crop)
1431 intptr_t *rs= pa->rectall + pa->rectx*y + x;
1433 addps(&handle->psmlist, rs, obi, facenr, z, 0, 0);
1437 int *rz= pa->rectz + pa->rectx*y + x;
1438 int *rp= pa->rectp + pa->rectx*y + x;
1439 int *ro= pa->recto + pa->rectx*y + x;
1450 int *rz= pa->rectbackz + pa->rectx*y + x;
1451 int *rp= pa->rectbackp + pa->rectx*y + x;
1452 int *ro= pa->rectbacko + pa->rectx*y + x;
1464 static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRen *obi, VlakRen *vlr, int quad, float x, float y, float z, float *co, float *color, float *area)
1466 ShadeInput *shi= ssamp->shi;
1468 float texfac, orthoarea, nor[3], alpha, sx, sy;
1470 /* cache for shadow */
1471 shi->samplenr= R.shadowsamplenr[shi->thread]++;
1474 shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
1476 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
1482 /* we estimate the area here using shi->dxco and shi->dyco. we need to
1483 enabled shi->osatex these are filled. we compute two areas, one with
1484 the normal pointed at the camera and one with the original normal, and
1485 then clamp to avoid a too large contribution from a single pixel */
1488 VECCOPY(nor, shi->facenor);
1489 calc_view_vector(shi->facenor, sx, sy);
1490 Normalize(shi->facenor);
1491 shade_input_set_viewco(shi, x, y, sx, sy, z);
1492 orthoarea= VecLength(shi->dxco)*VecLength(shi->dyco);
1494 VECCOPY(shi->facenor, nor);
1495 shade_input_set_viewco(shi, x, y, sx, sy, z);
1496 *area= VecLength(shi->dxco)*VecLength(shi->dyco);
1497 *area= MIN2(*area, 2.0f*orthoarea);
1499 shade_input_set_uv(shi);
1500 shade_input_set_normals(shi);
1502 /* we don't want flipped normals, they screw up back scattering */
1504 shade_input_flip_normals(shi);
1506 /* not a pretty solution, but fixes common cases */
1507 if(shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) {
1512 /* if nodetree, use the material that we are currently preprocessing
1513 instead of the node material */
1514 if(shi->mat->nodetree && shi->mat->use_nodes)
1517 /* init material vars */
1518 // note, keep this synced with render_types.h
1519 memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
1520 shi->har= shi->mat->har;
1523 shade_input_set_shade_texco(shi);
1525 shade_samples_do_AO(ssamp);
1526 shade_material_loop(shi, &shr);
1528 VECCOPY(co, shi->co);
1529 VECCOPY(color, shr.combined);
1531 /* texture blending */
1532 texfac= shi->mat->sss_texfac;
1534 alpha= shr.combined[3];
1538 static void zbufshade_sss_free(RenderPart *pa)
1541 MEM_freeN(pa->rectall); pa->rectall= NULL;
1542 freeps(&handle.psmlist);
1544 MEM_freeN(pa->rectz); pa->rectz= NULL;
1545 MEM_freeN(pa->rectp); pa->rectp= NULL;
1546 MEM_freeN(pa->recto); pa->recto= NULL;
1547 MEM_freeN(pa->rectbackz); pa->rectbackz= NULL;
1548 MEM_freeN(pa->rectbackp); pa->rectbackp= NULL;
1549 MEM_freeN(pa->rectbacko); pa->rectbacko= NULL;
1553 void zbufshade_sss_tile(RenderPart *pa)
1557 ZBufSSSHandle handle;
1558 RenderResult *rr= pa->result;
1561 Material *mat= re->sss_mat;
1562 float (*co)[3], (*color)[3], *area, *fcol;
1563 int x, y, seed, quad, totpoint, display = !(re->r.scemode & R_PREVIEWBUTS);
1564 int *ro, *rz, *rp, *rbo, *rbz, *rbp, lay;
1571 /* setup pixelstr list and buffer for zbuffering */
1576 handle.psmlist.first= handle.psmlist.last= NULL;
1577 addpsmain(&handle.psmlist);
1579 pa->rectall= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "rectall");
1581 pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1582 pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1583 pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1584 pa->rectbacko= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbacko");
1585 pa->rectbackp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackp");
1586 pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz");
1589 /* setup shade sample with correct passes */
1590 memset(&ssamp, 0, sizeof(ssamp));
1591 shade_sample_initialize(&ssamp, pa, rr->layers.first);
1594 for(rl=rr->layers.first; rl; rl=rl->next) {
1595 ssamp.shi[0].lay |= rl->lay;
1596 ssamp.shi[0].layflag |= rl->layflag;
1597 ssamp.shi[0].passflag |= rl->passflag;
1598 ssamp.shi[0].combinedflag |= ~rl->pass_xor;
1601 rl= rr->layers.first;
1602 ssamp.shi[0].passflag |= SCE_PASS_RGBA|SCE_PASS_COMBINED;
1603 ssamp.shi[0].combinedflag &= ~(SCE_PASS_SPEC);
1604 ssamp.shi[0].mat_override= NULL;
1605 ssamp.shi[0].light_override= NULL;
1606 lay= ssamp.shi[0].lay;
1608 /* create the pixelstrs to be used later */
1609 zbuffer_sss(pa, lay, &handle, addps_sss);
1611 if(handle.totps==0) {
1612 zbufshade_sss_free(pa);
1618 co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo");
1619 color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor");
1620 area= MEM_mallocN(sizeof(float)*handle.totps, "SSSArea");
1623 /* create ISB (does not work currently!) */
1624 if(re->r.mode & R_SHADOW)
1625 ISB_create(pa, NULL);
1629 /* initialize scanline updates for main thread */
1630 rr->renrect.ymin= 0;
1634 seed= pa->rectx*pa->disprect.ymin;
1647 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1648 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, fcol+=4) {
1649 /* per pixel fixed seed */
1650 BLI_thread_srandom(pa->thread, seed++);
1654 /* for each sample in this pixel, shade it */
1655 for(ps=(PixStr*)*rs; ps; ps=ps->next) {
1656 ObjectInstanceRen *obi= &re->objectinstance[ps->obi];
1657 ObjectRen *obr= obi->obr;
1658 vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
1659 quad= (ps->facenr & RE_QUAD_OFFS);
1662 shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, z,
1663 co[totpoint], color[totpoint], &area[totpoint]);
1667 VECADD(fcol, fcol, color);
1676 ObjectInstanceRen *obi= &re->objectinstance[*ro];
1677 ObjectRen *obr= obi->obr;
1680 vlr= RE_findOrAddVlak(obr, (*rp-1) & RE_QUAD_MASK);
1681 quad= ((*rp) & RE_QUAD_OFFS);
1683 shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rz,
1684 co[totpoint], color[totpoint], &area[totpoint]);
1686 VECADD(fcol, fcol, color[totpoint]);
1695 if(*rbp != 0 && !(*rbp == *(rp-1) && *rbo == *(ro-1))) {
1696 ObjectInstanceRen *obi= &re->objectinstance[*rbo];
1697 ObjectRen *obr= obi->obr;
1700 vlr= RE_findOrAddVlak(obr, (*rbp-1) & RE_QUAD_MASK);
1701 quad= ((*rbp) & RE_QUAD_OFFS);
1703 shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rbz,
1704 co[totpoint], color[totpoint], &area[totpoint]);
1706 /* to indicate this is a back sample */
1707 area[totpoint]= -area[totpoint];
1709 VECADD(fcol, fcol, color[totpoint]);
1714 rbz++; rbp++; rbo++;
1720 if(re->test_break(re->tbh)) break;
1723 /* note: after adding we do not free these arrays, sss keeps them */
1725 sss_add_points(re, co, color, area, totpoint);
1734 if(re->r.mode & R_SHADOW)
1739 /* display active layer */
1740 rr->renrect.ymin=rr->renrect.ymax= 0;
1741 rr->renlay= render_get_active_layer(&R, rr);
1744 zbufshade_sss_free(pa);
1747 /* ------------------------------------------------------------------------ */
1749 static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har) /* postprocess version */
1751 float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf;
1752 float haloxs, haloys;
1753 int minx, maxx, miny, maxy, x, y;
1755 /* calculate the disprect mapped coordinate for halo. note: rectx is disprect corrected */
1756 haloxs= har->xs - R.disprect.xmin;
1757 haloys= har->ys - R.disprect.ymin;
1759 har->miny= miny= haloys - har->rad/R.ycor;
1760 har->maxy= maxy= haloys + har->rad/R.ycor;
1763 else if(rr->recty<miny);
1765 minx= floor(haloxs-har->rad);
1766 maxx= ceil(haloxs+har->rad);
1769 else if(rr->rectx<minx);
1773 if(maxx>=rr->rectx) maxx= rr->rectx-1;
1775 if(maxy>rr->recty) maxy= rr->recty;
1777 rectft= rectf+ 4*rr->rectx*miny;
1779 for(y=miny; y<maxy; y++) {
1783 yn= (y - haloys)*R.ycor;
1786 for(x=minx; x<=maxx; x++) {
1790 if(dist<har->radsq) {
1792 if(shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec))
1793 addalphaAddfacFloat(rtf, colf, har->add);
1798 rectft+= 4*rr->rectx;
1800 if(R.test_break(R.tbh)) break;
1805 /* ------------------------------------------------------------------------ */
1807 static void renderflare(RenderResult *rr, float *rectf, HaloRen *har)
1809 extern float hashvectf[];
1812 float *rc, rad, alfa, visifac, vec[3];
1816 fla.linec= fla.ringc= fla.flarec= 0;
1821 visifac= R.ycor*(har->pixels);
1822 /* all radials added / r^3 == 1.0f! */
1823 visifac /= (har->rad*har->rad*har->rad);
1828 /* first halo: just do */
1830 har->rad= rad*ma->flaresize*visifac;
1831 har->radsq= har->rad*har->rad;
1834 har->alfa= alfa*visifac;
1836 renderhalo_post(rr, rectf, har);
1838 /* next halo's: the flares */
1839 rc= hashvectf + ma->seed2;
1841 for(b=1; b<har->flarec; b++) {
1846 fla.alfa= ma->flareboost*fabs(alfa*visifac*rc[3]);
1847 fla.hard= 20.0f + fabs(70*rc[7]);
1850 type= (int)(fabs(3.9*rc[6]));
1852 fla.rad= ma->subsize*sqrt(fabs(2.0f*har->rad*rc[4]));
1856 fla.rad+= R.rectx/10;
1859 fla.radsq= fla.rad*fla.rad;
1861 vec[0]= 1.4*rc[5]*(har->xs-R.winx/2);
1862 vec[1]= 1.4*rc[5]*(har->ys-R.winy/2);
1863 vec[2]= 32.0f*sqrt(vec[0]*vec[0] + vec[1]*vec[1] + 1.0f);
1865 fla.xs= R.winx/2 + vec[0] + (1.2+rc[8])*R.rectx*vec[0]/vec[2];
1866 fla.ys= R.winy/2 + vec[1] + (1.2+rc[8])*R.rectx*vec[1]/vec[2];
1868 if(R.flag & R_SEC_FIELD) {
1869 if(R.r.mode & R_ODDFIELD) fla.ys += 0.5;
1872 if(type & 1) fla.type= HA_FLARECIRC;
1874 renderhalo_post(rr, rectf, &fla);
1877 if(type & 2) fla.type= HA_FLARECIRC;
1879 renderhalo_post(rr, rectf, &fla);
1885 /* needs recode... integrate this better! */
1886 void add_halo_flare(Render *re)
1888 RenderResult *rr= re->result;
1891 int a, mode, do_draw=0;
1893 /* for now, we get the first renderlayer in list with halos set */
1894 for(rl= rr->layers.first; rl; rl= rl->next)
1895 if(rl->layflag & SCE_LAY_HALO)
1898 if(rl==NULL || rl->rectf==NULL)
1902 R.r.mode &= ~R_PANORAMA;
1904 project_renderdata(&R, projectverto, 0, 0, 0);
1906 for(a=0; a<R.tothalo; a++) {
1907 har= R.sortedhalos[a];
1911 renderflare(rr, rl->rectf, har);
1916 /* weak... the display callback wants an active renderlayer pointer... */
1918 re->display_draw(re->ddh, rr, NULL);
1924 /* ************************* used for shaded view ************************ */
1926 /* if *re, then initialize, otherwise execute */
1927 void RE_shade_external(Render *re, ShadeInput *shi, ShadeResult *shr)
1930 static ObjectRen obr;
1931 static ObjectInstanceRen obi;
1937 /* fake render face */
1938 memset(&vlr, 0, sizeof(VlakRen));
1939 memset(&obr, 0, sizeof(ObjectRen));
1940 memset(&obi, 0, sizeof(ObjectInstanceRen));
1950 if(shi->mat->nodetree && shi->mat->use_nodes)
1951 ntreeShaderExecTree(shi->mat->nodetree, shi, shr);
1953 /* copy all relevant material vars, note, keep this synced with render_types.h */
1954 memcpy(&shi->r, &shi->mat->r, 23*sizeof(float));
1955 shi->har= shi->mat->har;
1957 shade_material_loop(shi, shr);
1961 /* ************************* bake ************************ */
1964 typedef struct BakeShade {
1966 ObjectInstanceRen *obi;
1973 int rectx, recty, quad, type, vdone, ready;
1982 char *rect_mask; /* bake pixel mask */
1984 float dxco[3], dyco[3];
1987 /* bake uses a char mask to know what has been baked */
1988 #define BAKE_MASK_NULL 0
1989 #define BAKE_MASK_MARGIN 1
1990 #define BAKE_MASK_BAKED 2
1991 static void bake_mask_filter_extend( char *mask, int width, int height )
1993 char *row1, *row2, *row3;
1999 /* make a copy, to prevent flooding */
2000 temprect= MEM_dupallocN(mask);
2002 for(y=1; y<=height; y++) {
2004 row1= (char *)(temprect + (y-2)*rowlen);
2005 row2= row1 + rowlen;
2006 row3= row2 + rowlen;
2012 for(x=0; x<rowlen; x++) {
2013 if (mask[((y-1)*rowlen)+x]==0) {
2014 if (*row1 || *row2 || *row3 || *(row1+1) || *(row3+1) ) {
2015 mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN;
2016 } else if((x!=rowlen-1) && (*(row1+2) || *(row2+2) || *(row3+2)) ) {
2017 mask[((y-1)*rowlen)+x] = BAKE_MASK_MARGIN;
2022 row1++; row2++; row3++;
2026 MEM_freeN(temprect);
2029 static void bake_mask_clear( ImBuf *ibuf, char *mask, char val )
2032 if (ibuf->rect_float) {
2033 for(x=0; x<ibuf->x; x++) {
2034 for(y=0; y<ibuf->y; y++) {
2035 if (mask[ibuf->x*y + x] == val) {
2036 float *col= ibuf->rect_float + 4*(ibuf->x*y + x);
2037 col[0] = col[1] = col[2] = col[3] = 0.0f;
2044 for(x=0; x<ibuf->x; x++) {
2045 for(y=0; y<ibuf->y; y++) {
2046 if (mask[ibuf->x*y + x] == val) {
2047 char *col= (char *)(ibuf->rect + ibuf->x*y + x);
2048 col[0] = col[1] = col[2] = col[3] = 0;
2055 static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int isect, int x, int y, float u, float v)
2058 /* raytrace intersection with different u,v than scanconvert */
2061 shade_input_set_triangle_i(shi, obi, vlr, 2, 1, 3);
2063 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 3);
2066 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
2069 /* regular scanconvert */
2071 shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
2073 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
2076 /* cache for shadow */
2077 shi->samplenr= R.shadowsamplenr[shi->thread]++;
2079 shi->mask= 0xFFFF; /* all samples */
2086 shade_input_set_uv(shi);
2087 shade_input_set_normals(shi);
2089 /* no normal flip */
2091 shade_input_flip_normals(shi);
2093 /* set up view vector to look right at the surface (note that the normal
2094 * is negated in the renderer so it does not need to be done here) */
2095 shi->view[0]= shi->vn[0];
2096 shi->view[1]= shi->vn[1];
2097 shi->view[2]= shi->vn[2];
2100 static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int quad, int x, int y, float u, float v, float *tvn, float *ttang)
2102 BakeShade *bs= handle;
2103 ShadeSample *ssamp= &bs->ssamp;
2105 VlakRen *vlr= shi->vlr;
2107 /* init material vars */
2108 memcpy(&shi->r, &shi->mat->r, 23*sizeof(float)); // note, keep this synced with render_types.h
2109 shi->har= shi->mat->har;
2111 if(bs->type==RE_BAKE_AO) {
2112 ambient_occlusion(shi);
2114 if(R.r.bake_flag & R_BAKE_NORMALIZE)
2115 VECCOPY(shr.combined, shi->ao)
2117 ambient_occlusion_to_diffuse(shi, shr.combined);
2120 if (bs->type==RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */
2121 shi->r = shi->g = shi->b = 1.0f;
2123 shade_input_set_shade_texco(shi);
2125 if(!ELEM3(bs->type, RE_BAKE_NORMALS, RE_BAKE_TEXTURE, RE_BAKE_SHADOW))
2126 shade_samples_do_AO(ssamp);
2128 if(shi->mat->nodetree && shi->mat->use_nodes) {
2129 ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
2130 shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
2133 shade_material_loop(shi, &shr);
2135 if(bs->type==RE_BAKE_NORMALS) {
2138 VECCOPY(nor, shi->vn);
2140 if(R.r.bake_normal_space == R_BAKE_SPACE_CAMERA);
2141 else if(R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
2142 float mat[3][3], imat[3][3];
2146 VECCOPY(mat[0], ttang);
2147 Crossf(mat[1], tvn, ttang);
2148 VECCOPY(mat[2], tvn);
2151 VECCOPY(mat[0], shi->nmaptang);
2152 Crossf(mat[1], shi->vn, shi->nmaptang);
2153 VECCOPY(mat[2], shi->vn);
2157 Mat3MulVecfl(imat, nor);
2159 else if(R.r.bake_normal_space == R_BAKE_SPACE_OBJECT)
2160 Mat4Mul3Vecfl(ob->imat, nor); /* ob->imat includes viewinv! */
2161 else if(R.r.bake_normal_space == R_BAKE_SPACE_WORLD)
2162 Mat4Mul3Vecfl(R.viewinv, nor);
2164 Normalize(nor); /* in case object has scaling */
2166 shr.combined[0]= nor[0]/2.0f + 0.5f;
2167 shr.combined[1]= 0.5f - nor[1]/2.0f;
2168 shr.combined[2]= nor[2]/2.0f + 0.5f;
2170 else if(bs->type==RE_BAKE_TEXTURE) {
2171 shr.combined[0]= shi->r;
2172 shr.combined[1]= shi->g;
2173 shr.combined[2]= shi->b;
2174 shr.alpha = shi->alpha;
2176 else if(bs->type==RE_BAKE_SHADOW) {
2177 VECCOPY(shr.combined, shr.shad);
2178 shr.alpha = shi->alpha;
2182 if(bs->rect_float) {
2183 float *col= bs->rect_float + 4*(bs->rectx*y + x);
2184 VECCOPY(col, shr.combined);
2185 if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) {
2192 char *col= (char *)(bs->rect + bs->rectx*y + x);
2193 col[0]= FTOCHAR(shr.combined[0]);
2194 col[1]= FTOCHAR(shr.combined[1]);
2195 col[2]= FTOCHAR(shr.combined[2]);
2198 if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) {
2199 col[3]= FTOCHAR(shr.alpha);
2205 if (bs->rect_mask) {
2206 bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED;
2210 static void bake_displacement(void *handle, ShadeInput *shi, float dist, int x, int y)
2212 BakeShade *bs= handle;
2215 if(R.r.bake_flag & R_BAKE_NORMALIZE && R.r.bake_maxdist) {
2216 disp = (dist+R.r.bake_maxdist) / (R.r.bake_maxdist*2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/
2218 disp = 0.5 + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
2221 if(bs->rect_float) {
2222 float *col= bs->rect_float + 4*(bs->rectx*y + x);
2223 col[0] = col[1] = col[2] = disp;
2226 char *col= (char *)(bs->rect + bs->rectx*y + x);
2227 col[0]= FTOCHAR(disp);
2228 col[1]= FTOCHAR(disp);
2229 col[2]= FTOCHAR(disp);
2232 if (bs->rect_mask) {
2233 bs->rect_mask[bs->rectx*y + x] = BAKE_MASK_BAKED;
2237 static int bake_check_intersect(Isect *is, int ob, RayFace *face)
2239 BakeShade *bs = (BakeShade*)is->userdata;
2241 /* no direction checking for now, doesn't always improve the result
2242 * (INPR(shi->facenor, bs->dir) > 0.0f); */
2244 return (R.objectinstance[ob].obr->ob != bs->actob);
2247 static int bake_intersect_tree(RayTree* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist)
2252 /* might be useful to make a user setting for maxsize*/
2253 if(R.r.bake_maxdist > 0.0f)
2254 maxdist= R.r.bake_maxdist;
2256 maxdist= RE_ray_tree_max_size(R.raytree) + R.r.bake_biasdist;
2258 VECADDFAC(isect->start, start, dir, -R.r.bake_biasdist);
2260 isect->end[0] = isect->start[0] + dir[0]*maxdist*sign;
2261 isect->end[1] = isect->start[1] + dir[1]*maxdist*sign;
2262 isect->end[2] = isect->start[2] + dir[2]*maxdist*sign;
2264 hit = RE_ray_tree_intersect_check(R.raytree, isect, bake_check_intersect);
2266 hitco[0] = isect->start[0] + isect->labda*isect->vec[0];
2267 hitco[1] = isect->start[1] + isect->labda*isect->vec[1];
2268 hitco[2] = isect->start[2] + isect->labda*isect->vec[2];
2270 *dist= VecLenf(start, hitco);
2276 static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3)
2278 VlakRen *vlr= bs->vlr;
2279 float A, d1, d2, d3, *v1, *v2, *v3;
2292 /* formula derived from barycentric coordinates:
2293 * (uvArea1*v1 + uvArea2*v2 + uvArea3*v3)/uvArea
2294 * then taking u and v partial derivatives to get dxco and dyco */
2295 A= (uv2[0] - uv1[0])*(uv3[1] - uv1[1]) - (uv3[0] - uv1[0])*(uv2[1] - uv1[1]);
2297 if(fabs(A) > FLT_EPSILON) {
2300 d1= uv2[1] - uv3[1];
2301 d2= uv3[1] - uv1[1];
2302 d3= uv1[1] - uv2[1];
2303 bs->dxco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
2304 bs->dxco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
2305 bs->dxco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
2307 d1= uv3[0] - uv2[0];
2308 d2= uv1[0] - uv3[0];
2309 d3= uv2[0] - uv1[0];
2310 bs->dyco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
2311 bs->dyco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
2312 bs->dyco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
2315 bs->dxco[0]= bs->dxco[1]= bs->dxco[2]= 0.0f;
2316 bs->dyco[0]= bs->dyco[1]= bs->dyco[2]= 0.0f;
2319 if(bs->obi->flag & R_TRANSFORMED) {
2320 Mat3MulVecfl(bs->obi->nmat, bs->dxco);
2321 Mat3MulVecfl(bs->obi->nmat, bs->dyco);
2325 static void do_bake_shade(void *handle, int x, int y, float u, float v)
2327 BakeShade *bs= handle;
2328 VlakRen *vlr= bs->vlr;
2329 ObjectInstanceRen *obi= bs->obi;
2330 Object *ob= obi->obr->ob;
2331 float l, *v1, *v2, *v3, tvn[3], ttang[3];
2333 ShadeSample *ssamp= &bs->ssamp;
2334 ShadeInput *shi= ssamp->shi;
2336 /* fast threadsafe break test */
2337 if(R.test_break(R.tbh))
2340 /* setup render coordinates */
2355 shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
2356 shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
2357 shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
2359 if(obi->flag & R_TRANSFORMED)
2360 Mat4MulVecfl(obi->mat, shi->co);
2362 VECCOPY(shi->dxco, bs->dxco);
2363 VECCOPY(shi->dyco, bs->dyco);
2366 bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v);
2368 if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) {
2369 shade_input_set_shade_texco(shi);
2370 VECCOPY(tvn, shi->vn);
2371 VECCOPY(ttang, shi->nmaptang);
2374 /* if we are doing selected to active baking, find point on other face */
2376 Isect isec, minisec;
2377 float co[3], minco[3], dist, mindist=0.0f;
2378 int hit, sign, dir=1;
2380 /* intersect with ray going forward and backward*/
2382 memset(&minisec, 0, sizeof(minisec));
2383 minco[0]= minco[1]= minco[2]= 0.0f;
2385 VECCOPY(bs->dir, shi->vn);
2387 for(sign=-1; sign<=1; sign+=2) {
2388 memset(&isec, 0, sizeof(isec));
2389 isec.mode= RE_RAY_MIRROR;
2390 isec.faceorig= (RayFace*)vlr;
2391 isec.oborig= RAY_OBJECT_SET(&R, obi);
2394 if(bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) {
2395 if(!hit || VecLenf(shi->co, co) < VecLenf(shi->co, minco)) {
2405 if (bs->type==RE_BAKE_DISPLACEMENT) {
2407 bake_displacement(handle, shi, (dir==-1)? mindist:-mindist, x, y);
2409 bake_displacement(handle, shi, 0.0f, x, y);
2413 /* if hit, we shade from the new point, otherwise from point one starting face */
2415 vlr= (VlakRen*)minisec.face;
2416 obi= RAY_OBJECT_GET(&R, minisec.ob);
2417 quad= (minisec.isect == 2);
2418 VECCOPY(shi->co, minco);
2422 bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v);
2426 if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT)
2427 bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang);
2429 bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0);
2432 static int get_next_bake_face(BakeShade *bs)
2437 static int v= 0, vdone= 0;
2438 static ObjectInstanceRen *obi= NULL;
2443 obi= R.instancetable.first;
2447 BLI_lock_thread(LOCK_CUSTOM1);
2449 for(; obi; obi=obi->next, v=0) {
2452 for(; v<obr->totvlak; v++) {
2453 vlr= RE_findOrAddVlak(obr, v);
2455 if((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
2456 tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
2458 if(tface && tface->tpage) {
2459 Image *ima= tface->tpage;
2460 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
2461 float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f};
2466 if(ibuf->rect==NULL && ibuf->rect_float==NULL)
2469 if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
2472 /* find the image for the first time? */
2473 if(ima->id.flag & LIB_DOIT) {
2474 ima->id.flag &= ~LIB_DOIT;
2476 /* we either fill in float or char, this ensures things go fine */
2477 if(ibuf->rect_float)
2478 imb_freerectImBuf(ibuf);
2480 if(R.r.bake_flag & R_BAKE_CLEAR)
2481 IMB_rectfill(ibuf, vec);
2483 /* might be read by UI to set active image for display */
2490 bs->vdone++; /* only for error message if nothing was rendered */
2493 BLI_unlock_thread(LOCK_CUSTOM1);
2500 BLI_unlock_thread(LOCK_CUSTOM1);
2504 /* already have tested for tface and ima and zspan */
2505 static void shade_tface(BakeShade *bs)
2507 VlakRen *vlr= bs->vlr;
2508 ObjectInstanceRen *obi= bs->obi;
2509 ObjectRen *obr= obi->obr;
2510 MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
2511 Image *ima= tface->tpage;
2515 /* check valid zspan */
2518 bs->ibuf= BKE_image_get_ibuf(ima, NULL);
2519 /* note, these calls only free/fill contents of zspan struct, not zspan itself */
2520 zbuf_free_span(bs->zspan);
2521 zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
2524 bs->rectx= bs->ibuf->x;
2525 bs->recty= bs->ibuf->y;
2526 bs->rect= bs->ibuf->rect;
2527 bs->rect_float= bs->ibuf->rect_float;
2531 if (bs->ibuf->userdata==NULL) {
2532 BLI_lock_thread(LOCK_CUSTOM1);
2533 if (bs->ibuf->userdata==NULL) { /* since the thread was locked, its possible another thread alloced the value */
2534 bs->ibuf->userdata = (void *)MEM_callocN(sizeof(char)*bs->rectx*bs->recty, "BakeMask");
2535 bs->rect_mask= (char *)bs->ibuf->userdata;
2537 BLI_unlock_thread(LOCK_CUSTOM1);
2539 bs->rect_mask= (char *)bs->ibuf->userdata;
2543 /* get pixel level vertex coordinates */
2544 for(a=0; a<4; a++) {
2545 vec[a][0]= tface->uv[a][0]*(float)bs->rectx - 0.5f;
2546 vec[a][1]= tface->uv[a][1]*(float)bs->recty - 0.5f;
2549 /* UV indices have to be corrected for possible quad->tria splits */
2550 i1= 0; i2= 1; i3= 2;
2551 vlr_set_uv_indices(vlr, &i1, &i2, &i3);
2552 bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]);
2553 zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade);
2557 bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]);
2558 zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade);
2562 static void *do_bake_thread(void *bs_v)
2564 BakeShade *bs= bs_v;
2566 while(get_next_bake_face(bs)) {
2569 /* fast threadsafe break test */
2570 if(R.test_break(R.tbh))
2578 /* using object selection tags, the faces with UV maps get baked */
2579 /* render should have been setup */
2580 /* returns 0 if nothing was handled */
2581 int RE_bake_shade_all_selected(Render *re, int type, Object *actob)
2583 BakeShade handles[BLENDER_MAX_THREADS];
2586 int a, vdone=0, usemask=0;
2588 /* initialize render global */
2592 /* initialize static vars */
2593 get_next_bake_face(NULL);
2595 /* do we need a mask? */
2596 if (re->r.bake_filter && (re->r.bake_flag & R_BAKE_CLEAR)==0)
2599 /* baker uses this flag to detect if image was initialized */
2600 for(ima= G.main->image.first; ima; ima= ima->id.next) {
2601 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
2602 ima->id.flag |= LIB_DOIT;
2604 ibuf->userdata = NULL; /* use for masking if needed */
2607 BLI_init_threads(&threads, do_bake_thread, re->r.threads);
2609 /* get the threads running */
2610 for(a=0; a<re->r.threads; a++) {
2611 /* set defaults in handles */
2612 memset(&handles[a], 0, sizeof(BakeShade));
2614 handles[a].ssamp.shi[0].lay= re->scene->lay;
2616 if (type==RE_BAKE_SHADOW) {
2617 handles[a].ssamp.shi[0].passflag= SCE_PASS_SHADOW;
2619 handles[a].ssamp.shi[0].passflag= SCE_PASS_COMBINED;
2621 handles[a].ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
2622 handles[a].ssamp.shi[0].thread= a;
2623 handles[a].ssamp.tot= 1;
2625 handles[a].type= type;
2626 handles[a].actob= actob;
2627 handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
2629 handles[a].usemask = usemask;
2631 BLI_insert_thread(&threads, &handles[a]);
2634 /* wait for everything to be done */
2636 while(a!=re->r.threads) {
2640 for(a=0; a<re->r.threads; a++)
2641 if(handles[a].ready==0)
2645 /* filter and refresh images */
2646 for(ima= G.main->image.first; ima; ima= ima->id.next) {
2647 if((ima->id.flag & LIB_DOIT)==0) {
2648 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
2649 if (re->r.bake_filter) {
2651 /* extend the mask +2 pixels from the image,
2652 * this is so colors dont blend in from outside */
2655 for(a=0; a<re->r.bake_filter; a++)
2656 bake_mask_filter_extend((char *)ibuf->userdata, ibuf->x, ibuf->y);
2658 temprect = MEM_dupallocN(ibuf->userdata);
2660 /* expand twice to clear this many pixels, so they blend back in */
2661 bake_mask_filter_extend(temprect, ibuf->x, ibuf->y);
2662 bake_mask_filter_extend(temprect, ibuf->x, ibuf->y);
2664 /* clear all pixels in the margin*/
2665 bake_mask_clear(ibuf, temprect, BAKE_MASK_MARGIN);
2666 MEM_freeN(temprect);
2669 for(a=0; a<re->r.bake_filter; a++) {
2670 /*the mask, ibuf->userdata - can be null, in this case only zero alpha is used */
2671 IMB_filter_extend(ibuf, (char *)ibuf->userdata);
2674 if (ibuf->userdata) {
2675 MEM_freeN(ibuf->userdata);
2676 ibuf->userdata= NULL;
2679 ibuf->userflags |= IB_BITMAPDIRTY;
2680 if (ibuf->rect_float) IMB_rect_from_float(ibuf);
2684 /* calculate return value */
2685 for(a=0; a<re->r.threads; a++) {
2686 vdone+= handles[a].vdone;
2688 zbuf_free_span(handles[a].zspan);
2689 MEM_freeN(handles[a].zspan);
2692 BLI_end_threads(&threads);
2696 struct Image *RE_bake_shade_get_image(void)