2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * Contributors: Hos, Robert Wenzlaff.
22 * Contributors: 2004/2005/2006 Blender Foundation, full recode
24 * ***** END GPL LICENSE BLOCK *****
27 /** \file blender/render/intern/source/rendercore.c
39 /* External modules: */
40 #include "MEM_guardedalloc.h"
43 #include "BLI_blenlib.h"
44 #include "BLI_jitter.h"
46 #include "BLI_threads.h"
47 #include "BLI_utildefines.h"
51 #include "DNA_image_types.h"
52 #include "DNA_lamp_types.h"
53 #include "DNA_material_types.h"
54 #include "DNA_meshdata_types.h"
55 #include "DNA_group_types.h"
57 #include "BKE_global.h"
58 #include "BKE_image.h"
61 #include "BKE_texture.h"
62 #include "BKE_scene.h"
64 #include "IMB_imbuf_types.h"
65 #include "IMB_imbuf.h"
66 #include "IMB_colormanagement.h"
69 #include "rayintersection.h"
70 #include "rayobject.h"
71 #include "renderpipeline.h"
72 #include "render_result.h"
73 #include "render_types.h"
74 #include "renderdatabase.h"
75 #include "occlusion.h"
76 #include "pixelblending.h"
77 #include "pixelshading.h"
86 #include "rendercore.h"
89 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
90 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
91 /* only to be used here in this file, it's for speed */
92 extern struct Render R;
93 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
95 /* x and y are current pixels in rect to be rendered */
96 /* do not normalize! */
97 void calc_view_vector(float view[3], float x, float y)
100 view[2]= -ABS(R.clipsta);
102 if (R.r.mode & R_ORTHO) {
103 view[0]= view[1]= 0.0f;
107 if (R.r.mode & R_PANORAMA) {
111 /* move x and y to real viewplane coords */
112 x = (x / (float)R.winx);
113 view[0] = R.viewplane.xmin + x * BLI_rctf_size_x(&R.viewplane);
115 y = (y / (float)R.winy);
116 view[1] = R.viewplane.ymin + y * BLI_rctf_size_y(&R.viewplane);
118 // if (R.flag & R_SEC_FIELD) {
119 // if (R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor;
120 // else view[1]= (y+R.ystart+1.0)*R.ycor;
122 // else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor;
124 if (R.r.mode & R_PANORAMA) {
125 float u= view[0] + R.panodxv; float v= view[2];
126 view[0]= R.panoco*u + R.panosi*v;
127 view[2]= -R.panosi*u + R.panoco*v;
132 void calc_renderco_ortho(float co[3], float x, float y, int z)
134 /* x and y 3d coordinate can be derived from pixel coord and winmat */
135 float fx= 2.0f/(R.winx*R.winmat[0][0]);
136 float fy= 2.0f/(R.winy*R.winmat[1][1]);
139 co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0];
140 co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1];
142 zco= ((float)z)/2147483647.0f;
143 co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
146 void calc_renderco_zbuf(float co[3], const float view[3], int z)
150 /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */
151 zco= ((float)z)/2147483647.0f;
152 co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] );
159 /* also used in zbuf.c and shadbuf.c */
160 int count_mask(unsigned short mask)
163 return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]);
167 static int calchalo_z(HaloRen *har, int zz)
170 if (har->type & HA_ONLYSKY) {
171 if (zz < 0x7FFFFFF0) zz= - 0x7FFFFF; /* edge render messes zvalues */
181 static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, int od, float dist, float xn, float yn, PixStr *ps)
183 float col[4], accol[4], fac;
184 int amount, amountm, zz, flarec, sample, fullsample, mask=0;
186 fullsample= (totsample > 1);
188 accol[0] = accol[1] = accol[2] = accol[3]= 0.0f;
189 col[0] = col[1] = col[2] = col[3]= 0.0f;
193 amountm= count_mask(ps->mask);
196 zz= calchalo_z(har, ps->z);
197 if ((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) {
198 if (shadeHaloFloat(har, col, zz, dist, xn, yn, flarec)) {
202 for (sample=0; sample<totsample; sample++)
203 if (ps->mask & (1 << sample))
204 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
207 fac= ((float)amountm)/(float)R.osa;
208 accol[0]+= fac*col[0];
209 accol[1]+= fac*col[1];
210 accol[2]+= fac*col[2];
211 accol[3]+= fac*col[3];
220 /* now do the sky sub-pixels */
221 amount= R.osa-amount;
223 if (shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec)) {
225 fac= ((float)amount)/(float)R.osa;
226 accol[0]+= fac*col[0];
227 accol[1]+= fac*col[1];
228 accol[2]+= fac*col[2];
229 accol[3]+= fac*col[3];
235 for (sample=0; sample<totsample; sample++)
236 if (!(mask & (1 << sample)))
237 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
245 for (sample=0; sample<totsample; sample++)
246 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
250 static void halo_tile(RenderPart *pa, RenderLayer *rl)
252 RenderLayer *rlpp[RE_MAX_OSA];
254 rcti disprect= pa->disprect, testrect= pa->disprect;
255 float dist, xsq, ysq, xn, yn;
258 int a, *rz, zz, y, sample, totsample, od;
259 short minx, maxx, miny, maxy, x;
260 unsigned int lay= rl->lay;
262 /* we don't render halos in the cropped area, gives errors in flare counter */
264 testrect.xmin+= pa->crop;
265 testrect.xmax-= pa->crop;
266 testrect.ymin+= pa->crop;
267 testrect.ymax-= pa->crop;
270 totsample= get_sample_layers(pa, rl, rlpp);
272 for (a=0; a<R.tothalo; a++) {
273 har= R.sortedhalos[a];
275 /* layer test, clip halo with y */
276 if ((har->lay & lay) == 0) {
279 else if (testrect.ymin > har->maxy) {
282 else if (testrect.ymax < har->miny) {
287 minx= floor(har->xs-har->rad);
288 maxx= ceil(har->xs+har->rad);
290 if (testrect.xmin > maxx) {
293 else if (testrect.xmax < minx) {
298 minx = max_ii(minx, testrect.xmin);
299 maxx = min_ii(maxx, testrect.xmax);
301 miny = max_ii(har->miny, testrect.ymin);
302 maxy = min_ii(har->maxy, testrect.ymax);
304 for (y=miny; y<maxy; y++) {
305 int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin);
306 rz= pa->rectz + rectofs;
310 rd= pa->rectdaps + rectofs;
312 yn= (y-har->ys)*R.ycor;
315 for (x=minx; x<maxx; x++, rz++, od++) {
319 if (dist<har->radsq) {
321 halo_pixelstruct(har, rlpp, totsample, od, dist, xn, yn, (PixStr *)*rd);
324 zz= calchalo_z(har, *rz);
325 if ((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) {
326 if (shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) {
327 for (sample=0; sample<totsample; sample++)
328 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add);
338 if (R.test_break(R.tbh) ) break;
342 static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
344 RenderLayer *rlpp[RE_MAX_OSA];
348 intptr_t *rd= pa->rectdaps;
350 int x, y, sample, totsample, fullsample, od;
352 totsample= get_sample_layers(pa, rl, rlpp);
353 fullsample= (totsample > 1);
355 shade_input_initialize(&shi, pa, rl, 0); /* this zero's ShadeInput for us */
357 for (od=0, y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
358 for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, od++) {
360 calc_view_vector(shi.view, x, y);
363 PixStr *ps= (PixStr *)*rd;
364 int count, totsamp= 0, mask= 0;
367 if (R.r.mode & R_ORTHO)
368 calc_renderco_ortho(shi.co, (float)x, (float)y, ps->z);
370 calc_renderco_zbuf(shi.co, shi.view, ps->z);
372 totsamp+= count= count_mask(ps->mask);
375 col[0]= col[1]= col[2]= col[3]= 0.0f;
376 renderspothalo(&shi, col, 1.0f);
379 for (sample=0; sample<totsample; sample++) {
380 if (ps->mask & (1 << sample)) {
381 pass= rlpp[sample]->rectf + od*4;
386 if (pass[3]>1.0f) pass[3]= 1.0f;
391 fac= ((float)count)/(float)R.osa;
392 pass= rl->rectf + od*4;
393 pass[0]+= fac*col[0];
394 pass[1]+= fac*col[1];
395 pass[2]+= fac*col[2];
396 pass[3]+= fac*col[3];
397 if (pass[3]>1.0f) pass[3]= 1.0f;
406 col[0]= col[1]= col[2]= col[3]= 0.0f;
407 renderspothalo(&shi, col, 1.0f);
410 for (sample=0; sample<totsample; sample++) {
411 if (!(mask & (1 << sample))) {
412 pass= rlpp[sample]->rectf + od*4;
417 if (pass[3]>1.0f) pass[3]= 1.0f;
422 fac= ((float)R.osa-totsamp)/(float)R.osa;
423 pass= rl->rectf + od*4;
424 pass[0]+= fac*col[0];
425 pass[1]+= fac*col[1];
426 pass[2]+= fac*col[2];
427 pass[3]+= fac*col[3];
428 if (pass[3]>1.0f) pass[3]= 1.0f;
433 if (R.r.mode & R_ORTHO)
434 calc_renderco_ortho(shi.co, (float)x, (float)y, *rz);
436 calc_renderco_zbuf(shi.co, shi.view, *rz);
438 col[0]= col[1]= col[2]= col[3]= 0.0f;
439 renderspothalo(&shi, col, 1.0f);
441 for (sample=0; sample<totsample; sample++) {
442 pass= rlpp[sample]->rectf + od*4;
447 if (pass[3]>1.0f) pass[3]= 1.0f;
454 if (R.test_break(R.tbh)) break;
459 /* ********************* MAINLOOPS ******************** */
462 static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr)
467 add_filt_fmask(curmask, shr->combined, rl->rectf + 4*offset, rectx);
469 for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
470 float *fp, *col= NULL;
473 switch (rpass->passtype) {
475 fp= rpass->rect + offset;
485 case SCE_PASS_DIFFUSE:
491 case SCE_PASS_SHADOW:
497 case SCE_PASS_ENVIRONMENT:
500 case SCE_PASS_INDIRECT:
503 case SCE_PASS_REFLECT:
506 case SCE_PASS_REFRACT:
509 case SCE_PASS_NORMAL:
513 /* box filter only, gauss will screwup UV too much */
515 float mult= (float)count_mask(curmask)/(float)R.osa;
516 fp= rpass->rect + 3*offset;
517 fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
518 fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
522 case SCE_PASS_INDEXOB:
525 fp= rpass->rect + offset;
527 *fp= (float)shi->obr->ob->index;
530 case SCE_PASS_INDEXMA:
533 fp= rpass->rect + offset;
535 *fp= (float)shi->mat->index;
544 case SCE_PASS_VECTOR:
546 /* add minimum speed in pixel, no filter */
547 fp= rpass->rect + 4*offset;
548 if ( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
549 fp[0]= shr->winspeed[0];
550 fp[1]= shr->winspeed[1];
552 if ( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
553 fp[2]= shr->winspeed[2];
554 fp[3]= shr->winspeed[3];
559 case SCE_PASS_RAYHITS:
566 fp= rpass->rect + pixsize*offset;
567 add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize);
572 /* non-osa version */
573 static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *shr)
578 fp= rl->rectf + 4*offset;
579 copy_v4_v4(fp, shr->combined);
581 for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
582 float *col= NULL, uvcol[3];
585 switch (rpass->passtype) {
587 fp= rpass->rect + offset;
597 case SCE_PASS_DIFFUSE:
603 case SCE_PASS_SHADOW:
609 case SCE_PASS_ENVIRONMENT:
612 case SCE_PASS_INDIRECT:
615 case SCE_PASS_REFLECT:
618 case SCE_PASS_REFRACT:
621 case SCE_PASS_NORMAL:
626 uvcol[0]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
627 uvcol[1]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
632 case SCE_PASS_VECTOR:
636 case SCE_PASS_INDEXOB:
638 fp= rpass->rect + offset;
639 *fp= (float)shi->obr->ob->index;
642 case SCE_PASS_INDEXMA:
644 fp= rpass->rect + offset;
645 *fp= (float)shi->mat->index;
649 fp= rpass->rect + offset;
652 case SCE_PASS_RAYHITS:
658 fp= rpass->rect + pixsize*offset;
659 for (a=0; a<pixsize; a++)
665 int get_sample_layers(RenderPart *pa, RenderLayer *rl, RenderLayer **rlpp)
668 if (pa->fullresult.first) {
669 int sample, nr= BLI_findindex(&pa->result->layers, rl);
671 for (sample=0; sample<R.osa; sample++) {
672 RenderResult *rr= BLI_findlink(&pa->fullresult, sample);
674 rlpp[sample]= BLI_findlink(&rr->layers, nr);
685 /* only do sky, is default in the solid layer (shade_tile) btw */
686 static void sky_tile(RenderPart *pa, RenderLayer *rl)
688 RenderLayer *rlpp[RE_MAX_OSA];
689 int x, y, od=0, totsample;
691 if (R.r.alphamode!=R_ADDSKY)
694 totsample= get_sample_layers(pa, rl, rlpp);
696 for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
697 for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od+=4) {
699 int sample, done = FALSE;
701 for (sample= 0; sample<totsample; sample++) {
702 float *pass= rlpp[sample]->rectf + od;
707 shadeSkyPixel(col, x, y, pa->thread);
712 copy_v4_v4(pass, col);
715 addAlphaUnderFloat(pass, col);
722 if (R.test_break(R.tbh)) break;
726 static void atm_tile(RenderPart *pa, RenderLayer *rl)
731 RenderLayer *rlpp[RE_MAX_OSA];
735 totsample= get_sample_layers(pa, rl, rlpp);
737 /* check that z pass is enabled */
738 if (pa->rectz==NULL) return;
739 for (zpass= rl->passes.first; zpass; zpass= zpass->next)
740 if (zpass->passtype==SCE_PASS_Z)
743 if (zpass==NULL) return;
745 /* check for at least one sun lamp that its atmosphere flag is enabled */
746 for (go=R.lights.first; go; go= go->next) {
748 if (lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_AP))
751 /* do nothign and return if there is no sun lamp */
755 /* for each x,y and each sample, and each sun lamp*/
756 for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++) {
757 for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od++) {
760 for (sample=0; sample<totsample; sample++) {
761 float *zrect= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_Z) + od;
762 float *rgbrect = rlpp[sample]->rectf + 4*od;
766 for (go=R.lights.first; go; go= go->next) {
770 if (lar->type==LA_SUN && lar->sunsky) {
772 /* if it's sky continue and don't apply atmosphere effect on it */
773 if (*zrect >= 9.9e10f || rgbrect[3]==0.0f) {
777 if ((lar->sunsky->effect_type & LA_SUN_EFFECT_AP)) {
780 /* skip if worldspace lamp vector is below horizon */
781 if (go->ob->obmat[2][2] < 0.f) {
785 copy_v3_v3(tmp_rgb, rgbrect);
786 if (rgbrect[3]!=1.0f) { /* de-premul */
787 mul_v3_fl(tmp_rgb, 1.0f/rgbrect[3]);
789 shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect);
790 if (rgbrect[3]!=1.0f) { /* premul */
791 mul_v3_fl(tmp_rgb, rgbrect[3]);
795 copy_v3_v3(rgb, tmp_rgb);
799 rgb[0] = 0.5f*rgb[0] + 0.5f*tmp_rgb[0];
800 rgb[1] = 0.5f*rgb[1] + 0.5f*tmp_rgb[1];
801 rgb[2] = 0.5f*rgb[2] + 0.5f*tmp_rgb[2];
807 /* if at least for one sun lamp aerial perspective was applied*/
809 copy_v3_v3(rgbrect, rgb);
816 static void shadeDA_tile(RenderPart *pa, RenderLayer *rl)
818 RenderResult *rr= pa->result;
820 intptr_t *rd, *rectdaps= pa->rectdaps;
822 int x, y, seed, crop=0, offs=0, od;
824 if (R.test_break(R.tbh)) return;
826 /* irregular shadowb buffer creation */
827 if (R.r.mode & R_SHADOW)
828 ISB_create(pa, NULL);
830 /* we set per pixel a fixed seed, for random AO and shadow samples */
831 seed= pa->rectx*pa->disprect.ymin;
833 /* general shader info, passes */
834 shade_sample_initialize(&ssamp, pa, rl);
836 /* occlusion caching */
838 cache_occ_samples(&R, pa, &ssamp);
840 /* filtered render, for now we assume only 1 filter size */
843 rectdaps+= pa->rectx + 1;
847 /* scanline updates have to be 2 lines behind */
848 rr->renrect.ymin = 0;
849 rr->renrect.ymax = -2*crop;
852 for (y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) {
856 for (x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, od++) {
857 BLI_thread_srandom(pa->thread, seed++);
860 if (shade_samples(&ssamp, (PixStr *)(*rd), x, y)) {
862 /* multisample buffers or filtered mask filling? */
863 if (pa->fullresult.first) {
865 for (samp=0; samp<ssamp.tot; samp++) {
866 int smask= ssamp.shi[samp].mask;
867 for (a=0; a<R.osa; a++) {
870 add_passes(ssamp.rlpp[a], od, &ssamp.shi[samp], &ssamp.shr[samp]);
875 for (samp=0; samp<ssamp.tot; samp++)
876 add_filt_passes(rl, ssamp.shi[samp].mask, pa->rectx, od, &ssamp.shi[samp], &ssamp.shr[samp]);
882 rectdaps+= pa->rectx;
885 if (y&1) if (R.test_break(R.tbh)) break;
888 /* disable scanline updating */
891 if (R.r.mode & R_SHADOW)
895 free_occ_samples(&R, pa);
898 /* ************* pixel struct ******** */
901 static PixStrMain *addpsmain(ListBase *lb)
905 psm= (PixStrMain *)MEM_mallocN(sizeof(PixStrMain), "pixstrMain");
906 BLI_addtail(lb, psm);
908 psm->ps= (PixStr *)MEM_mallocN(4096*sizeof(PixStr), "pixstr");
914 static void freeps(ListBase *lb)
916 PixStrMain *psm, *psmnext;
918 for (psm= lb->first; psm; psm= psmnext) {
924 lb->first= lb->last= NULL;
927 static void addps(ListBase *lb, intptr_t *rd, int obi, int facenr, int z, int maskz, unsigned short mask)
930 PixStr *ps, *last= NULL;
936 if ( ps->obi == obi && ps->facenr == facenr ) {
945 /* make new PS (pixel struct) */
948 if (psm->counter==4095)
951 ps= psm->ps + psm->counter++;
953 if (last) last->next= ps;
954 else *rd= (intptr_t)ps;
965 static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect)
973 for (pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) {
974 if (*arect != 0.0f) {
975 addcol[0]= *arect * R.r.edgeR;
976 addcol[1]= *arect * R.r.edgeG;
977 addcol[2]= *arect * R.r.edgeB;
979 addAlphaOverFloat(rectf, addcol);
984 static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl)
986 RenderLayer *rlpp[RE_MAX_OSA];
987 int y, sample, totsample;
989 totsample= get_sample_layers(pa, rl, rlpp);
991 for (sample= 0; sample<totsample; sample++) {
992 float *rectf= rlpp[sample]->rectf;
994 for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
995 if (rectf[3] >= 1.0f) {
998 else if (rectf[3] > 0.0f) {
999 rectf[0] /= rectf[3];
1000 rectf[1] /= rectf[3];
1001 rectf[2] /= rectf[3];
1007 /* clamp alpha and RGB to 0..1 and 0..inf, can go outside due to filter */
1008 static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl)
1010 RenderLayer *rlpp[RE_MAX_OSA];
1011 int y, sample, totsample;
1013 totsample= get_sample_layers(pa, rl, rlpp);
1015 /* not for full sample, there we clamp after compositing */
1019 for (sample= 0; sample<totsample; sample++) {
1020 float *rectf= rlpp[sample]->rectf;
1022 for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
1023 rectf[0] = MAX2(rectf[0], 0.0f);
1024 rectf[1] = MAX2(rectf[1], 0.0f);
1025 rectf[2] = MAX2(rectf[2], 0.0f);
1026 CLAMP(rectf[3], 0.0f, 1.0f);
1031 /* adds only alpha values */
1032 static void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz)
1034 /* use zbuffer to define edges, add it to the image */
1035 int y, x, col, *rz, *rz1, *rz2, *rz3;
1036 int zval1, zval2, zval3;
1039 /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */
1041 if (rz==NULL) return;
1043 for (y=0; y<pa->recty; y++)
1044 for (x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4;
1050 rf= rectf+pa->rectx+1;
1052 for (y=0; y<pa->recty-2; y++) {
1053 for (x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) {
1055 /* prevent overflow with sky z values */
1056 zval1= rz1[0] + 2*rz1[1] + rz1[2];
1057 zval2= 2*rz2[0] + 2*rz2[2];
1058 zval3= rz3[0] + 2*rz3[1] + rz3[2];
1060 col= ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 );
1061 if (col<0) col= -col;
1064 if (col > (1<<16)) col= (1<<16);
1065 else col= (R.r.edgeint*col)>>8;
1070 if (col>255) fcol= 1.0f;
1071 else fcol= (float)col/255.0f;
1074 *rf+= fcol/(float)R.osa;
1085 /* shift back zbuf values, we might need it still */
1087 for (y=0; y<pa->recty; y++)
1088 for (x=0; x<pa->rectx; x++, rz++) (*rz)<<= 4;
1092 static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
1094 /* for all pixels with max speed, set to zero */
1095 RenderLayer *rlpp[RE_MAX_OSA];
1097 int a, sample, totsample;
1099 totsample= get_sample_layers(pa, rl, rlpp);
1101 for (sample= 0; sample<totsample; sample++) {
1102 fp= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_VECTOR);
1103 if (fp==NULL) break;
1105 for (a= 4*pa->rectx*pa->recty - 1; a>=0; a--)
1106 if (fp[a] == PASS_VECTOR_MAX) fp[a]= 0.0f;
1110 static unsigned short *make_solid_mask(RenderPart *pa)
1112 intptr_t *rd= pa->rectdaps;
1113 unsigned short *solidmask, *sp;
1116 if (rd==NULL) return NULL;
1118 sp=solidmask= MEM_mallocN(sizeof(short)*pa->rectx*pa->recty, "solidmask");
1120 for (x=pa->rectx*pa->recty; x>0; x--, rd++, sp++) {
1122 PixStr *ps= (PixStr *)*rd;
1125 for (ps= ps->next; ps; ps= ps->next)
1135 static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dmask, unsigned short smask)
1137 unsigned short shared= dmask & smask;
1138 float mul= 1.0f - source[3];
1140 if (shared) { /* overlapping masks */
1142 /* masks differ, we make a mixture of 'add' and 'over' */
1143 if (shared!=dmask) {
1144 float shared_bits= (float)count_mask(shared); /* alpha over */
1145 float tot_bits= (float)count_mask(smask|dmask); /* alpha add */
1147 float add= (tot_bits - shared_bits)/tot_bits; /* add level */
1148 mul= add + (1.0f-add)*mul;
1151 else if (dmask && smask) {
1152 /* works for premul only, of course */
1153 dest[0]+= source[0];
1154 dest[1]+= source[1];
1155 dest[2]+= source[2];
1156 dest[3]+= source[3];
1161 dest[0]= (mul*dest[0]) + source[0];
1162 dest[1]= (mul*dest[1]) + source[1];
1163 dest[2]= (mul*dest[2]) + source[2];
1164 dest[3]= (mul*dest[3]) + source[3];
1167 typedef struct ZbufSolidData {
1173 static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data)
1175 ZbufSolidData *sdata= (ZbufSolidData*)data;
1176 ListBase *lb= sdata->psmlist;
1177 intptr_t *rd= pa->rectdaps;
1178 int *ro= zspan->recto;
1179 int *rp= zspan->rectp;
1180 int *rz= zspan->rectz;
1181 int *rm= zspan->rectmask;
1183 int mask= 1<<sample;
1185 for (y=0; y<pa->recty; y++) {
1186 for (x=0; x<pa->rectx; x++, rd++, rp++, ro++, rz++, rm++) {
1188 addps(lb, rd, *ro, *rp, *rz, (zspan->rectmask)? *rm: 0, mask);
1193 if (sdata->rl->layflag & SCE_LAY_EDGE)
1194 if (R.r.mode & R_EDGE)
1195 edge_enhance_tile(pa, sdata->edgerect, zspan->rectz);
1198 /* main call for shading Delta Accum, for OSA */
1199 /* supposed to be fully threadable! */
1200 void zbufshadeDA_tile(RenderPart *pa)
1202 RenderResult *rr= pa->result;
1204 ListBase psmlist= {NULL, NULL};
1205 float *edgerect= NULL;
1207 /* allocate the necessary buffers */
1208 /* zbuffer inits these rects */
1209 pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1210 pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1211 pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1212 for (rl= rr->layers.first; rl; rl= rl->next) {
1213 if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
1214 pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
1216 /* initialize pixelstructs and edge buffer */
1217 addpsmain(&psmlist);
1218 pa->rectdaps= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "zbufDArectd");
1220 if (rl->layflag & SCE_LAY_EDGE)
1221 if (R.r.mode & R_EDGE)
1222 edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
1224 /* always fill visibility */
1225 for (pa->sample=0; pa->sample<R.osa; pa->sample+=4) {
1226 ZbufSolidData sdata;
1229 sdata.psmlist= &psmlist;
1230 sdata.edgerect= edgerect;
1231 zbuffer_solid(pa, rl, make_pixelstructs, &sdata);
1232 if (R.test_break(R.tbh)) break;
1236 if (rl->layflag & SCE_LAY_SOLID)
1237 shadeDA_tile(pa, rl);
1239 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
1240 if (R.flag & R_LAMPHALO)
1241 if (rl->layflag & SCE_LAY_HALO)
1242 lamphalo_tile(pa, rl);
1244 /* halo before ztra, because ztra fills in zbuffer now */
1245 if (R.flag & R_HALO)
1246 if (rl->layflag & SCE_LAY_HALO)
1250 if (R.flag & R_ZTRA || R.totstrand) {
1251 if (rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
1252 if (pa->fullresult.first) {
1253 zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
1256 unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */
1258 /* allocate, but not free here, for asynchronous display of this rect in main thread */
1259 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
1261 /* swap for live updates, and it is used in zbuf.c!!! */
1262 SWAP(float *, rl->acolrect, rl->rectf);
1263 ztramask= zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist);
1264 SWAP(float *, rl->acolrect, rl->rectf);
1266 /* zbuffer transp only returns ztramask if there's solid rendered */
1268 solidmask= make_solid_mask(pa);
1270 if (ztramask && solidmask) {
1271 unsigned short *sps= solidmask, *spz= ztramask;
1272 unsigned short fullmask= (1<<R.osa)-1;
1273 float *fcol= rl->rectf; float *acol= rl->acolrect;
1276 for (x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) {
1277 if (*sps == fullmask)
1278 addAlphaOverFloat(fcol, acol);
1280 addAlphaOverFloatMask(fcol, acol, *sps, *spz);
1284 float *fcol= rl->rectf; float *acol= rl->acolrect;
1286 for (x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
1287 addAlphaOverFloat(fcol, acol);
1290 if (solidmask) MEM_freeN(solidmask);
1291 if (ztramask) MEM_freeN(ztramask);
1297 if (rl->layflag & SCE_LAY_SKY)
1300 /* sky before edge */
1301 if (rl->layflag & SCE_LAY_SKY)
1305 if (rl->layflag & SCE_LAY_EDGE)
1306 if (R.r.mode & R_EDGE)
1307 edge_enhance_add(pa, rl->rectf, edgerect);
1309 if (rl->passflag & SCE_PASS_VECTOR)
1310 reset_sky_speed(pa, rl);
1312 /* clamp alpha to 0..1 range, can go outside due to filter */
1313 clamp_alpha_rgb_range(pa, rl);
1315 /* de-premul alpha */
1316 if (R.r.alphamode & R_ALPHAKEY)
1317 convert_to_key_alpha(pa, rl);
1319 /* free stuff within loop! */
1320 MEM_freeN(pa->rectdaps); pa->rectdaps= NULL;
1323 if (edgerect) MEM_freeN(edgerect);
1327 MEM_freeN(pa->rectmask);
1333 MEM_freeN(pa->recto); pa->recto= NULL;
1334 MEM_freeN(pa->rectp); pa->rectp= NULL;
1335 MEM_freeN(pa->rectz); pa->rectz= NULL;
1337 /* display active layer */
1338 rr->renrect.ymin=rr->renrect.ymax = 0;
1339 rr->renlay= render_get_active_layer(&R, rr);
1343 /* ------------------------------------------------------------------------ */
1345 /* non OSA case, full tile render */
1346 /* supposed to be fully threadable! */
1347 void zbufshade_tile(RenderPart *pa)
1350 RenderResult *rr= pa->result;
1353 float *edgerect= NULL;
1355 /* fake pixel struct, to comply to osa render */
1359 /* zbuffer code clears/inits rects */
1360 pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1361 pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1362 pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1364 for (rl= rr->layers.first; rl; rl= rl->next) {
1365 if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
1366 pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
1368 /* general shader info, passes */
1369 shade_sample_initialize(&ssamp, pa, rl);
1371 zbuffer_solid(pa, rl, NULL, NULL);
1373 if (!R.test_break(R.tbh)) { /* NOTE: this if () is not consistent */
1375 /* edges only for solid part, ztransp doesn't support it yet anti-aliased */
1376 if (rl->layflag & SCE_LAY_EDGE) {
1377 if (R.r.mode & R_EDGE) {
1378 edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge");
1379 edge_enhance_tile(pa, edgerect, pa->rectz);
1383 /* initialize scanline updates for main thread */
1384 rr->renrect.ymin = 0;
1387 if (rl->layflag & SCE_LAY_SOLID) {
1388 float *fcol= rl->rectf;
1389 int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz;
1390 int x, y, offs=0, seed;
1392 /* we set per pixel a fixed seed, for random AO and shadow samples */
1393 seed= pa->rectx*pa->disprect.ymin;
1395 /* irregular shadowb buffer creation */
1396 if (R.r.mode & R_SHADOW)
1397 ISB_create(pa, NULL);
1399 if (R.occlusiontree)
1400 cache_occ_samples(&R, pa, &ssamp);
1402 for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1403 for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) {
1404 /* per pixel fixed seed */
1405 BLI_thread_srandom(pa->thread, seed++);
1411 if (shade_samples(&ssamp, &ps, x, y)) {
1412 /* combined and passes */
1413 add_passes(rl, offs, ssamp.shi, ssamp.shr);
1418 if (R.test_break(R.tbh)) break;
1421 if (R.occlusiontree)
1422 free_occ_samples(&R, pa);
1424 if (R.r.mode & R_SHADOW)
1428 /* disable scanline updating */
1432 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */
1433 if (R.flag & R_LAMPHALO)
1434 if (rl->layflag & SCE_LAY_HALO)
1435 lamphalo_tile(pa, rl);
1437 /* halo before ztra, because ztra fills in zbuffer now */
1438 if (R.flag & R_HALO)
1439 if (rl->layflag & SCE_LAY_HALO)
1442 if (R.flag & R_ZTRA || R.totstrand) {
1443 if (rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) {
1447 /* allocate, but not free here, for asynchronous display of this rect in main thread */
1448 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer");
1450 /* swap for live updates */
1451 SWAP(float *, rl->acolrect, rl->rectf);
1452 zbuffer_transp_shade(pa, rl, rl->rectf, NULL);
1453 SWAP(float *, rl->acolrect, rl->rectf);
1455 fcol= rl->rectf; acol= rl->acolrect;
1456 for (x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) {
1457 addAlphaOverFloat(fcol, acol);
1463 if (rl->layflag & SCE_LAY_SKY)
1466 /* sky before edge */
1467 if (rl->layflag & SCE_LAY_SKY)
1470 if (!R.test_break(R.tbh)) {
1471 if (rl->layflag & SCE_LAY_EDGE)
1472 if (R.r.mode & R_EDGE)
1473 edge_enhance_add(pa, rl->rectf, edgerect);
1476 if (rl->passflag & SCE_PASS_VECTOR)
1477 reset_sky_speed(pa, rl);
1479 /* de-premul alpha */
1480 if (R.r.alphamode & R_ALPHAKEY)
1481 convert_to_key_alpha(pa, rl);
1483 if (edgerect) MEM_freeN(edgerect);
1487 MEM_freeN(pa->rectmask);
1492 /* display active layer */
1493 rr->renrect.ymin=rr->renrect.ymax = 0;
1494 rr->renlay= render_get_active_layer(&R, rr);
1496 MEM_freeN(pa->recto); pa->recto= NULL;
1497 MEM_freeN(pa->rectp); pa->rectp= NULL;
1498 MEM_freeN(pa->rectz); pa->rectz= NULL;
1501 /* SSS preprocess tile render, fully threadable */
1502 typedef struct ZBufSSSHandle {
1508 static void addps_sss(void *cb_handle, int obi, int facenr, int x, int y, int z)
1510 ZBufSSSHandle *handle = cb_handle;
1511 RenderPart *pa= handle->pa;
1513 /* extra border for filter gives double samples on part edges,
1514 * don't use those */
1515 if (x<pa->crop || x>=pa->rectx-pa->crop)
1517 if (y<pa->crop || y>=pa->recty-pa->crop)
1521 intptr_t *rs= pa->rectall + pa->rectx*y + x;
1523 addps(&handle->psmlist, rs, obi, facenr, z, 0, 0);
1527 int *rz= pa->rectz + pa->rectx*y + x;
1528 int *rp= pa->rectp + pa->rectx*y + x;
1529 int *ro= pa->recto + pa->rectx*y + x;
1539 if (pa->rectbackz) {
1540 int *rz= pa->rectbackz + pa->rectx*y + x;
1541 int *rp= pa->rectbackp + pa->rectx*y + x;
1542 int *ro= pa->rectbacko + pa->rectx*y + x;
1554 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[3], float *area)
1556 ShadeInput *shi= ssamp->shi;
1558 float /* texfac,*/ /* UNUSED */ orthoarea, nor[3], alpha, sx, sy;
1560 /* cache for shadow */
1561 shi->samplenr= R.shadowsamplenr[shi->thread]++;
1564 shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
1566 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
1572 /* we estimate the area here using shi->dxco and shi->dyco. we need to
1573 * enabled shi->osatex these are filled. we compute two areas, one with
1574 * the normal pointed at the camera and one with the original normal, and
1575 * then clamp to avoid a too large contribution from a single pixel */
1578 copy_v3_v3(nor, shi->facenor);
1579 calc_view_vector(shi->facenor, sx, sy);
1580 normalize_v3(shi->facenor);
1581 shade_input_set_viewco(shi, x, y, sx, sy, z);
1582 orthoarea= len_v3(shi->dxco)*len_v3(shi->dyco);
1584 copy_v3_v3(shi->facenor, nor);
1585 shade_input_set_viewco(shi, x, y, sx, sy, z);
1586 *area = min_ff(len_v3(shi->dxco) * len_v3(shi->dyco), 2.0f * orthoarea);
1588 shade_input_set_uv(shi);
1589 shade_input_set_normals(shi);
1591 /* we don't want flipped normals, they screw up back scattering */
1592 if (shi->flippednor)
1593 shade_input_flip_normals(shi);
1595 /* not a pretty solution, but fixes common cases */
1596 if (shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) {
1598 negate_v3(shi->vno);
1599 negate_v3(shi->nmapnorm);
1602 /* if nodetree, use the material that we are currently preprocessing
1603 * instead of the node material */
1604 if (shi->mat->nodetree && shi->mat->use_nodes)
1607 /* init material vars */
1608 shade_input_init_material(shi);
1611 shade_input_set_shade_texco(shi);
1613 shade_samples_do_AO(ssamp);
1614 shade_material_loop(shi, &shr);
1616 copy_v3_v3(co, shi->co);
1617 copy_v3_v3(color, shr.combined);
1619 /* texture blending */
1620 /* texfac= shi->mat->sss_texfac; */ /* UNUSED */
1622 alpha= shr.combined[3];
1626 static void zbufshade_sss_free(RenderPart *pa)
1629 MEM_freeN(pa->rectall); pa->rectall= NULL;
1630 freeps(&handle.psmlist);
1632 MEM_freeN(pa->rectz); pa->rectz= NULL;
1633 MEM_freeN(pa->rectp); pa->rectp= NULL;
1634 MEM_freeN(pa->recto); pa->recto= NULL;
1635 MEM_freeN(pa->rectbackz); pa->rectbackz= NULL;
1636 MEM_freeN(pa->rectbackp); pa->rectbackp= NULL;
1637 MEM_freeN(pa->rectbacko); pa->rectbacko= NULL;
1641 void zbufshade_sss_tile(RenderPart *pa)
1645 ZBufSSSHandle handle;
1646 RenderResult *rr= pa->result;
1649 Material *mat= re->sss_mat;
1650 float (*co)[3], (*color)[3], *area, *fcol;
1651 int x, y, seed, quad, totpoint, display = !(re->r.scemode & R_PREVIEWBUTS);
1652 int *ro, *rz, *rp, *rbo, *rbz, *rbp, lay;
1659 /* setup pixelstr list and buffer for zbuffering */
1664 handle.psmlist.first= handle.psmlist.last= NULL;
1665 addpsmain(&handle.psmlist);
1667 pa->rectall= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "rectall");
1669 pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto");
1670 pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
1671 pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
1672 pa->rectbacko= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbacko");
1673 pa->rectbackp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackp");
1674 pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz");
1677 /* setup shade sample with correct passes */
1678 memset(&ssamp, 0, sizeof(ssamp));
1679 shade_sample_initialize(&ssamp, pa, rr->layers.first);
1682 for (rl=rr->layers.first; rl; rl=rl->next) {
1683 ssamp.shi[0].lay |= rl->lay;
1684 ssamp.shi[0].layflag |= rl->layflag;
1685 ssamp.shi[0].passflag |= rl->passflag;
1686 ssamp.shi[0].combinedflag |= ~rl->pass_xor;
1689 rl= rr->layers.first;
1690 ssamp.shi[0].passflag |= SCE_PASS_RGBA|SCE_PASS_COMBINED;
1691 ssamp.shi[0].combinedflag &= ~(SCE_PASS_SPEC);
1692 ssamp.shi[0].mat_override= NULL;
1693 ssamp.shi[0].light_override= NULL;
1694 lay= ssamp.shi[0].lay;
1696 /* create the pixelstrs to be used later */
1697 zbuffer_sss(pa, lay, &handle, addps_sss);
1699 if (handle.totps==0) {
1700 zbufshade_sss_free(pa);
1706 co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo");
1707 color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor");
1708 area= MEM_mallocN(sizeof(float)*handle.totps, "SSSArea");
1711 /* create ISB (does not work currently!) */
1712 if (re->r.mode & R_SHADOW)
1713 ISB_create(pa, NULL);
1717 /* initialize scanline updates for main thread */
1718 rr->renrect.ymin = 0;
1722 seed= pa->rectx*pa->disprect.ymin;
1735 for (y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) {
1736 for (x=pa->disprect.xmin; x<pa->disprect.xmax; x++, fcol+=4) {
1737 /* per pixel fixed seed */
1738 BLI_thread_srandom(pa->thread, seed++);
1742 /* for each sample in this pixel, shade it */
1743 for (ps=(PixStr*)*rs; ps; ps=ps->next) {
1744 ObjectInstanceRen *obi= &re->objectinstance[ps->obi];
1745 ObjectRen *obr= obi->obr;
1746 vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK);
1747 quad= (ps->facenr & RE_QUAD_OFFS);
1750 shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, z,
1751 co[totpoint], color[totpoint], &area[totpoint]);
1755 add_v3_v3(fcol, color);
1764 ObjectInstanceRen *obi= &re->objectinstance[*ro];
1765 ObjectRen *obr= obi->obr;
1768 vlr= RE_findOrAddVlak(obr, (*rp-1) & RE_QUAD_MASK);
1769 quad= ((*rp) & RE_QUAD_OFFS);
1771 shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rz,
1772 co[totpoint], color[totpoint], &area[totpoint]);
1774 add_v3_v3(fcol, color[totpoint]);
1783 if (*rbp != 0 && !(*rbp == *(rp-1) && *rbo == *(ro-1))) {
1784 ObjectInstanceRen *obi= &re->objectinstance[*rbo];
1785 ObjectRen *obr= obi->obr;
1788 vlr= RE_findOrAddVlak(obr, (*rbp-1) & RE_QUAD_MASK);
1789 quad= ((*rbp) & RE_QUAD_OFFS);
1791 shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rbz,
1792 co[totpoint], color[totpoint], &area[totpoint]);
1794 /* to indicate this is a back sample */
1795 area[totpoint]= -area[totpoint];
1797 add_v3_v3(fcol, color[totpoint]);
1802 rbz++; rbp++; rbo++;
1808 if (re->test_break(re->tbh)) break;
1811 /* note: after adding we do not free these arrays, sss keeps them */
1813 sss_add_points(re, co, color, area, totpoint);
1822 if (re->r.mode & R_SHADOW)
1827 /* display active layer */
1828 rr->renrect.ymin=rr->renrect.ymax = 0;
1829 rr->renlay= render_get_active_layer(&R, rr);
1832 zbufshade_sss_free(pa);
1835 /* ------------------------------------------------------------------------ */
1837 static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har) /* postprocess version */
1839 float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf;
1840 float haloxs, haloys;
1841 int minx, maxx, miny, maxy, x, y;
1843 /* calculate the disprect mapped coordinate for halo. note: rectx is disprect corrected */
1844 haloxs= har->xs - R.disprect.xmin;
1845 haloys= har->ys - R.disprect.ymin;
1847 har->miny= miny= haloys - har->rad/R.ycor;
1848 har->maxy= maxy= haloys + har->rad/R.ycor;
1853 else if (rr->recty < miny) {
1857 minx = floor(haloxs - har->rad);
1858 maxx = ceil(haloxs + har->rad);
1863 else if (rr->rectx < minx) {
1867 if (minx<0) minx= 0;
1868 if (maxx>=rr->rectx) maxx= rr->rectx-1;
1869 if (miny<0) miny= 0;
1870 if (maxy>rr->recty) maxy= rr->recty;
1872 rectft= rectf+ 4*rr->rectx*miny;
1874 for (y=miny; y<maxy; y++) {
1878 yn= (y - haloys)*R.ycor;
1881 for (x=minx; x<=maxx; x++) {
1885 if (dist<har->radsq) {
1887 if (shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec))
1888 addalphaAddfacFloat(rtf, colf, har->add);
1893 rectft+= 4*rr->rectx;
1895 if (R.test_break(R.tbh)) break;
1900 /* ------------------------------------------------------------------------ */
1902 static void renderflare(RenderResult *rr, float *rectf, HaloRen *har)
1904 extern float hashvectf[];
1907 float *rc, rad, alfa, visifac, vec[3];
1911 fla.linec= fla.ringc= fla.flarec= 0;
1916 visifac= R.ycor*(har->pixels);
1917 /* all radials added / r^3 == 1.0f! */
1918 visifac /= (har->rad*har->rad*har->rad);
1923 /* first halo: just do */
1925 har->rad= rad*ma->flaresize*visifac;
1926 har->radsq= har->rad*har->rad;
1929 har->alfa= alfa*visifac;
1931 renderhalo_post(rr, rectf, har);
1933 /* next halo's: the flares */
1934 rc= hashvectf + ma->seed2;
1936 for (b=1; b<har->flarec; b++) {
1941 fla.alfa= ma->flareboost*fabsf(alfa*visifac*rc[3]);
1942 fla.hard= 20.0f + fabsf(70.0f*rc[7]);
1945 type= (int)(fabs(3.9f*rc[6]));
1947 fla.rad= ma->subsize*sqrtf(fabs(2.0f*har->rad*rc[4]));
1951 fla.rad+= R.rectx/10;
1954 fla.radsq= fla.rad*fla.rad;
1956 vec[0]= 1.4f*rc[5]*(har->xs-R.winx/2);
1957 vec[1]= 1.4f*rc[5]*(har->ys-R.winy/2);
1958 vec[2]= 32.0f*sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + 1.0f);
1960 fla.xs= R.winx/2 + vec[0] + (1.2f+rc[8])*R.rectx*vec[0]/vec[2];
1961 fla.ys= R.winy/2 + vec[1] + (1.2f+rc[8])*R.rectx*vec[1]/vec[2];
1963 if (R.flag & R_SEC_FIELD) {
1964 if (R.r.mode & R_ODDFIELD) fla.ys += 0.5f;
1965 else fla.ys -= 0.5f;
1967 if (type & 1) fla.type= HA_FLARECIRC;
1969 renderhalo_post(rr, rectf, &fla);
1972 if (type & 2) fla.type= HA_FLARECIRC;
1974 renderhalo_post(rr, rectf, &fla);
1980 /* needs recode... integrate this better! */
1981 void add_halo_flare(Render *re)
1983 RenderResult *rr= re->result;
1986 int a, mode, do_draw = FALSE;
1988 /* for now, we get the first renderlayer in list with halos set */
1989 for (rl= rr->layers.first; rl; rl= rl->next)
1990 if (rl->layflag & SCE_LAY_HALO)
1993 if (rl==NULL || rl->rectf==NULL)
1997 R.r.mode &= ~R_PANORAMA;
1999 project_renderdata(&R, projectverto, 0, 0, 0);
2001 for (a=0; a<R.tothalo; a++) {
2002 har= R.sortedhalos[a];
2006 renderflare(rr, rl->rectf, har);
2011 /* weak... the display callback wants an active renderlayer pointer... */
2013 re->display_draw(re->ddh, rr, NULL);
2019 /* ************************* bake ************************ */
2022 typedef struct BakeShade {
2024 ObjectInstanceRen *obi;
2031 int rectx, recty, quad, type, vdone, ready;
2040 char *rect_mask; /* bake pixel mask */
2042 float dxco[3], dyco[3];
2046 struct ColorSpace *rect_colorspace;
2049 static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int UNUSED(isect), int x, int y, float u, float v)
2052 shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3);
2054 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2);
2056 /* cache for shadow */
2057 shi->samplenr= R.shadowsamplenr[shi->thread]++;
2059 shi->mask= 0xFFFF; /* all samples */
2066 shade_input_set_uv(shi);
2067 shade_input_set_normals(shi);
2069 /* no normal flip */
2070 if (shi->flippednor)
2071 shade_input_flip_normals(shi);
2073 /* set up view vector to look right at the surface (note that the normal
2074 * is negated in the renderer so it does not need to be done here) */
2075 shi->view[0]= shi->vn[0];
2076 shi->view[1]= shi->vn[1];
2077 shi->view[2]= shi->vn[2];
2080 static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(quad), int x, int y, float UNUSED(u), float UNUSED(v), float *tvn, float *ttang)
2082 BakeShade *bs= handle;
2083 ShadeSample *ssamp= &bs->ssamp;
2085 VlakRen *vlr= shi->vlr;
2087 shade_input_init_material(shi);
2089 if (bs->type==RE_BAKE_AO) {
2090 ambient_occlusion(shi);
2092 if (R.r.bake_flag & R_BAKE_NORMALIZE) {
2093 copy_v3_v3(shr.combined, shi->ao);
2096 zero_v3(shr.combined);
2097 environment_lighting_apply(shi, &shr);
2101 if (bs->type==RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */
2102 shi->r = shi->g = shi->b = 1.0f;
2104 shade_input_set_shade_texco(shi);
2106 /* only do AO for a full bake (and obviously AO bakes)
2107 * AO for light bakes is a leftover and might not be needed */
2108 if ( ELEM3(bs->type, RE_BAKE_ALL, RE_BAKE_AO, RE_BAKE_LIGHT))
2109 shade_samples_do_AO(ssamp);
2111 if (shi->mat->nodetree && shi->mat->use_nodes) {
2112 ntreeShaderExecTree(shi->mat->nodetree, shi, &shr);
2113 shi->mat= vlr->mat; /* shi->mat is being set in nodetree */
2116 shade_material_loop(shi, &shr);
2118 if (bs->type==RE_BAKE_NORMALS) {
2121 copy_v3_v3(nor, shi->vn);
2123 if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA) {
2126 else if (R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) {
2127 float mat[3][3], imat[3][3];
2131 copy_v3_v3(mat[0], ttang);
2132 cross_v3_v3v3(mat[1], tvn, ttang);
2133 mul_v3_fl(mat[1], ttang[3]);
2134 copy_v3_v3(mat[2], tvn);
2137 copy_v3_v3(mat[0], shi->nmaptang);
2138 cross_v3_v3v3(mat[1], shi->nmapnorm, shi->nmaptang);
2139 mul_v3_fl(mat[1], shi->nmaptang[3]);
2140 copy_v3_v3(mat[2], shi->nmapnorm);
2143 invert_m3_m3(imat, mat);
2144 mul_m3_v3(imat, nor);
2146 else if (R.r.bake_normal_space == R_BAKE_SPACE_OBJECT)
2147 mul_mat3_m4_v3(ob->imat_ren, nor); /* ob->imat_ren includes viewinv! */
2148 else if (R.r.bake_normal_space == R_BAKE_SPACE_WORLD)
2149 mul_mat3_m4_v3(R.viewinv, nor);
2151 normalize_v3(nor); /* in case object has scaling */
2153 /* The invert of the red channel is to make
2154 * the normal map compliant with the outside world.
2155 * It needs to be done because in Blender
2156 * the normal used in the renderer points inward. It is generated
2157 * this way in calc_vertexnormals(). Should this ever change
2158 * this negate must be removed. */
2159 shr.combined[0]= (-nor[0])/2.0f + 0.5f;
2160 shr.combined[1]= nor[1]/2.0f + 0.5f;
2161 shr.combined[2]= nor[2]/2.0f + 0.5f;
2163 else if (bs->type==RE_BAKE_TEXTURE) {
2164 shr.combined[0]= shi->r;
2165 shr.combined[1]= shi->g;
2166 shr.combined[2]= shi->b;
2167 shr.alpha = shi->alpha;
2169 else if (bs->type==RE_BAKE_SHADOW) {
2170 copy_v3_v3(shr.combined, shr.shad);
2171 shr.alpha = shi->alpha;
2173 else if (bs->type==RE_BAKE_SPEC_COLOR) {
2174 shr.combined[0]= shi->specr;
2175 shr.combined[1]= shi->specg;
2176 shr.combined[2]= shi->specb;
2179 else if (bs->type==RE_BAKE_SPEC_INTENSITY) {
2182 shr.combined[2]= shi->spec;
2185 else if (bs->type==RE_BAKE_MIRROR_COLOR) {
2186 shr.combined[0]= shi->mirr;
2187 shr.combined[1]= shi->mirg;
2188 shr.combined[2]= shi->mirb;
2191 else if (bs->type==RE_BAKE_MIRROR_INTENSITY) {
2194 shr.combined[2]= shi->ray_mirror;
2197 else if (bs->type==RE_BAKE_ALPHA) {
2200 shr.combined[2]= shi->alpha;
2203 else if (bs->type==RE_BAKE_EMIT) {
2206 shr.combined[2]= shi->emit;
2211 if (bs->rect_float) {
2212 float *col= bs->rect_float + 4*(bs->rectx*y + x);
2213 copy_v3_v3(col, shr.combined);
2214 if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) {
2222 unsigned char *col= (unsigned char *)(bs->rect + bs->rectx*y + x);
2224 if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
2227 copy_v3_v3(rgb, shr.combined);
2228 if (R.scene_color_manage)
2229 IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace);
2230 rgb_float_to_uchar(col, rgb);
2233 rgb_float_to_uchar(col, shr.combined);
2236 if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
2237 col[3]= FTOCHAR(shr.alpha);
2244 if (bs->rect_mask) {
2245 bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED;
2249 static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist, int x, int y)
2251 BakeShade *bs= handle;
2254 if (R.r.bake_flag & R_BAKE_NORMALIZE && R.r.bake_maxdist) {
2255 disp = (dist+R.r.bake_maxdist) / (R.r.bake_maxdist*2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/
2258 disp = 0.5f + dist; /* alter the range from [-0.5,0.5] to [0,1]*/
2261 if (bs->rect_float) {
2262 float *col= bs->rect_float + 4*(bs->rectx*y + x);
2263 col[0] = col[1] = col[2] = disp;
2267 char *col= (char *)(bs->rect + bs->rectx*y + x);
2268 col[0] = col[1] = col[2] = FTOCHAR(disp);
2271 if (bs->rect_mask) {
2272 bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED;
2276 static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist)
2281 /* might be useful to make a user setting for maxsize*/
2282 if (R.r.bake_maxdist > 0.0f)
2283 maxdist= R.r.bake_maxdist;
2285 maxdist= RE_RAYTRACE_MAXDIST + R.r.bake_biasdist;
2287 /* 'dir' is always normalized */
2288 madd_v3_v3v3fl(isect->start, start, dir, -R.r.bake_biasdist);
2290 mul_v3_v3fl(isect->dir, dir, sign);
2292 isect->dist = maxdist;
2294 hit = RE_rayobject_raycast(raytree, isect);
2296 madd_v3_v3v3fl(hitco, isect->start, isect->dir, isect->dist);
2304 static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3)
2306 VlakRen *vlr= bs->vlr;
2307 float A, d1, d2, d3, *v1, *v2, *v3;
2320 /* formula derived from barycentric coordinates:
2321 * (uvArea1*v1 + uvArea2*v2 + uvArea3*v3)/uvArea
2322 * then taking u and v partial derivatives to get dxco and dyco */
2323 A= (uv2[0] - uv1[0])*(uv3[1] - uv1[1]) - (uv3[0] - uv1[0])*(uv2[1] - uv1[1]);
2325 if (fabsf(A) > FLT_EPSILON) {
2328 d1= uv2[1] - uv3[1];
2329 d2= uv3[1] - uv1[1];
2330 d3= uv1[1] - uv2[1];
2331 bs->dxco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
2332 bs->dxco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
2333 bs->dxco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
2335 d1= uv3[0] - uv2[0];
2336 d2= uv1[0] - uv3[0];
2337 d3= uv2[0] - uv1[0];
2338 bs->dyco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A;
2339 bs->dyco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A;
2340 bs->dyco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A;
2343 bs->dxco[0]= bs->dxco[1]= bs->dxco[2]= 0.0f;
2344 bs->dyco[0]= bs->dyco[1]= bs->dyco[2]= 0.0f;
2347 if (bs->obi->flag & R_TRANSFORMED) {
2348 mul_m3_v3(bs->obi->nmat, bs->dxco);
2349 mul_m3_v3(bs->obi->nmat, bs->dyco);
2353 static void do_bake_shade(void *handle, int x, int y, float u, float v)
2355 BakeShade *bs= handle;
2356 VlakRen *vlr= bs->vlr;
2357 ObjectInstanceRen *obi= bs->obi;
2358 Object *ob= obi->obr->ob;
2359 float l, *v1, *v2, *v3, tvn[3], ttang[4];
2361 ShadeSample *ssamp= &bs->ssamp;
2362 ShadeInput *shi= ssamp->shi;
2364 /* fast threadsafe break test */
2365 if (R.test_break(R.tbh))
2368 /* setup render coordinates */
2382 /* shrink barycentric coordinates inwards slightly to avoid some issues
2383 * where baking selected to active might just miss the other face at the
2384 * near the edge of a face */
2386 const float eps = 1.0f - 1e-4f;
2389 u = (u - 0.5f)*eps + 0.5f;
2390 v = (v - 0.5f)*eps + 0.5f;
2391 l = (l - 0.5f)*eps + 0.5f;
2393 invsum = 1.0f/(u + v + l);
2401 shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0];
2402 shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1];
2403 shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2];
2405 if (obi->flag & R_TRANSFORMED)
2406 mul_m4_v3(obi->mat, shi->co);
2408 copy_v3_v3(shi->dxco, bs->dxco);
2409 copy_v3_v3(shi->dyco, bs->dyco);
2412 bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v);
2414 if (bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) {
2415 shade_input_set_shade_texco(shi);
2416 copy_v3_v3(tvn, shi->nmapnorm);
2417 copy_v4_v4(ttang, shi->nmaptang);
2420 /* if we are doing selected to active baking, find point on other face */
2422 Isect isec, minisec;
2423 float co[3], minco[3], dist, mindist=0.0f;
2424 int hit, sign, dir=1;
2426 /* intersect with ray going forward and backward*/
2428 memset(&minisec, 0, sizeof(minisec));
2429 minco[0]= minco[1]= minco[2]= 0.0f;
2431 copy_v3_v3(bs->dir, shi->vn);
2433 for (sign=-1; sign<=1; sign+=2) {
2434 memset(&isec, 0, sizeof(isec));
2435 isec.mode= RE_RAY_MIRROR;
2438 isec.orig.face = vlr;
2439 isec.userdata= bs->actob;
2440 isec.check = RE_CHECK_VLR_BAKE;
2441 isec.skip = RE_SKIP_VLR_NEIGHBOUR;
2443 if (bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) {
2444 if (!hit || len_squared_v3v3(shi->co, co) < len_squared_v3v3(shi->co, minco)) {
2447 copy_v3_v3(minco, co);
2454 if (bs->type==RE_BAKE_DISPLACEMENT) {
2456 bake_displacement(handle, shi, (dir==-1)? mindist:-mindist, x, y);
2458 bake_displacement(handle, shi, 0.0f, x, y);
2462 /* if hit, we shade from the new point, otherwise from point one starting face */
2464 obi= (ObjectInstanceRen*)minisec.hit.ob;
2465 vlr= (VlakRen*)minisec.hit.face;
2466 quad= (minisec.isect == 2);
2467 copy_v3_v3(shi->co, minco);
2471 bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v);
2475 if (bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT)
2476 bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang);
2478 bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0);
2481 static int get_next_bake_face(BakeShade *bs)
2486 static int v= 0, vdone = FALSE;
2487 static ObjectInstanceRen *obi= NULL;
2492 obi= R.instancetable.first;
2496 BLI_lock_thread(LOCK_CUSTOM1);
2498 for (; obi; obi=obi->next, v=0) {
2501 for (; v<obr->totvlak; v++) {
2502 vlr= RE_findOrAddVlak(obr, v);
2504 if ((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) {
2505 tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
2507 if (tface && tface->tpage) {
2508 Image *ima= tface->tpage;
2509 ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
2510 const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f};
2511 const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f};
2516 if (ibuf->rect==NULL && ibuf->rect_float==NULL) {
2517 BKE_image_release_ibuf(ima, ibuf, NULL);
2521 if (ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4)) {
2522 BKE_image_release_ibuf(ima, ibuf, NULL);
2526 if (ima->flag & IMA_USED_FOR_RENDER) {
2527 ima->id.flag &= ~LIB_DOIT;
2528 BKE_image_release_ibuf(ima, ibuf, NULL);
2532 /* find the image for the first time? */
2533 if (ima->id.flag & LIB_DOIT) {
2534 ima->id.flag &= ~LIB_DOIT;
2536 /* we either fill in float or char, this ensures things go fine */
2537 if (ibuf->rect_float)
2538 imb_freerectImBuf(ibuf);
2540 if (R.r.bake_flag & R_BAKE_CLEAR)
2541 IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
2543 /* might be read by UI to set active image for display */
2547 ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
2552 bs->vdone++; /* only for error message if nothing was rendered */
2555 BLI_unlock_thread(LOCK_CUSTOM1);
2557 BKE_image_release_ibuf(ima, ibuf, NULL);
2565 BLI_unlock_thread(LOCK_CUSTOM1);
2569 /* already have tested for tface and ima and zspan */
2570 static void shade_tface(BakeShade *bs)
2572 VlakRen *vlr= bs->vlr;
2573 ObjectInstanceRen *obi= bs->obi;
2574 ObjectRen *obr= obi->obr;
2575 MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0);
2576 Image *ima= tface->tpage;
2580 /* check valid zspan */
2582 BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
2585 bs->ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
2586 /* note, these calls only free/fill contents of zspan struct, not zspan itself */
2587 zbuf_free_span(bs->zspan);
2588 zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop);
2591 bs->rectx= bs->ibuf->x;
2592 bs->recty= bs->ibuf->y;
2593 bs->rect= bs->ibuf->rect;
2594 bs->rect_colorspace= bs->ibuf->rect_colorspace;
2595 bs->rect_float= bs->ibuf->rect_float;
2599 if (bs->ibuf->userdata==NULL) {
2600 BLI_lock_thread(LOCK_CUSTOM1);
2601 if (bs->ibuf->userdata==NULL) /* since the thread was locked, its possible another thread alloced the value */
2602 bs->ibuf->userdata = (void *)MEM_callocN(sizeof(char)*bs->rectx*bs->recty, "BakeMask");
2603 bs->rect_mask= (char *)bs->ibuf->userdata;
2604 BLI_unlock_thread(LOCK_CUSTOM1);
2607 bs->rect_mask= (char *)bs->ibuf->userdata;
2611 /* get pixel level vertex coordinates */
2612 for (a=0; a<4; a++) {
2613 /* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests
2614 * where a pixel gets in between 2 faces or the middle of a quad,
2615 * camera aligned quads also have this problem but they are less common.
2616 * Add a small offset to the UVs, fixes bug #18685 - Campbell */
2617 vec[a][0]= tface->uv[a][0]*(float)bs->rectx - (0.5f + 0.001f);
2618 vec[a][1]= tface->uv[a][1]*(float)bs->recty - (0.5f + 0.002f);
2621 /* UV indices have to be corrected for possible quad->tria splits */
2622 i1= 0; i2= 1; i3= 2;
2623 vlr_set_uv_indices(vlr, &i1, &i2, &i3);
2624 bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]);
2625 zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade);
2629 bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]);
2630 zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade);
2634 static void *do_bake_thread(void *bs_v)
2636 BakeShade *bs= bs_v;
2638 while (get_next_bake_face(bs)) {
2641 /* fast threadsafe break test */
2642 if (R.test_break(R.tbh))
2645 /* access is not threadsafe but since its just true/false probably ok
2646 * only used for interactive baking */
2648 *bs->do_update= TRUE;
2652 BKE_image_release_ibuf(bs->ima, bs->ibuf, NULL);
2657 void RE_bake_ibuf_filter(ImBuf *ibuf, char *mask, const int filter)
2659 /* must check before filtering */
2660 const short is_new_alpha= (ibuf->planes != R_IMF_PLANES_RGBA) && BKE_imbuf_alpha_test(ibuf);
2664 IMB_filter_extend(ibuf, mask, filter);
2667 /* if the bake results in new alpha then change the image setting */
2669 ibuf->planes= R_IMF_PLANES_RGBA;
2672 if (filter && ibuf->planes != R_IMF_PLANES_RGBA) {
2673 /* clear alpha added by filtering */
2674 IMB_rectfill_alpha(ibuf, 1.0f);
2679 /* using object selection tags, the faces with UV maps get baked */
2680 /* render should have been setup */
2681 /* returns 0 if nothing was handled */
2682 int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update, float *progress)
2687 int a, vdone = FALSE, use_mask = FALSE, result = BAKE_RESULT_OK;
2689 re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene);
2691 /* initialize render global */
2695 /* initialize static vars */
2696 get_next_bake_face(NULL);
2698 /* do we need a mask? */
2699 if (re->r.bake_filter)
2702 /* baker uses this flag to detect if image was initialized */
2703 for (ima= G.main->image.first; ima; ima= ima->id.next) {
2704 ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
2705 ima->id.flag |= LIB_DOIT;
2706 ima->flag&= ~IMA_USED_FOR_RENDER;
2708 ibuf->userdata = NULL; /* use for masking if needed */
2710 BKE_image_release_ibuf(ima, ibuf, NULL);
2713 BLI_init_threads(&threads, do_bake_thread, re->r.threads);
2715 handles= MEM_callocN(sizeof(BakeShade)*re->r.threads, "BakeShade");
2717 /* get the threads running */
2718 for (a=0; a<re->r.threads; a++) {
2719 /* set defaults in handles */
2720 handles[a].ssamp.shi[0].lay= re->lay;
2722 if (type==RE_BAKE_SHADOW) {
2723 handles[a].ssamp.shi[0].passflag= SCE_PASS_SHADOW;
2726 handles[a].ssamp.shi[0].passflag= SCE_PASS_COMBINED;
2728 handles[a].ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC);
2729 handles[a].ssamp.shi[0].thread= a;
2730 handles[a].ssamp.tot= 1;
2732 handles[a].type= type;
2733 handles[a].actob= actob;
2734 handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake");
2736 handles[a].use_mask = use_mask;
2738 handles[a].do_update = do_update; /* use to tell the view to update */
2740 BLI_insert_thread(&threads, &handles[a]);
2743 /* wait for everything to be done */
2745 while (a!=re->r.threads) {
2748 /* calculate progress */
2749 for (vdone = FALSE, a=0; a<re->r.threads; a++)
2750 vdone+= handles[a].vdone;
2752 *progress = (float)(vdone / (float)re->totvlak);
2754 for (a=0; a<re->r.threads; a++) {
2755 if (handles[a].ready==0)
2760 /* filter and refresh images */
2761 for (ima= G.main->image.first; ima; ima= ima->id.next) {
2762 if ((ima->id.flag & LIB_DOIT)==0) {
2763 ImBuf *ibuf= BKE_image_acquire_ibuf(ima, NULL, NULL);
2765 if (ima->flag & IMA_USED_FOR_RENDER)
2766 result= BAKE_RESULT_FEEDBACK_LOOP;
2771 RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter);
2773 ibuf->userflags |= IB_BITMAPDIRTY;
2774 BKE_image_release_ibuf(ima, ibuf, NULL);
2778 /* calculate return value */
2779 for (a=0; a<re->r.threads; a++) {
2780 zbuf_free_span(handles[a].zspan);
2781 MEM_freeN(handles[a].zspan);
2786 BLI_end_threads(&threads);
2789 result= BAKE_RESULT_NO_OBJECTS;
2794 struct Image *RE_bake_shade_get_image(void)