Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00019 * All rights reserved. 00020 * 00021 * Contributors: Hos, Robert Wenzlaff. 00022 * Contributors: 2004/2005/2006 Blender Foundation, full recode 00023 * 00024 * ***** END GPL LICENSE BLOCK ***** 00025 */ 00026 00032 /* system includes */ 00033 #include <stdio.h> 00034 #include <math.h> 00035 #include <float.h> 00036 #include <string.h> 00037 #include <assert.h> 00038 00039 /* External modules: */ 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "BLI_math.h" 00043 #include "BLI_blenlib.h" 00044 #include "BLI_jitter.h" 00045 #include "BLI_rand.h" 00046 #include "BLI_threads.h" 00047 #include "BLI_utildefines.h" 00048 00049 00050 00051 #include "DNA_image_types.h" 00052 #include "DNA_lamp_types.h" 00053 #include "DNA_material_types.h" 00054 #include "DNA_meshdata_types.h" 00055 #include "DNA_group_types.h" 00056 00057 #include "BKE_global.h" 00058 #include "BKE_image.h" 00059 #include "BKE_main.h" 00060 #include "BKE_node.h" 00061 #include "BKE_texture.h" 00062 00063 #include "IMB_imbuf_types.h" 00064 #include "IMB_imbuf.h" 00065 00066 /* local include */ 00067 #include "rayintersection.h" 00068 #include "rayobject.h" 00069 #include "renderpipeline.h" 00070 #include "render_result.h" 00071 #include "render_types.h" 00072 #include "renderdatabase.h" 00073 #include "occlusion.h" 00074 #include "pixelblending.h" 00075 #include "pixelshading.h" 00076 #include "shadbuf.h" 00077 #include "shading.h" 00078 #include "sss.h" 00079 #include "zbuf.h" 00080 00081 #include "PIL_time.h" 00082 00083 /* own include */ 00084 #include "rendercore.h" 00085 00086 00087 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 00088 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ 00089 /* only to be used here in this file, it's for speed */ 00090 extern struct Render R; 00091 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 00092 00093 /* x and y are current pixels in rect to be rendered */ 00094 /* do not normalize! */ 00095 void calc_view_vector(float *view, float x, float y) 00096 { 00097 00098 view[2]= -ABS(R.clipsta); 00099 00100 if(R.r.mode & R_ORTHO) { 00101 view[0]= view[1]= 0.0f; 00102 } 00103 else { 00104 00105 if(R.r.mode & R_PANORAMA) { 00106 x-= R.panodxp; 00107 } 00108 00109 /* move x and y to real viewplane coords */ 00110 x= (x/(float)R.winx); 00111 view[0]= R.viewplane.xmin + x*(R.viewplane.xmax - R.viewplane.xmin); 00112 00113 y= (y/(float)R.winy); 00114 view[1]= R.viewplane.ymin + y*(R.viewplane.ymax - R.viewplane.ymin); 00115 00116 // if(R.flag & R_SEC_FIELD) { 00117 // if(R.r.mode & R_ODDFIELD) view[1]= (y+R.ystart)*R.ycor; 00118 // else view[1]= (y+R.ystart+1.0)*R.ycor; 00119 // } 00120 // else view[1]= (y+R.ystart+R.bluroffsy+0.5)*R.ycor; 00121 00122 if(R.r.mode & R_PANORAMA) { 00123 float u= view[0] + R.panodxv; float v= view[2]; 00124 view[0]= R.panoco*u + R.panosi*v; 00125 view[2]= -R.panosi*u + R.panoco*v; 00126 } 00127 } 00128 } 00129 00130 void calc_renderco_ortho(float co[3], float x, float y, int z) 00131 { 00132 /* x and y 3d coordinate can be derived from pixel coord and winmat */ 00133 float fx= 2.0f/(R.winx*R.winmat[0][0]); 00134 float fy= 2.0f/(R.winy*R.winmat[1][1]); 00135 float zco; 00136 00137 co[0]= (x - 0.5f*R.winx)*fx - R.winmat[3][0]/R.winmat[0][0]; 00138 co[1]= (y - 0.5f*R.winy)*fy - R.winmat[3][1]/R.winmat[1][1]; 00139 00140 zco= ((float)z)/2147483647.0f; 00141 co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] ); 00142 } 00143 00144 void calc_renderco_zbuf(float co[3], const float view[3], int z) 00145 { 00146 float fac, zco; 00147 00148 /* inverse of zbuf calc: zbuf = MAXZ*hoco_z/hoco_w */ 00149 zco= ((float)z)/2147483647.0f; 00150 co[2]= R.winmat[3][2]/( R.winmat[2][3]*zco - R.winmat[2][2] ); 00151 00152 fac= co[2]/view[2]; 00153 co[0]= fac*view[0]; 00154 co[1]= fac*view[1]; 00155 } 00156 00157 /* also used in zbuf.c and shadbuf.c */ 00158 int count_mask(unsigned short mask) 00159 { 00160 if(R.samples) 00161 return (R.samples->cmask[mask & 255]+R.samples->cmask[mask>>8]); 00162 return 0; 00163 } 00164 00165 static int calchalo_z(HaloRen *har, int zz) 00166 { 00167 00168 if(har->type & HA_ONLYSKY) { 00169 if(zz < 0x7FFFFFF0) zz= - 0x7FFFFF; /* edge render messes zvalues */ 00170 } 00171 else { 00172 zz= (zz>>8); 00173 } 00174 return zz; 00175 } 00176 00177 00178 00179 static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, int od, float dist, float xn, float yn, PixStr *ps) 00180 { 00181 float col[4], accol[4], fac; 00182 int amount, amountm, zz, flarec, sample, fullsample, mask=0; 00183 00184 fullsample= (totsample > 1); 00185 amount= 0; 00186 accol[0]=accol[1]=accol[2]=accol[3]= 0.0f; 00187 flarec= har->flarec; 00188 00189 while(ps) { 00190 amountm= count_mask(ps->mask); 00191 amount+= amountm; 00192 00193 zz= calchalo_z(har, ps->z); 00194 if((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) { 00195 if(shadeHaloFloat(har, col, zz, dist, xn, yn, flarec)) { 00196 flarec= 0; 00197 00198 if(fullsample) { 00199 for(sample=0; sample<totsample; sample++) 00200 if(ps->mask & (1 << sample)) 00201 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add); 00202 } 00203 else { 00204 fac= ((float)amountm)/(float)R.osa; 00205 accol[0]+= fac*col[0]; 00206 accol[1]+= fac*col[1]; 00207 accol[2]+= fac*col[2]; 00208 accol[3]+= fac*col[3]; 00209 } 00210 } 00211 } 00212 00213 mask |= ps->mask; 00214 ps= ps->next; 00215 } 00216 00217 /* now do the sky sub-pixels */ 00218 amount= R.osa-amount; 00219 if(amount) { 00220 if(shadeHaloFloat(har, col, 0x7FFFFF, dist, xn, yn, flarec)) { 00221 if(!fullsample) { 00222 fac= ((float)amount)/(float)R.osa; 00223 accol[0]+= fac*col[0]; 00224 accol[1]+= fac*col[1]; 00225 accol[2]+= fac*col[2]; 00226 accol[3]+= fac*col[3]; 00227 } 00228 } 00229 } 00230 00231 if(fullsample) { 00232 for(sample=0; sample<totsample; sample++) 00233 if(!(mask & (1 << sample))) 00234 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add); 00235 } 00236 else { 00237 col[0]= accol[0]; 00238 col[1]= accol[1]; 00239 col[2]= accol[2]; 00240 col[3]= accol[3]; 00241 00242 for(sample=0; sample<totsample; sample++) 00243 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add); 00244 } 00245 } 00246 00247 static void halo_tile(RenderPart *pa, RenderLayer *rl) 00248 { 00249 RenderLayer *rlpp[RE_MAX_OSA]; 00250 HaloRen *har; 00251 rcti disprect= pa->disprect, testrect= pa->disprect; 00252 float dist, xsq, ysq, xn, yn; 00253 float col[4]; 00254 intptr_t *rd= NULL; 00255 int a, *rz, zz, y, sample, totsample, od; 00256 short minx, maxx, miny, maxy, x; 00257 unsigned int lay= rl->lay; 00258 00259 /* we don't render halos in the cropped area, gives errors in flare counter */ 00260 if(pa->crop) { 00261 testrect.xmin+= pa->crop; 00262 testrect.xmax-= pa->crop; 00263 testrect.ymin+= pa->crop; 00264 testrect.ymax-= pa->crop; 00265 } 00266 00267 totsample= get_sample_layers(pa, rl, rlpp); 00268 00269 for(a=0; a<R.tothalo; a++) { 00270 har= R.sortedhalos[a]; 00271 00272 /* layer test, clip halo with y */ 00273 if((har->lay & lay)==0); 00274 else if(testrect.ymin > har->maxy); 00275 else if(testrect.ymax < har->miny); 00276 else { 00277 00278 minx= floor(har->xs-har->rad); 00279 maxx= ceil(har->xs+har->rad); 00280 00281 if(testrect.xmin > maxx); 00282 else if(testrect.xmax < minx); 00283 else { 00284 00285 minx= MAX2(minx, testrect.xmin); 00286 maxx= MIN2(maxx, testrect.xmax); 00287 00288 miny= MAX2(har->miny, testrect.ymin); 00289 maxy= MIN2(har->maxy, testrect.ymax); 00290 00291 for(y=miny; y<maxy; y++) { 00292 int rectofs= (y-disprect.ymin)*pa->rectx + (minx - disprect.xmin); 00293 rz= pa->rectz + rectofs; 00294 od= rectofs; 00295 00296 if(pa->rectdaps) 00297 rd= pa->rectdaps + rectofs; 00298 00299 yn= (y-har->ys)*R.ycor; 00300 ysq= yn*yn; 00301 00302 for(x=minx; x<maxx; x++, rz++, od++) { 00303 xn= x- har->xs; 00304 xsq= xn*xn; 00305 dist= xsq+ysq; 00306 if(dist<har->radsq) { 00307 if(rd && *rd) { 00308 halo_pixelstruct(har, rlpp, totsample, od, dist, xn, yn, (PixStr *)*rd); 00309 } 00310 else { 00311 zz= calchalo_z(har, *rz); 00312 if((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) { 00313 if(shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) { 00314 for(sample=0; sample<totsample; sample++) 00315 addalphaAddfacFloat(rlpp[sample]->rectf + od*4, col, har->add); 00316 } 00317 } 00318 } 00319 } 00320 if(rd) rd++; 00321 } 00322 } 00323 } 00324 } 00325 if(R.test_break(R.tbh) ) break; 00326 } 00327 } 00328 00329 static void lamphalo_tile(RenderPart *pa, RenderLayer *rl) 00330 { 00331 RenderLayer *rlpp[RE_MAX_OSA]; 00332 ShadeInput shi; 00333 float *pass; 00334 float fac, col[4]; 00335 intptr_t *rd= pa->rectdaps; 00336 int *rz= pa->rectz; 00337 int x, y, sample, totsample, fullsample, od; 00338 00339 totsample= get_sample_layers(pa, rl, rlpp); 00340 fullsample= (totsample > 1); 00341 00342 shade_input_initialize(&shi, pa, rl, 0); /* this zero's ShadeInput for us */ 00343 00344 for(od=0, y=pa->disprect.ymin; y<pa->disprect.ymax; y++) { 00345 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, rz++, od++) { 00346 00347 calc_view_vector(shi.view, x, y); 00348 00349 if(rd && *rd) { 00350 PixStr *ps= (PixStr *)*rd; 00351 int count, totsamp= 0, mask= 0; 00352 00353 while(ps) { 00354 if(R.r.mode & R_ORTHO) 00355 calc_renderco_ortho(shi.co, (float)x, (float)y, ps->z); 00356 else 00357 calc_renderco_zbuf(shi.co, shi.view, ps->z); 00358 00359 totsamp+= count= count_mask(ps->mask); 00360 mask |= ps->mask; 00361 00362 col[0]= col[1]= col[2]= col[3]= 0.0f; 00363 renderspothalo(&shi, col, 1.0f); 00364 00365 if(fullsample) { 00366 for(sample=0; sample<totsample; sample++) { 00367 if(ps->mask & (1 << sample)) { 00368 pass= rlpp[sample]->rectf + od*4; 00369 pass[0]+= col[0]; 00370 pass[1]+= col[1]; 00371 pass[2]+= col[2]; 00372 pass[3]+= col[3]; 00373 if(pass[3]>1.0f) pass[3]= 1.0f; 00374 } 00375 } 00376 } 00377 else { 00378 fac= ((float)count)/(float)R.osa; 00379 pass= rl->rectf + od*4; 00380 pass[0]+= fac*col[0]; 00381 pass[1]+= fac*col[1]; 00382 pass[2]+= fac*col[2]; 00383 pass[3]+= fac*col[3]; 00384 if(pass[3]>1.0f) pass[3]= 1.0f; 00385 } 00386 00387 ps= ps->next; 00388 } 00389 00390 if(totsamp<R.osa) { 00391 shi.co[2]= 0.0f; 00392 00393 col[0]= col[1]= col[2]= col[3]= 0.0f; 00394 renderspothalo(&shi, col, 1.0f); 00395 00396 if(fullsample) { 00397 for(sample=0; sample<totsample; sample++) { 00398 if(!(mask & (1 << sample))) { 00399 pass= rlpp[sample]->rectf + od*4; 00400 pass[0]+= col[0]; 00401 pass[1]+= col[1]; 00402 pass[2]+= col[2]; 00403 pass[3]+= col[3]; 00404 if(pass[3]>1.0f) pass[3]= 1.0f; 00405 } 00406 } 00407 } 00408 else { 00409 fac= ((float)R.osa-totsamp)/(float)R.osa; 00410 pass= rl->rectf + od*4; 00411 pass[0]+= fac*col[0]; 00412 pass[1]+= fac*col[1]; 00413 pass[2]+= fac*col[2]; 00414 pass[3]+= fac*col[3]; 00415 if(pass[3]>1.0f) pass[3]= 1.0f; 00416 } 00417 } 00418 } 00419 else { 00420 if(R.r.mode & R_ORTHO) 00421 calc_renderco_ortho(shi.co, (float)x, (float)y, *rz); 00422 else 00423 calc_renderco_zbuf(shi.co, shi.view, *rz); 00424 00425 col[0]= col[1]= col[2]= col[3]= 0.0f; 00426 renderspothalo(&shi, col, 1.0f); 00427 00428 for(sample=0; sample<totsample; sample++) { 00429 pass= rlpp[sample]->rectf + od*4; 00430 pass[0]+= col[0]; 00431 pass[1]+= col[1]; 00432 pass[2]+= col[2]; 00433 pass[3]+= col[3]; 00434 if(pass[3]>1.0f) pass[3]= 1.0f; 00435 } 00436 } 00437 00438 if(rd) rd++; 00439 } 00440 if(y&1) 00441 if(R.test_break(R.tbh)) break; 00442 } 00443 } 00444 00445 00446 /* ********************* MAINLOOPS ******************** */ 00447 00448 /* osa version */ 00449 static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset, ShadeInput *shi, ShadeResult *shr) 00450 { 00451 RenderPass *rpass; 00452 00453 /* combined rgb */ 00454 add_filt_fmask(curmask, shr->combined, rl->rectf + 4*offset, rectx); 00455 00456 for(rpass= rl->passes.first; rpass; rpass= rpass->next) { 00457 float *fp, *col= NULL; 00458 int pixsize= 3; 00459 00460 switch(rpass->passtype) { 00461 case SCE_PASS_Z: 00462 fp= rpass->rect + offset; 00463 *fp= shr->z; 00464 break; 00465 case SCE_PASS_RGBA: 00466 col= shr->col; 00467 pixsize= 4; 00468 break; 00469 case SCE_PASS_EMIT: 00470 col= shr->emit; 00471 break; 00472 case SCE_PASS_DIFFUSE: 00473 col= shr->diff; 00474 break; 00475 case SCE_PASS_SPEC: 00476 col= shr->spec; 00477 break; 00478 case SCE_PASS_SHADOW: 00479 col= shr->shad; 00480 break; 00481 case SCE_PASS_AO: 00482 col= shr->ao; 00483 break; 00484 case SCE_PASS_ENVIRONMENT: 00485 col= shr->env; 00486 break; 00487 case SCE_PASS_INDIRECT: 00488 col= shr->indirect; 00489 break; 00490 case SCE_PASS_REFLECT: 00491 col= shr->refl; 00492 break; 00493 case SCE_PASS_REFRACT: 00494 col= shr->refr; 00495 break; 00496 case SCE_PASS_NORMAL: 00497 col= shr->nor; 00498 break; 00499 case SCE_PASS_UV: 00500 /* box filter only, gauss will screwup UV too much */ 00501 if(shi->totuv) { 00502 float mult= (float)count_mask(curmask)/(float)R.osa; 00503 fp= rpass->rect + 3*offset; 00504 fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]); 00505 fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]); 00506 fp[2]+= mult; 00507 } 00508 break; 00509 case SCE_PASS_INDEXOB: 00510 /* no filter */ 00511 if(shi->vlr) { 00512 fp= rpass->rect + offset; 00513 if(*fp==0.0f) 00514 *fp= (float)shi->obr->ob->index; 00515 } 00516 break; 00517 case SCE_PASS_INDEXMA: 00518 /* no filter */ 00519 if(shi->vlr) { 00520 fp= rpass->rect + offset; 00521 if(*fp==0.0f) 00522 *fp= (float)shi->mat->index; 00523 } 00524 break; 00525 case SCE_PASS_MIST: 00526 /* */ 00527 col= &shr->mist; 00528 pixsize= 1; 00529 break; 00530 00531 case SCE_PASS_VECTOR: 00532 { 00533 /* add minimum speed in pixel, no filter */ 00534 fp= rpass->rect + 4*offset; 00535 if( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) { 00536 fp[0]= shr->winspeed[0]; 00537 fp[1]= shr->winspeed[1]; 00538 } 00539 if( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) { 00540 fp[2]= shr->winspeed[2]; 00541 fp[3]= shr->winspeed[3]; 00542 } 00543 } 00544 break; 00545 00546 case SCE_PASS_RAYHITS: 00547 /* */ 00548 col= shr->rayhits; 00549 pixsize= 4; 00550 break; 00551 } 00552 if(col) { 00553 fp= rpass->rect + pixsize*offset; 00554 add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize); 00555 } 00556 } 00557 } 00558 00559 /* non-osa version */ 00560 static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult *shr) 00561 { 00562 RenderPass *rpass; 00563 float *fp; 00564 00565 fp= rl->rectf + 4*offset; 00566 copy_v4_v4(fp, shr->combined); 00567 00568 for(rpass= rl->passes.first; rpass; rpass= rpass->next) { 00569 float *col= NULL, uvcol[3]; 00570 int a, pixsize= 3; 00571 00572 switch(rpass->passtype) { 00573 case SCE_PASS_Z: 00574 fp= rpass->rect + offset; 00575 *fp= shr->z; 00576 break; 00577 case SCE_PASS_RGBA: 00578 col= shr->col; 00579 pixsize= 4; 00580 break; 00581 case SCE_PASS_EMIT: 00582 col= shr->emit; 00583 break; 00584 case SCE_PASS_DIFFUSE: 00585 col= shr->diff; 00586 break; 00587 case SCE_PASS_SPEC: 00588 col= shr->spec; 00589 break; 00590 case SCE_PASS_SHADOW: 00591 col= shr->shad; 00592 break; 00593 case SCE_PASS_AO: 00594 col= shr->ao; 00595 break; 00596 case SCE_PASS_ENVIRONMENT: 00597 col= shr->env; 00598 break; 00599 case SCE_PASS_INDIRECT: 00600 col= shr->indirect; 00601 break; 00602 case SCE_PASS_REFLECT: 00603 col= shr->refl; 00604 break; 00605 case SCE_PASS_REFRACT: 00606 col= shr->refr; 00607 break; 00608 case SCE_PASS_NORMAL: 00609 col= shr->nor; 00610 break; 00611 case SCE_PASS_UV: 00612 if(shi->totuv) { 00613 uvcol[0]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[0]; 00614 uvcol[1]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[1]; 00615 uvcol[2]= 1.0f; 00616 col= uvcol; 00617 } 00618 break; 00619 case SCE_PASS_VECTOR: 00620 col= shr->winspeed; 00621 pixsize= 4; 00622 break; 00623 case SCE_PASS_INDEXOB: 00624 if(shi->vlr) { 00625 fp= rpass->rect + offset; 00626 *fp= (float)shi->obr->ob->index; 00627 } 00628 break; 00629 case SCE_PASS_INDEXMA: 00630 if(shi->vlr) { 00631 fp= rpass->rect + offset; 00632 *fp= (float)shi->mat->index; 00633 } 00634 break; 00635 case SCE_PASS_MIST: 00636 fp= rpass->rect + offset; 00637 *fp= shr->mist; 00638 break; 00639 case SCE_PASS_RAYHITS: 00640 col= shr->rayhits; 00641 pixsize= 4; 00642 break; 00643 } 00644 if(col) { 00645 fp= rpass->rect + pixsize*offset; 00646 for(a=0; a<pixsize; a++) 00647 fp[a]= col[a]; 00648 } 00649 } 00650 } 00651 00652 int get_sample_layers(RenderPart *pa, RenderLayer *rl, RenderLayer **rlpp) 00653 { 00654 00655 if(pa->fullresult.first) { 00656 int sample, nr= BLI_findindex(&pa->result->layers, rl); 00657 00658 for(sample=0; sample<R.osa; sample++) { 00659 RenderResult *rr= BLI_findlink(&pa->fullresult, sample); 00660 00661 rlpp[sample]= BLI_findlink(&rr->layers, nr); 00662 } 00663 return R.osa; 00664 } 00665 else { 00666 rlpp[0]= rl; 00667 return 1; 00668 } 00669 } 00670 00671 00672 /* only do sky, is default in the solid layer (shade_tile) btw */ 00673 static void sky_tile(RenderPart *pa, RenderLayer *rl) 00674 { 00675 RenderLayer *rlpp[RE_MAX_OSA]; 00676 int x, y, od=0, totsample; 00677 00678 if(R.r.alphamode!=R_ADDSKY) 00679 return; 00680 00681 totsample= get_sample_layers(pa, rl, rlpp); 00682 00683 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) { 00684 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od+=4) { 00685 float col[4]; 00686 int sample, done= 0; 00687 00688 for(sample= 0; sample<totsample; sample++) { 00689 float *pass= rlpp[sample]->rectf + od; 00690 00691 if(pass[3]<1.0f) { 00692 00693 if(done==0) { 00694 shadeSkyPixel(col, x, y, pa->thread); 00695 done= 1; 00696 } 00697 00698 if(pass[3]==0.0f) { 00699 copy_v4_v4(pass, col); 00700 } 00701 else { 00702 addAlphaUnderFloat(pass, col); 00703 } 00704 } 00705 } 00706 } 00707 00708 if(y&1) 00709 if(R.test_break(R.tbh)) break; 00710 } 00711 } 00712 00713 static void atm_tile(RenderPart *pa, RenderLayer *rl) 00714 { 00715 RenderPass *zpass; 00716 GroupObject *go; 00717 LampRen *lar; 00718 RenderLayer *rlpp[RE_MAX_OSA]; 00719 int totsample; 00720 int x, y, od= 0; 00721 00722 totsample= get_sample_layers(pa, rl, rlpp); 00723 00724 /* check that z pass is enabled */ 00725 if(pa->rectz==NULL) return; 00726 for(zpass= rl->passes.first; zpass; zpass= zpass->next) 00727 if(zpass->passtype==SCE_PASS_Z) 00728 break; 00729 00730 if(zpass==NULL) return; 00731 00732 /* check for at least one sun lamp that its atmosphere flag is enabled */ 00733 for(go=R.lights.first; go; go= go->next) { 00734 lar= go->lampren; 00735 if(lar->type==LA_SUN && lar->sunsky && (lar->sunsky->effect_type & LA_SUN_EFFECT_AP)) 00736 break; 00737 } 00738 /* do nothign and return if there is no sun lamp */ 00739 if(go==NULL) 00740 return; 00741 00742 /* for each x,y and each sample, and each sun lamp*/ 00743 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++) { 00744 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, od++) { 00745 int sample; 00746 00747 for(sample=0; sample<totsample; sample++) { 00748 float *zrect= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_Z) + od; 00749 float *rgbrect = rlpp[sample]->rectf + 4*od; 00750 float rgb[3] = {0}; 00751 int done= 0; 00752 00753 for(go=R.lights.first; go; go= go->next) { 00754 00755 00756 lar= go->lampren; 00757 if(lar->type==LA_SUN && lar->sunsky) { 00758 00759 /* if it's sky continue and don't apply atmosphere effect on it */ 00760 if(*zrect >= 9.9e10f || rgbrect[3]==0.0f) { 00761 continue; 00762 } 00763 00764 if((lar->sunsky->effect_type & LA_SUN_EFFECT_AP)) { 00765 float tmp_rgb[3]; 00766 00767 /* skip if worldspace lamp vector is below horizon */ 00768 if(go->ob->obmat[2][2] < 0.f) { 00769 continue; 00770 } 00771 00772 copy_v3_v3(tmp_rgb, rgbrect); 00773 if(rgbrect[3]!=1.0f) { /* de-premul */ 00774 mul_v3_fl(tmp_rgb, 1.0f/rgbrect[3]); 00775 } 00776 shadeAtmPixel(lar->sunsky, tmp_rgb, x, y, *zrect); 00777 if(rgbrect[3]!=1.0f) { /* premul */ 00778 mul_v3_fl(tmp_rgb, rgbrect[3]); 00779 } 00780 00781 if(done==0) { 00782 copy_v3_v3(rgb, tmp_rgb); 00783 done = 1; 00784 } 00785 else{ 00786 rgb[0] = 0.5f*rgb[0] + 0.5f*tmp_rgb[0]; 00787 rgb[1] = 0.5f*rgb[1] + 0.5f*tmp_rgb[1]; 00788 rgb[2] = 0.5f*rgb[2] + 0.5f*tmp_rgb[2]; 00789 } 00790 } 00791 } 00792 } 00793 00794 /* if at least for one sun lamp aerial perspective was applied*/ 00795 if(done) { 00796 copy_v3_v3(rgbrect, rgb); 00797 } 00798 } 00799 } 00800 } 00801 } 00802 00803 static void shadeDA_tile(RenderPart *pa, RenderLayer *rl) 00804 { 00805 RenderResult *rr= pa->result; 00806 ShadeSample ssamp; 00807 intptr_t *rd, *rectdaps= pa->rectdaps; 00808 int samp; 00809 int x, y, seed, crop=0, offs=0, od; 00810 00811 if(R.test_break(R.tbh)) return; 00812 00813 /* irregular shadowb buffer creation */ 00814 if(R.r.mode & R_SHADOW) 00815 ISB_create(pa, NULL); 00816 00817 /* we set per pixel a fixed seed, for random AO and shadow samples */ 00818 seed= pa->rectx*pa->disprect.ymin; 00819 00820 /* general shader info, passes */ 00821 shade_sample_initialize(&ssamp, pa, rl); 00822 00823 /* occlusion caching */ 00824 if(R.occlusiontree) 00825 cache_occ_samples(&R, pa, &ssamp); 00826 00827 /* filtered render, for now we assume only 1 filter size */ 00828 if(pa->crop) { 00829 crop= 1; 00830 rectdaps+= pa->rectx + 1; 00831 offs= pa->rectx + 1; 00832 } 00833 00834 /* scanline updates have to be 2 lines behind */ 00835 rr->renrect.ymin= 0; 00836 rr->renrect.ymax= -2*crop; 00837 rr->renlay= rl; 00838 00839 for(y=pa->disprect.ymin+crop; y<pa->disprect.ymax-crop; y++, rr->renrect.ymax++) { 00840 rd= rectdaps; 00841 od= offs; 00842 00843 for(x=pa->disprect.xmin+crop; x<pa->disprect.xmax-crop; x++, rd++, od++) { 00844 BLI_thread_srandom(pa->thread, seed++); 00845 00846 if(*rd) { 00847 if(shade_samples(&ssamp, (PixStr *)(*rd), x, y)) { 00848 00849 /* multisample buffers or filtered mask filling? */ 00850 if(pa->fullresult.first) { 00851 int a; 00852 for(samp=0; samp<ssamp.tot; samp++) { 00853 int smask= ssamp.shi[samp].mask; 00854 for(a=0; a<R.osa; a++) { 00855 int mask= 1<<a; 00856 if(smask & mask) 00857 add_passes(ssamp.rlpp[a], od, &ssamp.shi[samp], &ssamp.shr[samp]); 00858 } 00859 } 00860 } 00861 else { 00862 for(samp=0; samp<ssamp.tot; samp++) 00863 add_filt_passes(rl, ssamp.shi[samp].mask, pa->rectx, od, &ssamp.shi[samp], &ssamp.shr[samp]); 00864 } 00865 } 00866 } 00867 } 00868 00869 rectdaps+= pa->rectx; 00870 offs+= pa->rectx; 00871 00872 if(y&1) if(R.test_break(R.tbh)) break; 00873 } 00874 00875 /* disable scanline updating */ 00876 rr->renlay= NULL; 00877 00878 if(R.r.mode & R_SHADOW) 00879 ISB_free(pa); 00880 00881 if(R.occlusiontree) 00882 free_occ_samples(&R, pa); 00883 } 00884 00885 /* ************* pixel struct ******** */ 00886 00887 00888 static PixStrMain *addpsmain(ListBase *lb) 00889 { 00890 PixStrMain *psm; 00891 00892 psm= (PixStrMain *)MEM_mallocN(sizeof(PixStrMain),"pixstrMain"); 00893 BLI_addtail(lb, psm); 00894 00895 psm->ps= (PixStr *)MEM_mallocN(4096*sizeof(PixStr),"pixstr"); 00896 psm->counter= 0; 00897 00898 return psm; 00899 } 00900 00901 static void freeps(ListBase *lb) 00902 { 00903 PixStrMain *psm, *psmnext; 00904 00905 for(psm= lb->first; psm; psm= psmnext) { 00906 psmnext= psm->next; 00907 if(psm->ps) 00908 MEM_freeN(psm->ps); 00909 MEM_freeN(psm); 00910 } 00911 lb->first= lb->last= NULL; 00912 } 00913 00914 static void addps(ListBase *lb, intptr_t *rd, int obi, int facenr, int z, int maskz, unsigned short mask) 00915 { 00916 PixStrMain *psm; 00917 PixStr *ps, *last= NULL; 00918 00919 if(*rd) { 00920 ps= (PixStr *)(*rd); 00921 00922 while(ps) { 00923 if( ps->obi == obi && ps->facenr == facenr ) { 00924 ps->mask |= mask; 00925 return; 00926 } 00927 last= ps; 00928 ps= ps->next; 00929 } 00930 } 00931 00932 /* make new PS (pixel struct) */ 00933 psm= lb->last; 00934 00935 if(psm->counter==4095) 00936 psm= addpsmain(lb); 00937 00938 ps= psm->ps + psm->counter++; 00939 00940 if(last) last->next= ps; 00941 else *rd= (intptr_t)ps; 00942 00943 ps->next= NULL; 00944 ps->obi= obi; 00945 ps->facenr= facenr; 00946 ps->z= z; 00947 ps->maskz= maskz; 00948 ps->mask = mask; 00949 ps->shadfac= 0; 00950 } 00951 00952 static void edge_enhance_add(RenderPart *pa, float *rectf, float *arect) 00953 { 00954 float addcol[4]; 00955 int pix; 00956 00957 if(arect==NULL) 00958 return; 00959 00960 for(pix= pa->rectx*pa->recty; pix>0; pix--, arect++, rectf+=4) { 00961 if(*arect != 0.0f) { 00962 addcol[0]= *arect * R.r.edgeR; 00963 addcol[1]= *arect * R.r.edgeG; 00964 addcol[2]= *arect * R.r.edgeB; 00965 addcol[3]= *arect; 00966 addAlphaOverFloat(rectf, addcol); 00967 } 00968 } 00969 } 00970 00971 static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl) 00972 { 00973 RenderLayer *rlpp[RE_MAX_OSA]; 00974 int y, sample, totsample; 00975 00976 totsample= get_sample_layers(pa, rl, rlpp); 00977 00978 for(sample= 0; sample<totsample; sample++) { 00979 float *rectf= rlpp[sample]->rectf; 00980 00981 for(y= pa->rectx*pa->recty; y>0; y--, rectf+=4) { 00982 if(rectf[3] >= 1.0f); 00983 else if(rectf[3] > 0.0f) { 00984 rectf[0] /= rectf[3]; 00985 rectf[1] /= rectf[3]; 00986 rectf[2] /= rectf[3]; 00987 } 00988 } 00989 } 00990 } 00991 00992 /* adds only alpha values */ 00993 static void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz) 00994 { 00995 /* use zbuffer to define edges, add it to the image */ 00996 int y, x, col, *rz, *rz1, *rz2, *rz3; 00997 int zval1, zval2, zval3; 00998 float *rf; 00999 01000 /* shift values in zbuffer 4 to the right (anti overflows), for filter we need multiplying with 12 max */ 01001 rz= rectz; 01002 if(rz==NULL) return; 01003 01004 for(y=0; y<pa->recty; y++) 01005 for(x=0; x<pa->rectx; x++, rz++) (*rz)>>= 4; 01006 01007 rz1= rectz; 01008 rz2= rz1+pa->rectx; 01009 rz3= rz2+pa->rectx; 01010 01011 rf= rectf+pa->rectx+1; 01012 01013 for(y=0; y<pa->recty-2; y++) { 01014 for(x=0; x<pa->rectx-2; x++, rz1++, rz2++, rz3++, rf++) { 01015 01016 /* prevent overflow with sky z values */ 01017 zval1= rz1[0] + 2*rz1[1] + rz1[2]; 01018 zval2= 2*rz2[0] + 2*rz2[2]; 01019 zval3= rz3[0] + 2*rz3[1] + rz3[2]; 01020 01021 col= ( 4*rz2[1] - (zval1 + zval2 + zval3)/3 ); 01022 if(col<0) col= -col; 01023 01024 col >>= 5; 01025 if(col > (1<<16)) col= (1<<16); 01026 else col= (R.r.edgeint*col)>>8; 01027 01028 if(col>0) { 01029 float fcol; 01030 01031 if(col>255) fcol= 1.0f; 01032 else fcol= (float)col/255.0f; 01033 01034 if(R.osa) 01035 *rf+= fcol/(float)R.osa; 01036 else 01037 *rf= fcol; 01038 } 01039 } 01040 rz1+= 2; 01041 rz2+= 2; 01042 rz3+= 2; 01043 rf+= 2; 01044 } 01045 01046 /* shift back zbuf values, we might need it still */ 01047 rz= rectz; 01048 for(y=0; y<pa->recty; y++) 01049 for(x=0; x<pa->rectx; x++, rz++) (*rz)<<= 4; 01050 01051 } 01052 01053 static void reset_sky_speed(RenderPart *pa, RenderLayer *rl) 01054 { 01055 /* for all pixels with max speed, set to zero */ 01056 RenderLayer *rlpp[RE_MAX_OSA]; 01057 float *fp; 01058 int a, sample, totsample; 01059 01060 totsample= get_sample_layers(pa, rl, rlpp); 01061 01062 for(sample= 0; sample<totsample; sample++) { 01063 fp= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_VECTOR); 01064 if(fp==NULL) break; 01065 01066 for(a= 4*pa->rectx*pa->recty - 1; a>=0; a--) 01067 if(fp[a] == PASS_VECTOR_MAX) fp[a]= 0.0f; 01068 } 01069 } 01070 01071 static unsigned short *make_solid_mask(RenderPart *pa) 01072 { 01073 intptr_t *rd= pa->rectdaps; 01074 unsigned short *solidmask, *sp; 01075 int x; 01076 01077 if(rd==NULL) return NULL; 01078 01079 sp=solidmask= MEM_mallocN(sizeof(short)*pa->rectx*pa->recty, "solidmask"); 01080 01081 for(x=pa->rectx*pa->recty; x>0; x--, rd++, sp++) { 01082 if(*rd) { 01083 PixStr *ps= (PixStr *)*rd; 01084 01085 *sp= ps->mask; 01086 for(ps= ps->next; ps; ps= ps->next) 01087 *sp |= ps->mask; 01088 } 01089 else 01090 *sp= 0; 01091 } 01092 01093 return solidmask; 01094 } 01095 01096 static void addAlphaOverFloatMask(float *dest, float *source, unsigned short dmask, unsigned short smask) 01097 { 01098 unsigned short shared= dmask & smask; 01099 float mul= 1.0f - source[3]; 01100 01101 if(shared) { /* overlapping masks */ 01102 01103 /* masks differ, we make a mixture of 'add' and 'over' */ 01104 if(shared!=dmask) { 01105 float shared_bits= (float)count_mask(shared); /* alpha over */ 01106 float tot_bits= (float)count_mask(smask|dmask); /* alpha add */ 01107 01108 float add= (tot_bits - shared_bits)/tot_bits; /* add level */ 01109 mul= add + (1.0f-add)*mul; 01110 } 01111 } 01112 else if(dmask && smask) { 01113 /* works for premul only, of course */ 01114 dest[0]+= source[0]; 01115 dest[1]+= source[1]; 01116 dest[2]+= source[2]; 01117 dest[3]+= source[3]; 01118 01119 return; 01120 } 01121 01122 dest[0]= (mul*dest[0]) + source[0]; 01123 dest[1]= (mul*dest[1]) + source[1]; 01124 dest[2]= (mul*dest[2]) + source[2]; 01125 dest[3]= (mul*dest[3]) + source[3]; 01126 } 01127 01128 typedef struct ZbufSolidData { 01129 RenderLayer *rl; 01130 ListBase *psmlist; 01131 float *edgerect; 01132 } ZbufSolidData; 01133 01134 static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data) 01135 { 01136 ZbufSolidData *sdata= (ZbufSolidData*)data; 01137 ListBase *lb= sdata->psmlist; 01138 intptr_t *rd= pa->rectdaps; 01139 int *ro= zspan->recto; 01140 int *rp= zspan->rectp; 01141 int *rz= zspan->rectz; 01142 int *rm= zspan->rectmask; 01143 int x, y; 01144 int mask= 1<<sample; 01145 01146 for(y=0; y<pa->recty; y++) { 01147 for(x=0; x<pa->rectx; x++, rd++, rp++, ro++, rz++, rm++) { 01148 if(*rp) { 01149 addps(lb, rd, *ro, *rp, *rz, (zspan->rectmask)? *rm: 0, mask); 01150 } 01151 } 01152 } 01153 01154 if(sdata->rl->layflag & SCE_LAY_EDGE) 01155 if(R.r.mode & R_EDGE) 01156 edge_enhance_tile(pa, sdata->edgerect, zspan->rectz); 01157 } 01158 01159 /* main call for shading Delta Accum, for OSA */ 01160 /* supposed to be fully threadable! */ 01161 void zbufshadeDA_tile(RenderPart *pa) 01162 { 01163 RenderResult *rr= pa->result; 01164 RenderLayer *rl; 01165 ListBase psmlist= {NULL, NULL}; 01166 float *edgerect= NULL; 01167 01168 /* allocate the necessary buffers */ 01169 /* zbuffer inits these rects */ 01170 pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto"); 01171 pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp"); 01172 pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); 01173 for(rl= rr->layers.first; rl; rl= rl->next) { 01174 if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)) 01175 pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask"); 01176 01177 /* initialize pixelstructs and edge buffer */ 01178 addpsmain(&psmlist); 01179 pa->rectdaps= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "zbufDArectd"); 01180 01181 if(rl->layflag & SCE_LAY_EDGE) 01182 if(R.r.mode & R_EDGE) 01183 edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge"); 01184 01185 /* always fill visibility */ 01186 for(pa->sample=0; pa->sample<R.osa; pa->sample+=4) { 01187 ZbufSolidData sdata; 01188 01189 sdata.rl= rl; 01190 sdata.psmlist= &psmlist; 01191 sdata.edgerect= edgerect; 01192 zbuffer_solid(pa, rl, make_pixelstructs, &sdata); 01193 if(R.test_break(R.tbh)) break; 01194 } 01195 01196 /* shades solid */ 01197 if(rl->layflag & SCE_LAY_SOLID) 01198 shadeDA_tile(pa, rl); 01199 01200 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */ 01201 if(R.flag & R_LAMPHALO) 01202 if(rl->layflag & SCE_LAY_HALO) 01203 lamphalo_tile(pa, rl); 01204 01205 /* halo before ztra, because ztra fills in zbuffer now */ 01206 if(R.flag & R_HALO) 01207 if(rl->layflag & SCE_LAY_HALO) 01208 halo_tile(pa, rl); 01209 01210 /* transp layer */ 01211 if(R.flag & R_ZTRA || R.totstrand) { 01212 if(rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) { 01213 if(pa->fullresult.first) { 01214 zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist); 01215 } 01216 else { 01217 unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */ 01218 01219 /* allocate, but not free here, for asynchronous display of this rect in main thread */ 01220 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer"); 01221 01222 /* swap for live updates, and it is used in zbuf.c!!! */ 01223 SWAP(float *, rl->acolrect, rl->rectf); 01224 ztramask= zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist); 01225 SWAP(float *, rl->acolrect, rl->rectf); 01226 01227 /* zbuffer transp only returns ztramask if there's solid rendered */ 01228 if(ztramask) 01229 solidmask= make_solid_mask(pa); 01230 01231 if(ztramask && solidmask) { 01232 unsigned short *sps= solidmask, *spz= ztramask; 01233 unsigned short fullmask= (1<<R.osa)-1; 01234 float *fcol= rl->rectf; float *acol= rl->acolrect; 01235 int x; 01236 01237 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4, sps++, spz++) { 01238 if(*sps == fullmask) 01239 addAlphaOverFloat(fcol, acol); 01240 else 01241 addAlphaOverFloatMask(fcol, acol, *sps, *spz); 01242 } 01243 } 01244 else { 01245 float *fcol= rl->rectf; float *acol= rl->acolrect; 01246 int x; 01247 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) { 01248 addAlphaOverFloat(fcol, acol); 01249 } 01250 } 01251 if(solidmask) MEM_freeN(solidmask); 01252 if(ztramask) MEM_freeN(ztramask); 01253 } 01254 } 01255 } 01256 01257 /* sun/sky */ 01258 if(rl->layflag & SCE_LAY_SKY) 01259 atm_tile(pa, rl); 01260 01261 /* sky before edge */ 01262 if(rl->layflag & SCE_LAY_SKY) 01263 sky_tile(pa, rl); 01264 01265 /* extra layers */ 01266 if(rl->layflag & SCE_LAY_EDGE) 01267 if(R.r.mode & R_EDGE) 01268 edge_enhance_add(pa, rl->rectf, edgerect); 01269 01270 if(rl->passflag & SCE_PASS_VECTOR) 01271 reset_sky_speed(pa, rl); 01272 01273 /* de-premul alpha */ 01274 if(R.r.alphamode & R_ALPHAKEY) 01275 convert_to_key_alpha(pa, rl); 01276 01277 /* free stuff within loop! */ 01278 MEM_freeN(pa->rectdaps); pa->rectdaps= NULL; 01279 freeps(&psmlist); 01280 01281 if(edgerect) MEM_freeN(edgerect); 01282 edgerect= NULL; 01283 01284 if(pa->rectmask) { 01285 MEM_freeN(pa->rectmask); 01286 pa->rectmask= NULL; 01287 } 01288 } 01289 01290 /* free all */ 01291 MEM_freeN(pa->recto); pa->recto= NULL; 01292 MEM_freeN(pa->rectp); pa->rectp= NULL; 01293 MEM_freeN(pa->rectz); pa->rectz= NULL; 01294 01295 /* display active layer */ 01296 rr->renrect.ymin=rr->renrect.ymax= 0; 01297 rr->renlay= render_get_active_layer(&R, rr); 01298 } 01299 01300 01301 /* ------------------------------------------------------------------------ */ 01302 01303 /* non OSA case, full tile render */ 01304 /* supposed to be fully threadable! */ 01305 void zbufshade_tile(RenderPart *pa) 01306 { 01307 ShadeSample ssamp; 01308 RenderResult *rr= pa->result; 01309 RenderLayer *rl; 01310 PixStr ps; 01311 float *edgerect= NULL; 01312 01313 /* fake pixel struct, to comply to osa render */ 01314 ps.next= NULL; 01315 ps.mask= 0xFFFF; 01316 01317 /* zbuffer code clears/inits rects */ 01318 pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto"); 01319 pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp"); 01320 pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); 01321 01322 for(rl= rr->layers.first; rl; rl= rl->next) { 01323 if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)) 01324 pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask"); 01325 01326 /* general shader info, passes */ 01327 shade_sample_initialize(&ssamp, pa, rl); 01328 01329 zbuffer_solid(pa, rl, NULL, NULL); 01330 01331 if(!R.test_break(R.tbh)) { /* NOTE: this if() is not consistent */ 01332 01333 /* edges only for solid part, ztransp doesn't support it yet anti-aliased */ 01334 if(rl->layflag & SCE_LAY_EDGE) { 01335 if(R.r.mode & R_EDGE) { 01336 edgerect= MEM_callocN(sizeof(float)*pa->rectx*pa->recty, "rectedge"); 01337 edge_enhance_tile(pa, edgerect, pa->rectz); 01338 } 01339 } 01340 01341 /* initialize scanline updates for main thread */ 01342 rr->renrect.ymin= 0; 01343 rr->renlay= rl; 01344 01345 if(rl->layflag & SCE_LAY_SOLID) { 01346 float *fcol= rl->rectf; 01347 int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz; 01348 int x, y, offs=0, seed; 01349 01350 /* we set per pixel a fixed seed, for random AO and shadow samples */ 01351 seed= pa->rectx*pa->disprect.ymin; 01352 01353 /* irregular shadowb buffer creation */ 01354 if(R.r.mode & R_SHADOW) 01355 ISB_create(pa, NULL); 01356 01357 if(R.occlusiontree) 01358 cache_occ_samples(&R, pa, &ssamp); 01359 01360 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) { 01361 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) { 01362 /* per pixel fixed seed */ 01363 BLI_thread_srandom(pa->thread, seed++); 01364 01365 if(*rp) { 01366 ps.obi= *ro; 01367 ps.facenr= *rp; 01368 ps.z= *rz; 01369 if(shade_samples(&ssamp, &ps, x, y)) { 01370 /* combined and passes */ 01371 add_passes(rl, offs, ssamp.shi, ssamp.shr); 01372 } 01373 } 01374 } 01375 if(y&1) 01376 if(R.test_break(R.tbh)) break; 01377 } 01378 01379 if(R.occlusiontree) 01380 free_occ_samples(&R, pa); 01381 01382 if(R.r.mode & R_SHADOW) 01383 ISB_free(pa); 01384 } 01385 01386 /* disable scanline updating */ 01387 rr->renlay= NULL; 01388 } 01389 01390 /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */ 01391 if(R.flag & R_LAMPHALO) 01392 if(rl->layflag & SCE_LAY_HALO) 01393 lamphalo_tile(pa, rl); 01394 01395 /* halo before ztra, because ztra fills in zbuffer now */ 01396 if(R.flag & R_HALO) 01397 if(rl->layflag & SCE_LAY_HALO) 01398 halo_tile(pa, rl); 01399 01400 if(R.flag & R_ZTRA || R.totstrand) { 01401 if(rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) { 01402 float *fcol, *acol; 01403 int x; 01404 01405 /* allocate, but not free here, for asynchronous display of this rect in main thread */ 01406 rl->acolrect= MEM_callocN(4*sizeof(float)*pa->rectx*pa->recty, "alpha layer"); 01407 01408 /* swap for live updates */ 01409 SWAP(float *, rl->acolrect, rl->rectf); 01410 zbuffer_transp_shade(pa, rl, rl->rectf, NULL); 01411 SWAP(float *, rl->acolrect, rl->rectf); 01412 01413 fcol= rl->rectf; acol= rl->acolrect; 01414 for(x=pa->rectx*pa->recty; x>0; x--, acol+=4, fcol+=4) { 01415 addAlphaOverFloat(fcol, acol); 01416 } 01417 } 01418 } 01419 01420 /* sun/sky */ 01421 if(rl->layflag & SCE_LAY_SKY) 01422 atm_tile(pa, rl); 01423 01424 /* sky before edge */ 01425 if(rl->layflag & SCE_LAY_SKY) 01426 sky_tile(pa, rl); 01427 01428 if(!R.test_break(R.tbh)) { 01429 if(rl->layflag & SCE_LAY_EDGE) 01430 if(R.r.mode & R_EDGE) 01431 edge_enhance_add(pa, rl->rectf, edgerect); 01432 } 01433 01434 if(rl->passflag & SCE_PASS_VECTOR) 01435 reset_sky_speed(pa, rl); 01436 01437 /* de-premul alpha */ 01438 if(R.r.alphamode & R_ALPHAKEY) 01439 convert_to_key_alpha(pa, rl); 01440 01441 if(edgerect) MEM_freeN(edgerect); 01442 edgerect= NULL; 01443 01444 if(pa->rectmask) { 01445 MEM_freeN(pa->rectmask); 01446 pa->rectmask= NULL; 01447 } 01448 } 01449 01450 /* display active layer */ 01451 rr->renrect.ymin=rr->renrect.ymax= 0; 01452 rr->renlay= render_get_active_layer(&R, rr); 01453 01454 MEM_freeN(pa->recto); pa->recto= NULL; 01455 MEM_freeN(pa->rectp); pa->rectp= NULL; 01456 MEM_freeN(pa->rectz); pa->rectz= NULL; 01457 } 01458 01459 /* SSS preprocess tile render, fully threadable */ 01460 typedef struct ZBufSSSHandle { 01461 RenderPart *pa; 01462 ListBase psmlist; 01463 int totps; 01464 } ZBufSSSHandle; 01465 01466 static void addps_sss(void *cb_handle, int obi, int facenr, int x, int y, int z) 01467 { 01468 ZBufSSSHandle *handle = cb_handle; 01469 RenderPart *pa= handle->pa; 01470 01471 /* extra border for filter gives double samples on part edges, 01472 don't use those */ 01473 if(x<pa->crop || x>=pa->rectx-pa->crop) 01474 return; 01475 if(y<pa->crop || y>=pa->recty-pa->crop) 01476 return; 01477 01478 if(pa->rectall) { 01479 intptr_t *rs= pa->rectall + pa->rectx*y + x; 01480 01481 addps(&handle->psmlist, rs, obi, facenr, z, 0, 0); 01482 handle->totps++; 01483 } 01484 if(pa->rectz) { 01485 int *rz= pa->rectz + pa->rectx*y + x; 01486 int *rp= pa->rectp + pa->rectx*y + x; 01487 int *ro= pa->recto + pa->rectx*y + x; 01488 01489 if(z < *rz) { 01490 if(*rp == 0) 01491 handle->totps++; 01492 *rz= z; 01493 *rp= facenr; 01494 *ro= obi; 01495 } 01496 } 01497 if(pa->rectbackz) { 01498 int *rz= pa->rectbackz + pa->rectx*y + x; 01499 int *rp= pa->rectbackp + pa->rectx*y + x; 01500 int *ro= pa->rectbacko + pa->rectx*y + x; 01501 01502 if(z >= *rz) { 01503 if(*rp == 0) 01504 handle->totps++; 01505 *rz= z; 01506 *rp= facenr; 01507 *ro= obi; 01508 } 01509 } 01510 } 01511 01512 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) 01513 { 01514 ShadeInput *shi= ssamp->shi; 01515 ShadeResult shr; 01516 float /* texfac,*/ /* UNUSED */ orthoarea, nor[3], alpha, sx, sy; 01517 01518 /* cache for shadow */ 01519 shi->samplenr= R.shadowsamplenr[shi->thread]++; 01520 01521 if(quad) 01522 shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3); 01523 else 01524 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2); 01525 01526 /* center pixel */ 01527 sx = x + 0.5f; 01528 sy = y + 0.5f; 01529 01530 /* we estimate the area here using shi->dxco and shi->dyco. we need to 01531 enabled shi->osatex these are filled. we compute two areas, one with 01532 the normal pointed at the camera and one with the original normal, and 01533 then clamp to avoid a too large contribution from a single pixel */ 01534 shi->osatex= 1; 01535 01536 copy_v3_v3(nor, shi->facenor); 01537 calc_view_vector(shi->facenor, sx, sy); 01538 normalize_v3(shi->facenor); 01539 shade_input_set_viewco(shi, x, y, sx, sy, z); 01540 orthoarea= len_v3(shi->dxco)*len_v3(shi->dyco); 01541 01542 copy_v3_v3(shi->facenor, nor); 01543 shade_input_set_viewco(shi, x, y, sx, sy, z); 01544 *area= len_v3(shi->dxco)*len_v3(shi->dyco); 01545 *area= MIN2(*area, 2.0f*orthoarea); 01546 01547 shade_input_set_uv(shi); 01548 shade_input_set_normals(shi); 01549 01550 /* we don't want flipped normals, they screw up back scattering */ 01551 if(shi->flippednor) 01552 shade_input_flip_normals(shi); 01553 01554 /* not a pretty solution, but fixes common cases */ 01555 if(shi->obr->ob && shi->obr->ob->transflag & OB_NEG_SCALE) { 01556 negate_v3(shi->vn); 01557 negate_v3(shi->vno); 01558 negate_v3(shi->nmapnorm); 01559 } 01560 01561 /* if nodetree, use the material that we are currently preprocessing 01562 instead of the node material */ 01563 if(shi->mat->nodetree && shi->mat->use_nodes) 01564 shi->mat= mat; 01565 01566 /* init material vars */ 01567 shade_input_init_material(shi); 01568 01569 /* render */ 01570 shade_input_set_shade_texco(shi); 01571 01572 shade_samples_do_AO(ssamp); 01573 shade_material_loop(shi, &shr); 01574 01575 copy_v3_v3(co, shi->co); 01576 copy_v3_v3(color, shr.combined); 01577 01578 /* texture blending */ 01579 /* texfac= shi->mat->sss_texfac; */ /* UNUSED */ 01580 01581 alpha= shr.combined[3]; 01582 *area *= alpha; 01583 } 01584 01585 static void zbufshade_sss_free(RenderPart *pa) 01586 { 01587 #if 0 01588 MEM_freeN(pa->rectall); pa->rectall= NULL; 01589 freeps(&handle.psmlist); 01590 #else 01591 MEM_freeN(pa->rectz); pa->rectz= NULL; 01592 MEM_freeN(pa->rectp); pa->rectp= NULL; 01593 MEM_freeN(pa->recto); pa->recto= NULL; 01594 MEM_freeN(pa->rectbackz); pa->rectbackz= NULL; 01595 MEM_freeN(pa->rectbackp); pa->rectbackp= NULL; 01596 MEM_freeN(pa->rectbacko); pa->rectbacko= NULL; 01597 #endif 01598 } 01599 01600 void zbufshade_sss_tile(RenderPart *pa) 01601 { 01602 Render *re= &R; 01603 ShadeSample ssamp; 01604 ZBufSSSHandle handle; 01605 RenderResult *rr= pa->result; 01606 RenderLayer *rl; 01607 VlakRen *vlr; 01608 Material *mat= re->sss_mat; 01609 float (*co)[3], (*color)[3], *area, *fcol; 01610 int x, y, seed, quad, totpoint, display = !(re->r.scemode & R_PREVIEWBUTS); 01611 int *ro, *rz, *rp, *rbo, *rbz, *rbp, lay; 01612 #if 0 01613 PixStr *ps; 01614 intptr_t *rs; 01615 int z; 01616 #endif 01617 01618 /* setup pixelstr list and buffer for zbuffering */ 01619 handle.pa= pa; 01620 handle.totps= 0; 01621 01622 #if 0 01623 handle.psmlist.first= handle.psmlist.last= NULL; 01624 addpsmain(&handle.psmlist); 01625 01626 pa->rectall= MEM_callocN(sizeof(intptr_t)*pa->rectx*pa->recty+4, "rectall"); 01627 #else 01628 pa->recto= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "recto"); 01629 pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp"); 01630 pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); 01631 pa->rectbacko= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbacko"); 01632 pa->rectbackp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackp"); 01633 pa->rectbackz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectbackz"); 01634 #endif 01635 01636 /* setup shade sample with correct passes */ 01637 memset(&ssamp, 0, sizeof(ssamp)); 01638 shade_sample_initialize(&ssamp, pa, rr->layers.first); 01639 ssamp.tot= 1; 01640 01641 for(rl=rr->layers.first; rl; rl=rl->next) { 01642 ssamp.shi[0].lay |= rl->lay; 01643 ssamp.shi[0].layflag |= rl->layflag; 01644 ssamp.shi[0].passflag |= rl->passflag; 01645 ssamp.shi[0].combinedflag |= ~rl->pass_xor; 01646 } 01647 01648 rl= rr->layers.first; 01649 ssamp.shi[0].passflag |= SCE_PASS_RGBA|SCE_PASS_COMBINED; 01650 ssamp.shi[0].combinedflag &= ~(SCE_PASS_SPEC); 01651 ssamp.shi[0].mat_override= NULL; 01652 ssamp.shi[0].light_override= NULL; 01653 lay= ssamp.shi[0].lay; 01654 01655 /* create the pixelstrs to be used later */ 01656 zbuffer_sss(pa, lay, &handle, addps_sss); 01657 01658 if(handle.totps==0) { 01659 zbufshade_sss_free(pa); 01660 return; 01661 } 01662 01663 fcol= rl->rectf; 01664 01665 co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo"); 01666 color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor"); 01667 area= MEM_mallocN(sizeof(float)*handle.totps, "SSSArea"); 01668 01669 #if 0 01670 /* create ISB (does not work currently!) */ 01671 if(re->r.mode & R_SHADOW) 01672 ISB_create(pa, NULL); 01673 #endif 01674 01675 if(display) { 01676 /* initialize scanline updates for main thread */ 01677 rr->renrect.ymin= 0; 01678 rr->renlay= rl; 01679 } 01680 01681 seed= pa->rectx*pa->disprect.ymin; 01682 #if 0 01683 rs= pa->rectall; 01684 #else 01685 rz= pa->rectz; 01686 rp= pa->rectp; 01687 ro= pa->recto; 01688 rbz= pa->rectbackz; 01689 rbp= pa->rectbackp; 01690 rbo= pa->rectbacko; 01691 #endif 01692 totpoint= 0; 01693 01694 for(y=pa->disprect.ymin; y<pa->disprect.ymax; y++, rr->renrect.ymax++) { 01695 for(x=pa->disprect.xmin; x<pa->disprect.xmax; x++, fcol+=4) { 01696 /* per pixel fixed seed */ 01697 BLI_thread_srandom(pa->thread, seed++); 01698 01699 #if 0 01700 if(rs) { 01701 /* for each sample in this pixel, shade it */ 01702 for(ps=(PixStr*)*rs; ps; ps=ps->next) { 01703 ObjectInstanceRen *obi= &re->objectinstance[ps->obi]; 01704 ObjectRen *obr= obi->obr; 01705 vlr= RE_findOrAddVlak(obr, (ps->facenr-1) & RE_QUAD_MASK); 01706 quad= (ps->facenr & RE_QUAD_OFFS); 01707 z= ps->z; 01708 01709 shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, z, 01710 co[totpoint], color[totpoint], &area[totpoint]); 01711 01712 totpoint++; 01713 01714 add_v3_v3(fcol, color); 01715 fcol[3]= 1.0f; 01716 } 01717 01718 rs++; 01719 } 01720 #else 01721 if(rp) { 01722 if(*rp != 0) { 01723 ObjectInstanceRen *obi= &re->objectinstance[*ro]; 01724 ObjectRen *obr= obi->obr; 01725 01726 /* shade front */ 01727 vlr= RE_findOrAddVlak(obr, (*rp-1) & RE_QUAD_MASK); 01728 quad= ((*rp) & RE_QUAD_OFFS); 01729 01730 shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rz, 01731 co[totpoint], color[totpoint], &area[totpoint]); 01732 01733 add_v3_v3(fcol, color[totpoint]); 01734 fcol[3]= 1.0f; 01735 totpoint++; 01736 } 01737 01738 rp++; rz++; ro++; 01739 } 01740 01741 if(rbp) { 01742 if(*rbp != 0 && !(*rbp == *(rp-1) && *rbo == *(ro-1))) { 01743 ObjectInstanceRen *obi= &re->objectinstance[*rbo]; 01744 ObjectRen *obr= obi->obr; 01745 01746 /* shade back */ 01747 vlr= RE_findOrAddVlak(obr, (*rbp-1) & RE_QUAD_MASK); 01748 quad= ((*rbp) & RE_QUAD_OFFS); 01749 01750 shade_sample_sss(&ssamp, mat, obi, vlr, quad, x, y, *rbz, 01751 co[totpoint], color[totpoint], &area[totpoint]); 01752 01753 /* to indicate this is a back sample */ 01754 area[totpoint]= -area[totpoint]; 01755 01756 add_v3_v3(fcol, color[totpoint]); 01757 fcol[3]= 1.0f; 01758 totpoint++; 01759 } 01760 01761 rbz++; rbp++; rbo++; 01762 } 01763 #endif 01764 } 01765 01766 if(y&1) 01767 if(re->test_break(re->tbh)) break; 01768 } 01769 01770 /* note: after adding we do not free these arrays, sss keeps them */ 01771 if(totpoint > 0) { 01772 sss_add_points(re, co, color, area, totpoint); 01773 } 01774 else { 01775 MEM_freeN(co); 01776 MEM_freeN(color); 01777 MEM_freeN(area); 01778 } 01779 01780 #if 0 01781 if(re->r.mode & R_SHADOW) 01782 ISB_free(pa); 01783 #endif 01784 01785 if(display) { 01786 /* display active layer */ 01787 rr->renrect.ymin=rr->renrect.ymax= 0; 01788 rr->renlay= render_get_active_layer(&R, rr); 01789 } 01790 01791 zbufshade_sss_free(pa); 01792 } 01793 01794 /* ------------------------------------------------------------------------ */ 01795 01796 static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har) /* postprocess version */ 01797 { 01798 float dist, xsq, ysq, xn, yn, colf[4], *rectft, *rtf; 01799 float haloxs, haloys; 01800 int minx, maxx, miny, maxy, x, y; 01801 01802 /* calculate the disprect mapped coordinate for halo. note: rectx is disprect corrected */ 01803 haloxs= har->xs - R.disprect.xmin; 01804 haloys= har->ys - R.disprect.ymin; 01805 01806 har->miny= miny= haloys - har->rad/R.ycor; 01807 har->maxy= maxy= haloys + har->rad/R.ycor; 01808 01809 if(maxy<0); 01810 else if(rr->recty<miny); 01811 else { 01812 minx= floor(haloxs-har->rad); 01813 maxx= ceil(haloxs+har->rad); 01814 01815 if(maxx<0); 01816 else if(rr->rectx<minx); 01817 else { 01818 01819 if(minx<0) minx= 0; 01820 if(maxx>=rr->rectx) maxx= rr->rectx-1; 01821 if(miny<0) miny= 0; 01822 if(maxy>rr->recty) maxy= rr->recty; 01823 01824 rectft= rectf+ 4*rr->rectx*miny; 01825 01826 for(y=miny; y<maxy; y++) { 01827 01828 rtf= rectft+4*minx; 01829 01830 yn= (y - haloys)*R.ycor; 01831 ysq= yn*yn; 01832 01833 for(x=minx; x<=maxx; x++) { 01834 xn= x - haloxs; 01835 xsq= xn*xn; 01836 dist= xsq+ysq; 01837 if(dist<har->radsq) { 01838 01839 if(shadeHaloFloat(har, colf, 0x7FFFFF, dist, xn, yn, har->flarec)) 01840 addalphaAddfacFloat(rtf, colf, har->add); 01841 } 01842 rtf+=4; 01843 } 01844 01845 rectft+= 4*rr->rectx; 01846 01847 if(R.test_break(R.tbh)) break; 01848 } 01849 } 01850 } 01851 } 01852 /* ------------------------------------------------------------------------ */ 01853 01854 static void renderflare(RenderResult *rr, float *rectf, HaloRen *har) 01855 { 01856 extern float hashvectf[]; 01857 HaloRen fla; 01858 Material *ma; 01859 float *rc, rad, alfa, visifac, vec[3]; 01860 int b, type; 01861 01862 fla= *har; 01863 fla.linec= fla.ringc= fla.flarec= 0; 01864 01865 rad= har->rad; 01866 alfa= har->alfa; 01867 01868 visifac= R.ycor*(har->pixels); 01869 /* all radials added / r^3 == 1.0f! */ 01870 visifac /= (har->rad*har->rad*har->rad); 01871 visifac*= visifac; 01872 01873 ma= har->mat; 01874 01875 /* first halo: just do */ 01876 01877 har->rad= rad*ma->flaresize*visifac; 01878 har->radsq= har->rad*har->rad; 01879 har->zs= fla.zs= 0; 01880 01881 har->alfa= alfa*visifac; 01882 01883 renderhalo_post(rr, rectf, har); 01884 01885 /* next halo's: the flares */ 01886 rc= hashvectf + ma->seed2; 01887 01888 for(b=1; b<har->flarec; b++) { 01889 01890 fla.r= fabs(rc[0]); 01891 fla.g= fabs(rc[1]); 01892 fla.b= fabs(rc[2]); 01893 fla.alfa= ma->flareboost*fabsf(alfa*visifac*rc[3]); 01894 fla.hard= 20.0f + fabsf(70.0f*rc[7]); 01895 fla.tex= 0; 01896 01897 type= (int)(fabs(3.9f*rc[6])); 01898 01899 fla.rad= ma->subsize*sqrtf(fabs(2.0f*har->rad*rc[4])); 01900 01901 if(type==3) { 01902 fla.rad*= 3.0f; 01903 fla.rad+= R.rectx/10; 01904 } 01905 01906 fla.radsq= fla.rad*fla.rad; 01907 01908 vec[0]= 1.4f*rc[5]*(har->xs-R.winx/2); 01909 vec[1]= 1.4f*rc[5]*(har->ys-R.winy/2); 01910 vec[2]= 32.0f*sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + 1.0f); 01911 01912 fla.xs= R.winx/2 + vec[0] + (1.2f+rc[8])*R.rectx*vec[0]/vec[2]; 01913 fla.ys= R.winy/2 + vec[1] + (1.2f+rc[8])*R.rectx*vec[1]/vec[2]; 01914 01915 if(R.flag & R_SEC_FIELD) { 01916 if(R.r.mode & R_ODDFIELD) fla.ys += 0.5f; 01917 else fla.ys -= 0.5f; 01918 } 01919 if(type & 1) fla.type= HA_FLARECIRC; 01920 else fla.type= 0; 01921 renderhalo_post(rr, rectf, &fla); 01922 01923 fla.alfa*= 0.5f; 01924 if(type & 2) fla.type= HA_FLARECIRC; 01925 else fla.type= 0; 01926 renderhalo_post(rr, rectf, &fla); 01927 01928 rc+= 7; 01929 } 01930 } 01931 01932 /* needs recode... integrate this better! */ 01933 void add_halo_flare(Render *re) 01934 { 01935 RenderResult *rr= re->result; 01936 RenderLayer *rl; 01937 HaloRen *har; 01938 int a, mode, do_draw=0; 01939 01940 /* for now, we get the first renderlayer in list with halos set */ 01941 for(rl= rr->layers.first; rl; rl= rl->next) 01942 if(rl->layflag & SCE_LAY_HALO) 01943 break; 01944 01945 if(rl==NULL || rl->rectf==NULL) 01946 return; 01947 01948 mode= R.r.mode; 01949 R.r.mode &= ~R_PANORAMA; 01950 01951 project_renderdata(&R, projectverto, 0, 0, 0); 01952 01953 for(a=0; a<R.tothalo; a++) { 01954 har= R.sortedhalos[a]; 01955 01956 if(har->flarec) { 01957 do_draw= 1; 01958 renderflare(rr, rl->rectf, har); 01959 } 01960 } 01961 01962 if(do_draw) { 01963 /* weak... the display callback wants an active renderlayer pointer... */ 01964 rr->renlay= rl; 01965 re->display_draw(re->ddh, rr, NULL); 01966 } 01967 01968 R.r.mode= mode; 01969 } 01970 01971 /* ************************* bake ************************ */ 01972 01973 01974 typedef struct BakeShade { 01975 ShadeSample ssamp; 01976 ObjectInstanceRen *obi; 01977 VlakRen *vlr; 01978 01979 ZSpan *zspan; 01980 Image *ima; 01981 ImBuf *ibuf; 01982 01983 int rectx, recty, quad, type, vdone, ready; 01984 01985 float dir[3]; 01986 Object *actob; 01987 01988 unsigned int *rect; 01989 float *rect_float; 01990 01991 int usemask; 01992 char *rect_mask; /* bake pixel mask */ 01993 01994 float dxco[3], dyco[3]; 01995 01996 short *do_update; 01997 } BakeShade; 01998 01999 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) 02000 { 02001 if(quad) 02002 shade_input_set_triangle_i(shi, obi, vlr, 0, 2, 3); 02003 else 02004 shade_input_set_triangle_i(shi, obi, vlr, 0, 1, 2); 02005 02006 /* cache for shadow */ 02007 shi->samplenr= R.shadowsamplenr[shi->thread]++; 02008 02009 shi->mask= 0xFFFF; /* all samples */ 02010 02011 shi->u= -u; 02012 shi->v= -v; 02013 shi->xs= x; 02014 shi->ys= y; 02015 02016 shade_input_set_uv(shi); 02017 shade_input_set_normals(shi); 02018 02019 /* no normal flip */ 02020 if(shi->flippednor) 02021 shade_input_flip_normals(shi); 02022 02023 /* set up view vector to look right at the surface (note that the normal 02024 * is negated in the renderer so it does not need to be done here) */ 02025 shi->view[0]= shi->vn[0]; 02026 shi->view[1]= shi->vn[1]; 02027 shi->view[2]= shi->vn[2]; 02028 } 02029 02030 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) 02031 { 02032 BakeShade *bs= handle; 02033 ShadeSample *ssamp= &bs->ssamp; 02034 ShadeResult shr; 02035 VlakRen *vlr= shi->vlr; 02036 02037 shade_input_init_material(shi); 02038 02039 if(bs->type==RE_BAKE_AO) { 02040 ambient_occlusion(shi); 02041 02042 if(R.r.bake_flag & R_BAKE_NORMALIZE) { 02043 copy_v3_v3(shr.combined, shi->ao); 02044 } 02045 else { 02046 zero_v3(shr.combined); 02047 environment_lighting_apply(shi, &shr); 02048 } 02049 } 02050 else { 02051 if (bs->type==RE_BAKE_SHADOW) /* Why do shadows set the color anyhow?, ignore material color for baking */ 02052 shi->r = shi->g = shi->b = 1.0f; 02053 02054 shade_input_set_shade_texco(shi); 02055 02056 /* only do AO for a full bake (and obviously AO bakes) 02057 AO for light bakes is a leftover and might not be needed */ 02058 if( ELEM3(bs->type, RE_BAKE_ALL, RE_BAKE_AO, RE_BAKE_LIGHT)) 02059 shade_samples_do_AO(ssamp); 02060 02061 if(shi->mat->nodetree && shi->mat->use_nodes) { 02062 ntreeShaderExecTree(shi->mat->nodetree, shi, &shr); 02063 shi->mat= vlr->mat; /* shi->mat is being set in nodetree */ 02064 } 02065 else 02066 shade_material_loop(shi, &shr); 02067 02068 if(bs->type==RE_BAKE_NORMALS) { 02069 float nor[3]; 02070 02071 copy_v3_v3(nor, shi->vn); 02072 02073 if(R.r.bake_normal_space == R_BAKE_SPACE_CAMERA); 02074 else if(R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) { 02075 float mat[3][3], imat[3][3]; 02076 02077 /* bitangent */ 02078 if(tvn && ttang) { 02079 copy_v3_v3(mat[0], ttang); 02080 cross_v3_v3v3(mat[1], tvn, ttang); 02081 mul_v3_fl(mat[1], ttang[3]); 02082 copy_v3_v3(mat[2], tvn); 02083 } 02084 else { 02085 copy_v3_v3(mat[0], shi->nmaptang); 02086 cross_v3_v3v3(mat[1], shi->nmapnorm, shi->nmaptang); 02087 mul_v3_fl(mat[1], shi->nmaptang[3]); 02088 copy_v3_v3(mat[2], shi->nmapnorm); 02089 } 02090 02091 invert_m3_m3(imat, mat); 02092 mul_m3_v3(imat, nor); 02093 } 02094 else if(R.r.bake_normal_space == R_BAKE_SPACE_OBJECT) 02095 mul_mat3_m4_v3(ob->imat_ren, nor); /* ob->imat_ren includes viewinv! */ 02096 else if(R.r.bake_normal_space == R_BAKE_SPACE_WORLD) 02097 mul_mat3_m4_v3(R.viewinv, nor); 02098 02099 normalize_v3(nor); /* in case object has scaling */ 02100 02101 // The invert of the red channel is to make 02102 // the normal map compliant with the outside world. 02103 // It needs to be done because in Blender 02104 // the normal used in the renderer points inward. It is generated 02105 // this way in calc_vertexnormals(). Should this ever change 02106 // this negate must be removed. 02107 shr.combined[0]= (-nor[0])/2.0f + 0.5f; 02108 shr.combined[1]= nor[1]/2.0f + 0.5f; 02109 shr.combined[2]= nor[2]/2.0f + 0.5f; 02110 } 02111 else if(bs->type==RE_BAKE_TEXTURE) { 02112 shr.combined[0]= shi->r; 02113 shr.combined[1]= shi->g; 02114 shr.combined[2]= shi->b; 02115 shr.alpha = shi->alpha; 02116 } 02117 else if(bs->type==RE_BAKE_SHADOW) { 02118 copy_v3_v3(shr.combined, shr.shad); 02119 shr.alpha = shi->alpha; 02120 } 02121 else if(bs->type==RE_BAKE_SPEC_COLOR) { 02122 shr.combined[0]= shi->specr; 02123 shr.combined[1]= shi->specg; 02124 shr.combined[2]= shi->specb; 02125 shr.alpha = 1.0f; 02126 } 02127 else if(bs->type==RE_BAKE_SPEC_INTENSITY) { 02128 shr.combined[0]= 02129 shr.combined[1]= 02130 shr.combined[2]= shi->spec; 02131 shr.alpha = 1.0f; 02132 } 02133 else if(bs->type==RE_BAKE_MIRROR_COLOR) { 02134 shr.combined[0]= shi->mirr; 02135 shr.combined[1]= shi->mirg; 02136 shr.combined[2]= shi->mirb; 02137 shr.alpha = 1.0f; 02138 } 02139 else if(bs->type==RE_BAKE_MIRROR_INTENSITY) { 02140 shr.combined[0]= 02141 shr.combined[1]= 02142 shr.combined[2]= shi->ray_mirror; 02143 shr.alpha = 1.0f; 02144 } 02145 else if(bs->type==RE_BAKE_ALPHA) { 02146 shr.combined[0]= 02147 shr.combined[1]= 02148 shr.combined[2]= shi->alpha; 02149 shr.alpha = 1.0f; 02150 } 02151 else if(bs->type==RE_BAKE_EMIT) { 02152 shr.combined[0]= 02153 shr.combined[1]= 02154 shr.combined[2]= shi->emit; 02155 shr.alpha = 1.0f; 02156 } 02157 } 02158 02159 if(bs->rect_float) { 02160 float *col= bs->rect_float + 4*(bs->rectx*y + x); 02161 copy_v3_v3(col, shr.combined); 02162 if (bs->type==RE_BAKE_ALL || bs->type==RE_BAKE_TEXTURE) { 02163 col[3]= shr.alpha; 02164 } else { 02165 col[3]= 1.0; 02166 } 02167 } 02168 else { 02169 char *col= (char *)(bs->rect + bs->rectx*y + x); 02170 02171 if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE) && (R.r.color_mgt_flag & R_COLOR_MANAGEMENT)) { 02172 float srgb[3]; 02173 srgb[0]= linearrgb_to_srgb(shr.combined[0]); 02174 srgb[1]= linearrgb_to_srgb(shr.combined[1]); 02175 srgb[2]= linearrgb_to_srgb(shr.combined[2]); 02176 02177 col[0]= FTOCHAR(srgb[0]); 02178 col[1]= FTOCHAR(srgb[1]); 02179 col[2]= FTOCHAR(srgb[2]); 02180 } else { 02181 col[0]= FTOCHAR(shr.combined[0]); 02182 col[1]= FTOCHAR(shr.combined[1]); 02183 col[2]= FTOCHAR(shr.combined[2]); 02184 } 02185 02186 if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) { 02187 col[3]= FTOCHAR(shr.alpha); 02188 } else { 02189 col[3]= 255; 02190 } 02191 } 02192 02193 if (bs->rect_mask) { 02194 bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED; 02195 } 02196 } 02197 02198 static void bake_displacement(void *handle, ShadeInput *UNUSED(shi), float dist, int x, int y) 02199 { 02200 BakeShade *bs= handle; 02201 float disp; 02202 02203 if(R.r.bake_flag & R_BAKE_NORMALIZE && R.r.bake_maxdist) { 02204 disp = (dist+R.r.bake_maxdist) / (R.r.bake_maxdist*2); /* alter the range from [-bake_maxdist, bake_maxdist] to [0, 1]*/ 02205 } else { 02206 disp = 0.5f + dist; /* alter the range from [-0.5,0.5] to [0,1]*/ 02207 } 02208 02209 if(bs->rect_float) { 02210 float *col= bs->rect_float + 4*(bs->rectx*y + x); 02211 col[0] = col[1] = col[2] = disp; 02212 col[3]= 1.0f; 02213 } else { 02214 char *col= (char *)(bs->rect + bs->rectx*y + x); 02215 col[0]= FTOCHAR(disp); 02216 col[1]= FTOCHAR(disp); 02217 col[2]= FTOCHAR(disp); 02218 col[3]= 255; 02219 } 02220 if (bs->rect_mask) { 02221 bs->rect_mask[bs->rectx*y + x] = FILTER_MASK_USED; 02222 } 02223 } 02224 02225 static int bake_intersect_tree(RayObject* raytree, Isect* isect, float *start, float *dir, float sign, float *hitco, float *dist) 02226 { 02227 float maxdist; 02228 int hit; 02229 02230 /* might be useful to make a user setting for maxsize*/ 02231 if(R.r.bake_maxdist > 0.0f) 02232 maxdist= R.r.bake_maxdist; 02233 else 02234 maxdist= RE_RAYTRACE_MAXDIST + R.r.bake_biasdist; 02235 02236 /* 'dir' is always normalized */ 02237 madd_v3_v3v3fl(isect->start, start, dir, -R.r.bake_biasdist); 02238 02239 mul_v3_v3fl(isect->dir, dir, sign); 02240 02241 isect->dist = maxdist; 02242 02243 hit = RE_rayobject_raycast(raytree, isect); 02244 if(hit) { 02245 madd_v3_v3v3fl(hitco, isect->start, isect->dir, isect->dist); 02246 02247 *dist= isect->dist; 02248 } 02249 02250 return hit; 02251 } 02252 02253 static void bake_set_vlr_dxyco(BakeShade *bs, float *uv1, float *uv2, float *uv3) 02254 { 02255 VlakRen *vlr= bs->vlr; 02256 float A, d1, d2, d3, *v1, *v2, *v3; 02257 02258 if(bs->quad) { 02259 v1= vlr->v1->co; 02260 v2= vlr->v3->co; 02261 v3= vlr->v4->co; 02262 } 02263 else { 02264 v1= vlr->v1->co; 02265 v2= vlr->v2->co; 02266 v3= vlr->v3->co; 02267 } 02268 02269 /* formula derived from barycentric coordinates: 02270 * (uvArea1*v1 + uvArea2*v2 + uvArea3*v3)/uvArea 02271 * then taking u and v partial derivatives to get dxco and dyco */ 02272 A= (uv2[0] - uv1[0])*(uv3[1] - uv1[1]) - (uv3[0] - uv1[0])*(uv2[1] - uv1[1]); 02273 02274 if(fabsf(A) > FLT_EPSILON) { 02275 A= 0.5f/A; 02276 02277 d1= uv2[1] - uv3[1]; 02278 d2= uv3[1] - uv1[1]; 02279 d3= uv1[1] - uv2[1]; 02280 bs->dxco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A; 02281 bs->dxco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A; 02282 bs->dxco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A; 02283 02284 d1= uv3[0] - uv2[0]; 02285 d2= uv1[0] - uv3[0]; 02286 d3= uv2[0] - uv1[0]; 02287 bs->dyco[0]= (v1[0]*d1 + v2[0]*d2 + v3[0]*d3)*A; 02288 bs->dyco[1]= (v1[1]*d1 + v2[1]*d2 + v3[1]*d3)*A; 02289 bs->dyco[2]= (v1[2]*d1 + v2[2]*d2 + v3[2]*d3)*A; 02290 } 02291 else { 02292 bs->dxco[0]= bs->dxco[1]= bs->dxco[2]= 0.0f; 02293 bs->dyco[0]= bs->dyco[1]= bs->dyco[2]= 0.0f; 02294 } 02295 02296 if(bs->obi->flag & R_TRANSFORMED) { 02297 mul_m3_v3(bs->obi->nmat, bs->dxco); 02298 mul_m3_v3(bs->obi->nmat, bs->dyco); 02299 } 02300 } 02301 02302 static void do_bake_shade(void *handle, int x, int y, float u, float v) 02303 { 02304 BakeShade *bs= handle; 02305 VlakRen *vlr= bs->vlr; 02306 ObjectInstanceRen *obi= bs->obi; 02307 Object *ob= obi->obr->ob; 02308 float l, *v1, *v2, *v3, tvn[3], ttang[4]; 02309 int quad; 02310 ShadeSample *ssamp= &bs->ssamp; 02311 ShadeInput *shi= ssamp->shi; 02312 02313 /* fast threadsafe break test */ 02314 if(R.test_break(R.tbh)) 02315 return; 02316 02317 /* setup render coordinates */ 02318 if(bs->quad) { 02319 v1= vlr->v1->co; 02320 v2= vlr->v3->co; 02321 v3= vlr->v4->co; 02322 } 02323 else { 02324 v1= vlr->v1->co; 02325 v2= vlr->v2->co; 02326 v3= vlr->v3->co; 02327 } 02328 02329 /* renderco */ 02330 l= 1.0f-u-v; 02331 02332 shi->co[0]= l*v3[0]+u*v1[0]+v*v2[0]; 02333 shi->co[1]= l*v3[1]+u*v1[1]+v*v2[1]; 02334 shi->co[2]= l*v3[2]+u*v1[2]+v*v2[2]; 02335 02336 if(obi->flag & R_TRANSFORMED) 02337 mul_m4_v3(obi->mat, shi->co); 02338 02339 copy_v3_v3(shi->dxco, bs->dxco); 02340 copy_v3_v3(shi->dyco, bs->dyco); 02341 02342 quad= bs->quad; 02343 bake_set_shade_input(obi, vlr, shi, quad, 0, x, y, u, v); 02344 02345 if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) { 02346 shade_input_set_shade_texco(shi); 02347 copy_v3_v3(tvn, shi->nmapnorm); 02348 copy_v4_v4(ttang, shi->nmaptang); 02349 } 02350 02351 /* if we are doing selected to active baking, find point on other face */ 02352 if(bs->actob) { 02353 Isect isec, minisec; 02354 float co[3], minco[3], dist, mindist=0.0f; 02355 int hit, sign, dir=1; 02356 02357 /* intersect with ray going forward and backward*/ 02358 hit= 0; 02359 memset(&minisec, 0, sizeof(minisec)); 02360 minco[0]= minco[1]= minco[2]= 0.0f; 02361 02362 copy_v3_v3(bs->dir, shi->vn); 02363 02364 for(sign=-1; sign<=1; sign+=2) { 02365 memset(&isec, 0, sizeof(isec)); 02366 isec.mode= RE_RAY_MIRROR; 02367 02368 isec.orig.ob = obi; 02369 isec.orig.face = vlr; 02370 isec.userdata= bs->actob; 02371 isec.check = RE_CHECK_VLR_BAKE; 02372 isec.skip = RE_SKIP_VLR_NEIGHBOUR; 02373 02374 if(bake_intersect_tree(R.raytree, &isec, shi->co, shi->vn, sign, co, &dist)) { 02375 if(!hit || len_squared_v3v3(shi->co, co) < len_squared_v3v3(shi->co, minco)) { 02376 minisec= isec; 02377 mindist= dist; 02378 copy_v3_v3(minco, co); 02379 hit= 1; 02380 dir = sign; 02381 } 02382 } 02383 } 02384 02385 if (bs->type==RE_BAKE_DISPLACEMENT) { 02386 if(hit) 02387 bake_displacement(handle, shi, (dir==-1)? mindist:-mindist, x, y); 02388 else 02389 bake_displacement(handle, shi, 0.0f, x, y); 02390 return; 02391 } 02392 02393 /* if hit, we shade from the new point, otherwise from point one starting face */ 02394 if(hit) { 02395 obi= (ObjectInstanceRen*)minisec.hit.ob; 02396 vlr= (VlakRen*)minisec.hit.face; 02397 quad= (minisec.isect == 2); 02398 copy_v3_v3(shi->co, minco); 02399 02400 u= -minisec.u; 02401 v= -minisec.v; 02402 bake_set_shade_input(obi, vlr, shi, quad, 1, x, y, u, v); 02403 } 02404 } 02405 02406 if(bs->type==RE_BAKE_NORMALS && R.r.bake_normal_space==R_BAKE_SPACE_TANGENT) 02407 bake_shade(handle, ob, shi, quad, x, y, u, v, tvn, ttang); 02408 else 02409 bake_shade(handle, ob, shi, quad, x, y, u, v, 0, 0); 02410 } 02411 02412 static int get_next_bake_face(BakeShade *bs) 02413 { 02414 ObjectRen *obr; 02415 VlakRen *vlr; 02416 MTFace *tface; 02417 static int v= 0, vdone= 0; 02418 static ObjectInstanceRen *obi= NULL; 02419 02420 if(bs==NULL) { 02421 vlr= NULL; 02422 v= vdone= 0; 02423 obi= R.instancetable.first; 02424 return 0; 02425 } 02426 02427 BLI_lock_thread(LOCK_CUSTOM1); 02428 02429 for(; obi; obi=obi->next, v=0) { 02430 obr= obi->obr; 02431 02432 for(; v<obr->totvlak; v++) { 02433 vlr= RE_findOrAddVlak(obr, v); 02434 02435 if((bs->actob && bs->actob == obr->ob) || (!bs->actob && (obr->ob->flag & SELECT))) { 02436 tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0); 02437 02438 if(tface && tface->tpage) { 02439 Image *ima= tface->tpage; 02440 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); 02441 const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f}; 02442 const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f}; 02443 02444 if(ibuf==NULL) 02445 continue; 02446 02447 if(ibuf->rect==NULL && ibuf->rect_float==NULL) 02448 continue; 02449 02450 if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4)) 02451 continue; 02452 02453 /* find the image for the first time? */ 02454 if(ima->id.flag & LIB_DOIT) { 02455 ima->id.flag &= ~LIB_DOIT; 02456 02457 /* we either fill in float or char, this ensures things go fine */ 02458 if(ibuf->rect_float) 02459 imb_freerectImBuf(ibuf); 02460 /* clear image */ 02461 if(R.r.bake_flag & R_BAKE_CLEAR) 02462 IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); 02463 02464 /* might be read by UI to set active image for display */ 02465 R.bakebuf= ima; 02466 } 02467 02468 bs->obi= obi; 02469 bs->vlr= vlr; 02470 02471 bs->vdone++; /* only for error message if nothing was rendered */ 02472 v++; 02473 02474 BLI_unlock_thread(LOCK_CUSTOM1); 02475 return 1; 02476 } 02477 } 02478 } 02479 } 02480 02481 BLI_unlock_thread(LOCK_CUSTOM1); 02482 return 0; 02483 } 02484 02485 /* already have tested for tface and ima and zspan */ 02486 static void shade_tface(BakeShade *bs) 02487 { 02488 VlakRen *vlr= bs->vlr; 02489 ObjectInstanceRen *obi= bs->obi; 02490 ObjectRen *obr= obi->obr; 02491 MTFace *tface= RE_vlakren_get_tface(obr, vlr, obr->bakemtface, NULL, 0); 02492 Image *ima= tface->tpage; 02493 float vec[4][2]; 02494 int a, i1, i2, i3; 02495 02496 /* check valid zspan */ 02497 if(ima!=bs->ima) { 02498 bs->ima= ima; 02499 bs->ibuf= BKE_image_get_ibuf(ima, NULL); 02500 /* note, these calls only free/fill contents of zspan struct, not zspan itself */ 02501 zbuf_free_span(bs->zspan); 02502 zbuf_alloc_span(bs->zspan, bs->ibuf->x, bs->ibuf->y, R.clipcrop); 02503 } 02504 02505 bs->rectx= bs->ibuf->x; 02506 bs->recty= bs->ibuf->y; 02507 bs->rect= bs->ibuf->rect; 02508 bs->rect_float= bs->ibuf->rect_float; 02509 bs->quad= 0; 02510 02511 if (bs->usemask) { 02512 if (bs->ibuf->userdata==NULL) { 02513 BLI_lock_thread(LOCK_CUSTOM1); 02514 if (bs->ibuf->userdata==NULL) /* since the thread was locked, its possible another thread alloced the value */ 02515 bs->ibuf->userdata = (void *)MEM_callocN(sizeof(char)*bs->rectx*bs->recty, "BakeMask"); 02516 bs->rect_mask= (char *)bs->ibuf->userdata; 02517 BLI_unlock_thread(LOCK_CUSTOM1); 02518 } else { 02519 bs->rect_mask= (char *)bs->ibuf->userdata; 02520 } 02521 } 02522 02523 /* get pixel level vertex coordinates */ 02524 for(a=0; a<4; a++) { 02525 /* Note, workaround for pixel aligned UVs which are common and can screw up our intersection tests 02526 * where a pixel gets in between 2 faces or the middle of a quad, 02527 * camera aligned quads also have this problem but they are less common. 02528 * Add a small offset to the UVs, fixes bug #18685 - Campbell */ 02529 vec[a][0]= tface->uv[a][0]*(float)bs->rectx - (0.5f + 0.001f); 02530 vec[a][1]= tface->uv[a][1]*(float)bs->recty - (0.5f + 0.002f); 02531 } 02532 02533 /* UV indices have to be corrected for possible quad->tria splits */ 02534 i1= 0; i2= 1; i3= 2; 02535 vlr_set_uv_indices(vlr, &i1, &i2, &i3); 02536 bake_set_vlr_dxyco(bs, vec[i1], vec[i2], vec[i3]); 02537 zspan_scanconvert(bs->zspan, bs, vec[i1], vec[i2], vec[i3], do_bake_shade); 02538 02539 if(vlr->v4) { 02540 bs->quad= 1; 02541 bake_set_vlr_dxyco(bs, vec[0], vec[2], vec[3]); 02542 zspan_scanconvert(bs->zspan, bs, vec[0], vec[2], vec[3], do_bake_shade); 02543 } 02544 } 02545 02546 static void *do_bake_thread(void *bs_v) 02547 { 02548 BakeShade *bs= bs_v; 02549 02550 while(get_next_bake_face(bs)) { 02551 shade_tface(bs); 02552 02553 /* fast threadsafe break test */ 02554 if(R.test_break(R.tbh)) 02555 break; 02556 02557 /* access is not threadsafe but since its just true/false probably ok 02558 * only used for interactive baking */ 02559 if(bs->do_update) 02560 *bs->do_update= TRUE; 02561 } 02562 bs->ready= 1; 02563 02564 return NULL; 02565 } 02566 02567 void RE_bake_ibuf_filter(ImBuf *ibuf, char *mask, const int filter) 02568 { 02569 /* must check before filtering */ 02570 const short is_new_alpha= (ibuf->planes != R_IMF_PLANES_RGBA) && BKE_alphatest_ibuf(ibuf); 02571 02572 /* Margin */ 02573 if(filter) { 02574 IMB_filter_extend(ibuf, mask, filter); 02575 } 02576 02577 /* if the bake results in new alpha then change the image setting */ 02578 if(is_new_alpha) { 02579 ibuf->planes= R_IMF_PLANES_RGBA; 02580 } 02581 else { 02582 if(filter && ibuf->planes != R_IMF_PLANES_RGBA) { 02583 /* clear alpha added by filtering */ 02584 IMB_rectfill_alpha(ibuf, 1.0f); 02585 } 02586 } 02587 } 02588 02589 /* using object selection tags, the faces with UV maps get baked */ 02590 /* render should have been setup */ 02591 /* returns 0 if nothing was handled */ 02592 int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update, float *progress) 02593 { 02594 BakeShade *handles; 02595 ListBase threads; 02596 Image *ima; 02597 int a, vdone=0, usemask=0; 02598 02599 /* initialize render global */ 02600 R= *re; 02601 R.bakebuf= NULL; 02602 02603 /* initialize static vars */ 02604 get_next_bake_face(NULL); 02605 02606 /* do we need a mask? */ 02607 if (re->r.bake_filter) 02608 usemask = 1; 02609 02610 /* baker uses this flag to detect if image was initialized */ 02611 for(ima= G.main->image.first; ima; ima= ima->id.next) { 02612 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); 02613 ima->id.flag |= LIB_DOIT; 02614 if(ibuf) { 02615 ibuf->userdata = NULL; /* use for masking if needed */ 02616 if(ibuf->rect_float) 02617 ibuf->profile = IB_PROFILE_LINEAR_RGB; 02618 } 02619 } 02620 02621 BLI_init_threads(&threads, do_bake_thread, re->r.threads); 02622 02623 handles= MEM_callocN(sizeof(BakeShade)*re->r.threads, "BakeShade"); 02624 02625 /* get the threads running */ 02626 for(a=0; a<re->r.threads; a++) { 02627 /* set defaults in handles */ 02628 handles[a].ssamp.shi[0].lay= re->lay; 02629 02630 if (type==RE_BAKE_SHADOW) { 02631 handles[a].ssamp.shi[0].passflag= SCE_PASS_SHADOW; 02632 } else { 02633 handles[a].ssamp.shi[0].passflag= SCE_PASS_COMBINED; 02634 } 02635 handles[a].ssamp.shi[0].combinedflag= ~(SCE_PASS_SPEC); 02636 handles[a].ssamp.shi[0].thread= a; 02637 handles[a].ssamp.tot= 1; 02638 02639 handles[a].type= type; 02640 handles[a].actob= actob; 02641 handles[a].zspan= MEM_callocN(sizeof(ZSpan), "zspan for bake"); 02642 02643 handles[a].usemask = usemask; 02644 02645 handles[a].do_update = do_update; /* use to tell the view to update */ 02646 02647 BLI_insert_thread(&threads, &handles[a]); 02648 } 02649 02650 /* wait for everything to be done */ 02651 a= 0; 02652 while(a!=re->r.threads) { 02653 PIL_sleep_ms(50); 02654 02655 /* calculate progress */ 02656 for(vdone=0, a=0; a<re->r.threads; a++) 02657 vdone+= handles[a].vdone; 02658 if (progress) 02659 *progress = (float)(vdone / (float)re->totvlak); 02660 02661 for(a=0; a<re->r.threads; a++) { 02662 if(handles[a].ready==0) 02663 break; 02664 } 02665 } 02666 02667 /* filter and refresh images */ 02668 for(ima= G.main->image.first; ima; ima= ima->id.next) { 02669 if((ima->id.flag & LIB_DOIT)==0) { 02670 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); 02671 02672 if(!ibuf) 02673 continue; 02674 02675 RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter); 02676 02677 ibuf->userflags |= IB_BITMAPDIRTY; 02678 if (ibuf->rect_float) IMB_rect_from_float(ibuf); 02679 } 02680 } 02681 02682 /* calculate return value */ 02683 for(a=0; a<re->r.threads; a++) { 02684 zbuf_free_span(handles[a].zspan); 02685 MEM_freeN(handles[a].zspan); 02686 } 02687 02688 MEM_freeN(handles); 02689 02690 BLI_end_threads(&threads); 02691 02692 return vdone; 02693 } 02694 02695 struct Image *RE_bake_shade_get_image(void) 02696 { 02697 return R.bakebuf; 02698 } 02699