|
Blender
V2.59
|
00001 /* 00002 * $Id: render_texture.c 37653 2011-06-20 03:37:41Z mfoxdogg $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * Contributor(s): 2004-2006, Blender Foundation, full recode 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <stdio.h> 00034 #include <stdlib.h> 00035 #include <string.h> 00036 #include <math.h> 00037 00038 #include "BLI_blenlib.h" 00039 #include "BLI_math.h" 00040 #include "BLI_rand.h" 00041 #include "BLI_utildefines.h" 00042 00043 #include "DNA_texture_types.h" 00044 #include "DNA_object_types.h" 00045 #include "DNA_lamp_types.h" 00046 #include "DNA_mesh_types.h" 00047 #include "DNA_meshdata_types.h" 00048 #include "DNA_material_types.h" 00049 #include "DNA_image_types.h" 00050 #include "DNA_node_types.h" 00051 00052 #include "IMB_imbuf_types.h" 00053 #include "IMB_imbuf.h" 00054 00055 #include "BKE_colortools.h" 00056 #include "BKE_image.h" 00057 #include "BKE_node.h" 00058 #include "BKE_plugin_types.h" 00059 00060 00061 #include "BKE_global.h" 00062 #include "BKE_main.h" 00063 #include "BKE_material.h" 00064 00065 #include "BKE_library.h" 00066 #include "BKE_image.h" 00067 #include "BKE_texture.h" 00068 #include "BKE_key.h" 00069 #include "BKE_ipo.h" 00070 00071 #include "envmap.h" 00072 #include "pointdensity.h" 00073 #include "voxeldata.h" 00074 #include "renderpipeline.h" 00075 #include "render_types.h" 00076 #include "rendercore.h" 00077 #include "shading.h" 00078 #include "texture.h" 00079 00080 #include "renderdatabase.h" /* needed for UV */ 00081 00082 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 00083 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ 00084 /* only to be used here in this file, it's for speed */ 00085 extern struct Render R; 00086 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ 00087 00088 00089 00090 00091 static void init_render_texture(Render *re, Tex *tex) 00092 { 00093 int cfra= re->scene->r.cfra; 00094 00095 if(re) cfra= re->r.cfra; 00096 00097 /* imap test */ 00098 if(tex->ima && ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) { 00099 BKE_image_user_calc_frame(&tex->iuser, cfra, re?re->flag & R_SEC_FIELD:0); 00100 } 00101 00102 if(tex->type==TEX_PLUGIN) { 00103 if(tex->plugin && tex->plugin->doit) { 00104 if(tex->plugin->cfra) { 00105 *(tex->plugin->cfra)= (float)cfra; //BKE_curframe(re->scene); // XXX old animsys - timing stuff to be fixed 00106 } 00107 } 00108 } 00109 else if(tex->type==TEX_ENVMAP) { 00110 /* just in case */ 00111 tex->imaflag |= TEX_INTERPOL | TEX_MIPMAP; 00112 tex->extend= TEX_CLIP; 00113 00114 if(tex->env) { 00115 if(tex->env->type==ENV_PLANE) 00116 tex->extend= TEX_EXTEND; 00117 00118 /* only free envmap when rendermode was set to render envmaps, for previewrender */ 00119 if(G.rendering && re) { 00120 if (re->r.mode & R_ENVMAP) 00121 if(tex->env->stype==ENV_ANIM) 00122 BKE_free_envmapdata(tex->env); 00123 } 00124 } 00125 } 00126 00127 if(tex->nodetree && tex->use_nodes) { 00128 ntreeBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */ 00129 } 00130 } 00131 00132 /* ------------------------------------------------------------------------- */ 00133 00134 void init_render_textures(Render *re) 00135 { 00136 Tex *tex; 00137 00138 tex= re->main->tex.first; 00139 while(tex) { 00140 if(tex->id.us) init_render_texture(re, tex); 00141 tex= tex->id.next; 00142 } 00143 } 00144 00145 static void end_render_texture(Tex *tex) 00146 { 00147 if(tex && tex->use_nodes && tex->nodetree) 00148 ntreeEndExecTree(tex->nodetree); 00149 } 00150 00151 void end_render_textures(Render *re) 00152 { 00153 Tex *tex; 00154 for(tex= re->main->tex.first; tex; tex= tex->id.next) 00155 if(tex->id.us) 00156 end_render_texture(tex); 00157 } 00158 00159 /* ------------------------------------------------------------------------- */ 00160 00161 00162 /* this allows colorbanded textures to control normals as well */ 00163 static void tex_normal_derivate(Tex *tex, TexResult *texres) 00164 { 00165 if (tex->flag & TEX_COLORBAND) { 00166 float col[4]; 00167 if (do_colorband(tex->coba, texres->tin, col)) { 00168 float fac0, fac1, fac2, fac3; 00169 00170 fac0= (col[0]+col[1]+col[2]); 00171 do_colorband(tex->coba, texres->nor[0], col); 00172 fac1= (col[0]+col[1]+col[2]); 00173 do_colorband(tex->coba, texres->nor[1], col); 00174 fac2= (col[0]+col[1]+col[2]); 00175 do_colorband(tex->coba, texres->nor[2], col); 00176 fac3= (col[0]+col[1]+col[2]); 00177 00178 texres->nor[0]= 0.3333*(fac0 - fac1); 00179 texres->nor[1]= 0.3333*(fac0 - fac2); 00180 texres->nor[2]= 0.3333*(fac0 - fac3); 00181 00182 return; 00183 } 00184 } 00185 texres->nor[0]= texres->tin - texres->nor[0]; 00186 texres->nor[1]= texres->tin - texres->nor[1]; 00187 texres->nor[2]= texres->tin - texres->nor[2]; 00188 } 00189 00190 00191 00192 static int blend(Tex *tex, float *texvec, TexResult *texres) 00193 { 00194 float x, y, t; 00195 00196 if(tex->flag & TEX_FLIPBLEND) { 00197 x= texvec[1]; 00198 y= texvec[0]; 00199 } 00200 else { 00201 x= texvec[0]; 00202 y= texvec[1]; 00203 } 00204 00205 if(tex->stype==TEX_LIN) { /* lin */ 00206 texres->tin= (1.0+x)/2.0; 00207 } 00208 else if(tex->stype==TEX_QUAD) { /* quad */ 00209 texres->tin= (1.0+x)/2.0; 00210 if(texres->tin<0.0) texres->tin= 0.0; 00211 else texres->tin*= texres->tin; 00212 } 00213 else if(tex->stype==TEX_EASE) { /* ease */ 00214 texres->tin= (1.0+x)/2.0; 00215 if(texres->tin<=.0) texres->tin= 0.0; 00216 else if(texres->tin>=1.0) texres->tin= 1.0; 00217 else { 00218 t= texres->tin*texres->tin; 00219 texres->tin= (3.0*t-2.0*t*texres->tin); 00220 } 00221 } 00222 else if(tex->stype==TEX_DIAG) { /* diag */ 00223 texres->tin= (2.0+x+y)/4.0; 00224 } 00225 else if(tex->stype==TEX_RAD) { /* radial */ 00226 texres->tin= (atan2(y,x) / (2*M_PI) + 0.5); 00227 } 00228 else { /* sphere TEX_SPHERE */ 00229 texres->tin= 1.0-sqrt(x*x+ y*y+texvec[2]*texvec[2]); 00230 if(texres->tin<0.0) texres->tin= 0.0; 00231 if(tex->stype==TEX_HALO) texres->tin*= texres->tin; /* halo */ 00232 } 00233 00234 BRICONT; 00235 00236 return TEX_INT; 00237 } 00238 00239 /* ------------------------------------------------------------------------- */ 00240 /* ************************************************************************* */ 00241 00242 /* newnoise: all noisebased types now have different noisebases to choose from */ 00243 00244 static int clouds(Tex *tex, float *texvec, TexResult *texres) 00245 { 00246 int rv = TEX_INT; 00247 00248 texres->tin = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00249 00250 if (texres->nor!=NULL) { 00251 // calculate bumpnormal 00252 texres->nor[0] = BLI_gTurbulence(tex->noisesize, texvec[0] + tex->nabla, texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00253 texres->nor[1] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1] + tex->nabla, texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00254 texres->nor[2] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2] + tex->nabla, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00255 00256 tex_normal_derivate(tex, texres); 00257 rv |= TEX_NOR; 00258 } 00259 00260 if (tex->stype==TEX_COLOR) { 00261 // in this case, int. value should really be computed from color, 00262 // and bumpnormal from that, would be too slow, looks ok as is 00263 texres->tr = texres->tin; 00264 texres->tg = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[0], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00265 texres->tb = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[2], texvec[0], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00266 BRICONTRGB; 00267 texres->ta = 1.0; 00268 return (rv | TEX_RGB); 00269 } 00270 00271 BRICONT; 00272 00273 return rv; 00274 00275 } 00276 00277 /* creates a sine wave */ 00278 static float tex_sin(float a) 00279 { 00280 a = 0.5 + 0.5*sin(a); 00281 00282 return a; 00283 } 00284 00285 /* creates a saw wave */ 00286 static float tex_saw(float a) 00287 { 00288 const float b = 2*M_PI; 00289 00290 int n = (int)(a / b); 00291 a -= n*b; 00292 if (a < 0) a += b; 00293 return a / b; 00294 } 00295 00296 /* creates a triangle wave */ 00297 static float tex_tri(float a) 00298 { 00299 const float b = 2*M_PI; 00300 const float rmax = 1.0; 00301 00302 a = rmax - 2.0*fabs(floor((a*(1.0/b))+0.5) - (a*(1.0/b))); 00303 00304 return a; 00305 } 00306 00307 /* computes basic wood intensity value at x,y,z */ 00308 static float wood_int(Tex *tex, float x, float y, float z) 00309 { 00310 float wi=0; 00311 short wf = tex->noisebasis2; /* wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2 */ 00312 short wt = tex->stype; /* wood type: TEX_BAND=0, TEX_RING=1, TEX_BANDNOISE=2, TEX_RINGNOISE=3 */ 00313 00314 float (*waveform[3])(float); /* create array of pointers to waveform functions */ 00315 waveform[0] = tex_sin; /* assign address of tex_sin() function to pointer array */ 00316 waveform[1] = tex_saw; 00317 waveform[2] = tex_tri; 00318 00319 if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 is initialized ahead of time */ 00320 00321 if (wt==TEX_BAND) { 00322 wi = waveform[wf]((x + y + z)*10.0); 00323 } 00324 else if (wt==TEX_RING) { 00325 wi = waveform[wf](sqrt(x*x + y*y + z*z)*20.0); 00326 } 00327 else if (wt==TEX_BANDNOISE) { 00328 wi = tex->turbul*BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00329 wi = waveform[wf]((x + y + z)*10.0 + wi); 00330 } 00331 else if (wt==TEX_RINGNOISE) { 00332 wi = tex->turbul*BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00333 wi = waveform[wf](sqrt(x*x + y*y + z*z)*20.0 + wi); 00334 } 00335 00336 return wi; 00337 } 00338 00339 static int wood(Tex *tex, float *texvec, TexResult *texres) 00340 { 00341 int rv=TEX_INT; 00342 00343 texres->tin = wood_int(tex, texvec[0], texvec[1], texvec[2]); 00344 if (texres->nor!=NULL) { 00345 /* calculate bumpnormal */ 00346 texres->nor[0] = wood_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]); 00347 texres->nor[1] = wood_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]); 00348 texres->nor[2] = wood_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla); 00349 00350 tex_normal_derivate(tex, texres); 00351 rv |= TEX_NOR; 00352 } 00353 00354 BRICONT; 00355 00356 return rv; 00357 } 00358 00359 /* computes basic marble intensity at x,y,z */ 00360 static float marble_int(Tex *tex, float x, float y, float z) 00361 { 00362 float n, mi; 00363 short wf = tex->noisebasis2; /* wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2 */ 00364 short mt = tex->stype; /* marble type: TEX_SOFT=0, TEX_SHARP=1,TEX_SHAPER=2 */ 00365 00366 float (*waveform[3])(float); /* create array of pointers to waveform functions */ 00367 waveform[0] = tex_sin; /* assign address of tex_sin() function to pointer array */ 00368 waveform[1] = tex_saw; 00369 waveform[2] = tex_tri; 00370 00371 if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 isn't initialized ahead of time */ 00372 00373 n = 5.0 * (x + y + z); 00374 00375 mi = n + tex->turbul * BLI_gTurbulence(tex->noisesize, x, y, z, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00376 00377 if (mt>=TEX_SOFT) { /* TEX_SOFT always true */ 00378 mi = waveform[wf](mi); 00379 if (mt==TEX_SHARP) { 00380 mi = sqrt(mi); 00381 } 00382 else if (mt==TEX_SHARPER) { 00383 mi = sqrt(sqrt(mi)); 00384 } 00385 } 00386 00387 return mi; 00388 } 00389 00390 static int marble(Tex *tex, float *texvec, TexResult *texres) 00391 { 00392 int rv=TEX_INT; 00393 00394 texres->tin = marble_int(tex, texvec[0], texvec[1], texvec[2]); 00395 00396 if (texres->nor!=NULL) { 00397 /* calculate bumpnormal */ 00398 texres->nor[0] = marble_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]); 00399 texres->nor[1] = marble_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]); 00400 texres->nor[2] = marble_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla); 00401 00402 tex_normal_derivate(tex, texres); 00403 00404 rv |= TEX_NOR; 00405 } 00406 00407 BRICONT; 00408 00409 return rv; 00410 } 00411 00412 /* ------------------------------------------------------------------------- */ 00413 00414 static int magic(Tex *tex, float *texvec, TexResult *texres) 00415 { 00416 float x, y, z, turb=1.0; 00417 int n; 00418 00419 n= tex->noisedepth; 00420 turb= tex->turbul/5.0; 00421 00422 x= sin( ( texvec[0]+texvec[1]+texvec[2])*5.0 ); 00423 y= cos( (-texvec[0]+texvec[1]-texvec[2])*5.0 ); 00424 z= -cos( (-texvec[0]-texvec[1]+texvec[2])*5.0 ); 00425 if(n>0) { 00426 x*= turb; 00427 y*= turb; 00428 z*= turb; 00429 y= -cos(x-y+z); 00430 y*= turb; 00431 if(n>1) { 00432 x= cos(x-y-z); 00433 x*= turb; 00434 if(n>2) { 00435 z= sin(-x-y-z); 00436 z*= turb; 00437 if(n>3) { 00438 x= -cos(-x+y-z); 00439 x*= turb; 00440 if(n>4) { 00441 y= -sin(-x+y+z); 00442 y*= turb; 00443 if(n>5) { 00444 y= -cos(-x+y+z); 00445 y*= turb; 00446 if(n>6) { 00447 x= cos(x+y+z); 00448 x*= turb; 00449 if(n>7) { 00450 z= sin(x+y-z); 00451 z*= turb; 00452 if(n>8) { 00453 x= -cos(-x-y+z); 00454 x*= turb; 00455 if(n>9) { 00456 y= -sin(x-y+z); 00457 y*= turb; 00458 } 00459 } 00460 } 00461 } 00462 } 00463 } 00464 } 00465 } 00466 } 00467 } 00468 00469 if(turb!=0.0) { 00470 turb*= 2.0; 00471 x/= turb; 00472 y/= turb; 00473 z/= turb; 00474 } 00475 texres->tr= 0.5-x; 00476 texres->tg= 0.5-y; 00477 texres->tb= 0.5-z; 00478 00479 texres->tin= 0.3333*(texres->tr+texres->tg+texres->tb); 00480 00481 BRICONTRGB; 00482 texres->ta= 1.0; 00483 00484 return TEX_RGB; 00485 } 00486 00487 /* ------------------------------------------------------------------------- */ 00488 00489 /* newnoise: stucci also modified to use different noisebasis */ 00490 static int stucci(Tex *tex, float *texvec, TexResult *texres) 00491 { 00492 float nor[3], b2, ofs; 00493 int retval= TEX_INT; 00494 00495 b2= BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00496 00497 ofs= tex->turbul/200.0; 00498 00499 if(tex->stype) ofs*=(b2*b2); 00500 nor[0] = BLI_gNoise(tex->noisesize, texvec[0]+ofs, texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00501 nor[1] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1]+ofs, texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00502 nor[2] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2]+ofs, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis); 00503 00504 texres->tin= nor[2]; 00505 00506 if(texres->nor) { 00507 00508 VECCOPY(texres->nor, nor); 00509 tex_normal_derivate(tex, texres); 00510 00511 if(tex->stype==TEX_WALLOUT) { 00512 texres->nor[0]= -texres->nor[0]; 00513 texres->nor[1]= -texres->nor[1]; 00514 texres->nor[2]= -texres->nor[2]; 00515 } 00516 00517 retval |= TEX_NOR; 00518 } 00519 00520 if(tex->stype==TEX_WALLOUT) 00521 texres->tin= 1.0f-texres->tin; 00522 00523 if(texres->tin<0.0f) 00524 texres->tin= 0.0f; 00525 00526 return retval; 00527 } 00528 00529 /* ------------------------------------------------------------------------- */ 00530 /* newnoise: musgrave terrain noise types */ 00531 00532 static float mg_mFractalOrfBmTex(Tex *tex, float *texvec, TexResult *texres) 00533 { 00534 int rv = TEX_INT; 00535 float (*mgravefunc)(float, float, float, float, float, float, int); 00536 00537 if (tex->stype==TEX_MFRACTAL) 00538 mgravefunc = mg_MultiFractal; 00539 else 00540 mgravefunc = mg_fBm; 00541 00542 texres->tin = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); 00543 00544 if (texres->nor!=NULL) { 00545 float offs= tex->nabla/tex->noisesize; // also scaling of texvec 00546 00547 /* calculate bumpnormal */ 00548 texres->nor[0] = tex->ns_outscale*mgravefunc(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); 00549 texres->nor[1] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); 00550 texres->nor[2] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis); 00551 00552 tex_normal_derivate(tex, texres); 00553 rv |= TEX_NOR; 00554 } 00555 00556 BRICONT; 00557 00558 return rv; 00559 00560 } 00561 00562 static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec, TexResult *texres) 00563 { 00564 int rv = TEX_INT; 00565 float (*mgravefunc)(float, float, float, float, float, float, float, float, int); 00566 00567 if (tex->stype==TEX_RIDGEDMF) 00568 mgravefunc = mg_RidgedMultiFractal; 00569 else 00570 mgravefunc = mg_HybridMultiFractal; 00571 00572 texres->tin = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); 00573 00574 if (texres->nor!=NULL) { 00575 float offs= tex->nabla/tex->noisesize; // also scaling of texvec 00576 00577 /* calculate bumpnormal */ 00578 texres->nor[0] = tex->ns_outscale*mgravefunc(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); 00579 texres->nor[1] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); 00580 texres->nor[2] = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->mg_gain, tex->noisebasis); 00581 00582 tex_normal_derivate(tex, texres); 00583 rv |= TEX_NOR; 00584 } 00585 00586 BRICONT; 00587 00588 return rv; 00589 00590 } 00591 00592 00593 static float mg_HTerrainTex(Tex *tex, float *texvec, TexResult *texres) 00594 { 00595 int rv = TEX_INT; 00596 00597 texres->tin = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); 00598 00599 if (texres->nor!=NULL) { 00600 float offs= tex->nabla/tex->noisesize; // also scaling of texvec 00601 00602 /* calculate bumpnormal */ 00603 texres->nor[0] = tex->ns_outscale*mg_HeteroTerrain(texvec[0] + offs, texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); 00604 texres->nor[1] = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1] + offs, texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); 00605 texres->nor[2] = tex->ns_outscale*mg_HeteroTerrain(texvec[0], texvec[1], texvec[2] + offs, tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->mg_offset, tex->noisebasis); 00606 00607 tex_normal_derivate(tex, texres); 00608 rv |= TEX_NOR; 00609 } 00610 00611 BRICONT; 00612 00613 return rv; 00614 00615 } 00616 00617 00618 static float mg_distNoiseTex(Tex *tex, float *texvec, TexResult *texres) 00619 { 00620 int rv = TEX_INT; 00621 00622 texres->tin = mg_VLNoise(texvec[0], texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2); 00623 00624 if (texres->nor!=NULL) { 00625 float offs= tex->nabla/tex->noisesize; // also scaling of texvec 00626 00627 /* calculate bumpnormal */ 00628 texres->nor[0] = mg_VLNoise(texvec[0] + offs, texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2); 00629 texres->nor[1] = mg_VLNoise(texvec[0], texvec[1] + offs, texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2); 00630 texres->nor[2] = mg_VLNoise(texvec[0], texvec[1], texvec[2] + offs, tex->dist_amount, tex->noisebasis, tex->noisebasis2); 00631 00632 tex_normal_derivate(tex, texres); 00633 rv |= TEX_NOR; 00634 } 00635 00636 BRICONT; 00637 00638 00639 return rv; 00640 00641 } 00642 00643 00644 /* ------------------------------------------------------------------------- */ 00645 /* newnoise: Voronoi texture type, probably the slowest, especially with minkovsky, bumpmapping, could be done another way */ 00646 00647 static float voronoiTex(Tex *tex, float *texvec, TexResult *texres) 00648 { 00649 int rv = TEX_INT; 00650 float da[4], pa[12]; /* distance and point coordinate arrays of 4 nearest neighbours */ 00651 float aw1 = fabs(tex->vn_w1); 00652 float aw2 = fabs(tex->vn_w2); 00653 float aw3 = fabs(tex->vn_w3); 00654 float aw4 = fabs(tex->vn_w4); 00655 float sc = (aw1 + aw2 + aw3 + aw4); 00656 if (sc!=0.f) sc = tex->ns_outscale/sc; 00657 00658 voronoi(texvec[0], texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); 00659 texres->tin = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); 00660 00661 if (tex->vn_coltype) { 00662 float ca[3]; /* cell color */ 00663 cellNoiseV(pa[0], pa[1], pa[2], ca); 00664 texres->tr = aw1*ca[0]; 00665 texres->tg = aw1*ca[1]; 00666 texres->tb = aw1*ca[2]; 00667 cellNoiseV(pa[3], pa[4], pa[5], ca); 00668 texres->tr += aw2*ca[0]; 00669 texres->tg += aw2*ca[1]; 00670 texres->tb += aw2*ca[2]; 00671 cellNoiseV(pa[6], pa[7], pa[8], ca); 00672 texres->tr += aw3*ca[0]; 00673 texres->tg += aw3*ca[1]; 00674 texres->tb += aw3*ca[2]; 00675 cellNoiseV(pa[9], pa[10], pa[11], ca); 00676 texres->tr += aw4*ca[0]; 00677 texres->tg += aw4*ca[1]; 00678 texres->tb += aw4*ca[2]; 00679 if (tex->vn_coltype>=2) { 00680 float t1 = (da[1]-da[0])*10; 00681 if (t1>1) t1=1; 00682 if (tex->vn_coltype==3) t1*=texres->tin; else t1*=sc; 00683 texres->tr *= t1; 00684 texres->tg *= t1; 00685 texres->tb *= t1; 00686 } 00687 else { 00688 texres->tr *= sc; 00689 texres->tg *= sc; 00690 texres->tb *= sc; 00691 } 00692 } 00693 00694 if (texres->nor!=NULL) { 00695 float offs= tex->nabla/tex->noisesize; // also scaling of texvec 00696 00697 /* calculate bumpnormal */ 00698 voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); 00699 texres->nor[0] = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); 00700 voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, tex->vn_mexp, tex->vn_distm); 00701 texres->nor[1] = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); 00702 voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, tex->vn_mexp, tex->vn_distm); 00703 texres->nor[2] = sc * fabs(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]); 00704 00705 tex_normal_derivate(tex, texres); 00706 rv |= TEX_NOR; 00707 } 00708 00709 if (tex->vn_coltype) { 00710 BRICONTRGB; 00711 texres->ta = 1.0; 00712 return (rv | TEX_RGB); 00713 } 00714 00715 BRICONT; 00716 00717 return rv; 00718 00719 } 00720 00721 /* ------------------------------------------------------------------------- */ 00722 00723 static int texnoise(Tex *tex, TexResult *texres) 00724 { 00725 float div=3.0; 00726 int val, ran, loop; 00727 00728 ran= BLI_rand(); 00729 val= (ran & 3); 00730 00731 loop= tex->noisedepth; 00732 while(loop--) { 00733 ran= (ran>>2); 00734 val*= (ran & 3); 00735 div*= 3.0; 00736 } 00737 00738 texres->tin= ((float)val)/div; 00739 00740 BRICONT; 00741 return TEX_INT; 00742 } 00743 00744 /* ------------------------------------------------------------------------- */ 00745 00746 static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) 00747 { 00748 PluginTex *pit; 00749 int rgbnor=0; 00750 float result[ 8 ]; 00751 00752 texres->tin= 0.0; 00753 00754 pit= tex->plugin; 00755 if(pit && pit->doit) { 00756 if(texres->nor) { 00757 if (pit->version < 6) { 00758 VECCOPY(pit->result+5, texres->nor); 00759 } else { 00760 VECCOPY(result+5, texres->nor); 00761 } 00762 } 00763 if (pit->version < 6) { 00764 if(osatex) rgbnor= ((TexDoitold)pit->doit)(tex->stype, 00765 pit->data, texvec, dxt, dyt); 00766 else rgbnor= ((TexDoitold)pit->doit)(tex->stype, 00767 pit->data, texvec, NULL, NULL); 00768 } else { 00769 if(osatex) rgbnor= ((TexDoit)pit->doit)(tex->stype, 00770 pit->data, texvec, dxt, dyt, result); 00771 else rgbnor= ((TexDoit)pit->doit)(tex->stype, 00772 pit->data, texvec, NULL, NULL, result); 00773 } 00774 00775 if (pit->version < 6) { 00776 texres->tin = pit->result[0]; 00777 } else { 00778 texres->tin = result[0]; /* XXX, assigning garbage value, fixme! */ 00779 } 00780 00781 if(rgbnor & TEX_NOR) { 00782 if(texres->nor) { 00783 if (pit->version < 6) { 00784 VECCOPY(texres->nor, pit->result+5); 00785 } else { 00786 VECCOPY(texres->nor, result+5); 00787 } 00788 } 00789 } 00790 00791 if(rgbnor & TEX_RGB) { 00792 if (pit->version < 6) { 00793 texres->tr = pit->result[1]; 00794 texres->tg = pit->result[2]; 00795 texres->tb = pit->result[3]; 00796 texres->ta = pit->result[4]; 00797 } else { 00798 texres->tr = result[1]; 00799 texres->tg = result[2]; 00800 texres->tb = result[3]; 00801 texres->ta = result[4]; 00802 } 00803 00804 BRICONTRGB; 00805 } 00806 00807 BRICONT; 00808 } 00809 00810 return rgbnor; 00811 } 00812 00813 00814 static int cubemap_glob(float *n, float x, float y, float z, float *adr1, float *adr2) 00815 { 00816 float x1, y1, z1, nor[3]; 00817 int ret; 00818 00819 if(n==NULL) { 00820 nor[0]= x; nor[1]= y; nor[2]= z; // use local render coord 00821 } 00822 else { 00823 VECCOPY(nor, n); 00824 } 00825 mul_mat3_m4_v3(R.viewinv, nor); 00826 00827 x1= fabs(nor[0]); 00828 y1= fabs(nor[1]); 00829 z1= fabs(nor[2]); 00830 00831 if(z1>=x1 && z1>=y1) { 00832 *adr1 = (x + 1.0) / 2.0; 00833 *adr2 = (y + 1.0) / 2.0; 00834 ret= 0; 00835 } 00836 else if(y1>=x1 && y1>=z1) { 00837 *adr1 = (x + 1.0) / 2.0; 00838 *adr2 = (z + 1.0) / 2.0; 00839 ret= 1; 00840 } 00841 else { 00842 *adr1 = (y + 1.0) / 2.0; 00843 *adr2 = (z + 1.0) / 2.0; 00844 ret= 2; 00845 } 00846 return ret; 00847 } 00848 00849 /* ------------------------------------------------------------------------- */ 00850 00851 /* mtex argument only for projection switches */ 00852 static int cubemap(MTex *mtex, VlakRen *vlr, float *n, float x, float y, float z, float *adr1, float *adr2) 00853 { 00854 int proj[4]={0, ME_PROJXY, ME_PROJXZ, ME_PROJYZ}, ret= 0; 00855 00856 if(vlr) { 00857 int index; 00858 00859 /* Mesh vertices have such flags, for others we calculate it once based on orco */ 00860 if((vlr->puno & (ME_PROJXY|ME_PROJXZ|ME_PROJYZ))==0) { 00861 /* test for v1, vlr can be faked for baking */ 00862 if(vlr->v1 && vlr->v1->orco) { 00863 float nor[3]; 00864 normal_tri_v3( nor,vlr->v1->orco, vlr->v2->orco, vlr->v3->orco); 00865 00866 if( fabs(nor[0])<fabs(nor[2]) && fabs(nor[1])<fabs(nor[2]) ) vlr->puno |= ME_PROJXY; 00867 else if( fabs(nor[0])<fabs(nor[1]) && fabs(nor[2])<fabs(nor[1]) ) vlr->puno |= ME_PROJXZ; 00868 else vlr->puno |= ME_PROJYZ; 00869 } 00870 else return cubemap_glob(n, x, y, z, adr1, adr2); 00871 } 00872 00873 if(mtex) { 00874 /* the mtex->proj{xyz} have type char. maybe this should be wider? */ 00875 /* casting to int ensures that the index type is right. */ 00876 index = (int) mtex->projx; 00877 proj[index]= ME_PROJXY; 00878 00879 index = (int) mtex->projy; 00880 proj[index]= ME_PROJXZ; 00881 00882 index = (int) mtex->projz; 00883 proj[index]= ME_PROJYZ; 00884 } 00885 00886 if(vlr->puno & proj[1]) { 00887 *adr1 = (x + 1.0) / 2.0; 00888 *adr2 = (y + 1.0) / 2.0; 00889 } 00890 else if(vlr->puno & proj[2]) { 00891 *adr1 = (x + 1.0) / 2.0; 00892 *adr2 = (z + 1.0) / 2.0; 00893 ret= 1; 00894 } 00895 else { 00896 *adr1 = (y + 1.0) / 2.0; 00897 *adr2 = (z + 1.0) / 2.0; 00898 ret= 2; 00899 } 00900 } 00901 else { 00902 return cubemap_glob(n, x, y, z, adr1, adr2); 00903 } 00904 00905 return ret; 00906 } 00907 00908 /* ------------------------------------------------------------------------- */ 00909 00910 static int cubemap_ob(Object *ob, float *n, float x, float y, float z, float *adr1, float *adr2) 00911 { 00912 float x1, y1, z1, nor[3]; 00913 int ret; 00914 00915 if(n==NULL) return 0; 00916 00917 VECCOPY(nor, n); 00918 if(ob) mul_mat3_m4_v3(ob->imat, nor); 00919 00920 x1= fabs(nor[0]); 00921 y1= fabs(nor[1]); 00922 z1= fabs(nor[2]); 00923 00924 if(z1>=x1 && z1>=y1) { 00925 *adr1 = (x + 1.0) / 2.0; 00926 *adr2 = (y + 1.0) / 2.0; 00927 ret= 0; 00928 } 00929 else if(y1>=x1 && y1>=z1) { 00930 *adr1 = (x + 1.0) / 2.0; 00931 *adr2 = (z + 1.0) / 2.0; 00932 ret= 1; 00933 } 00934 else { 00935 *adr1 = (y + 1.0) / 2.0; 00936 *adr2 = (z + 1.0) / 2.0; 00937 ret= 2; 00938 } 00939 return ret; 00940 } 00941 00942 /* ------------------------------------------------------------------------- */ 00943 00944 static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, float *n, float *dxt, float *dyt) 00945 { 00946 Tex *tex; 00947 Object *ob= NULL; 00948 float fx, fy, fac1, area[8]; 00949 int ok, proj, areaflag= 0, wrap, texco; 00950 00951 /* mtex variables localized, only cubemap doesn't cooperate yet... */ 00952 wrap= mtex->mapping; 00953 tex= mtex->tex; 00954 ob= mtex->object; 00955 texco= mtex->texco; 00956 00957 if(R.osa==0) { 00958 00959 if(wrap==MTEX_FLAT) { 00960 fx = (t[0] + 1.0) / 2.0; 00961 fy = (t[1] + 1.0) / 2.0; 00962 } 00963 else if(wrap==MTEX_TUBE) map_to_tube( &fx, &fy,t[0], t[1], t[2]); 00964 else if(wrap==MTEX_SPHERE) map_to_sphere( &fx, &fy,t[0], t[1], t[2]); 00965 else { 00966 if(texco==TEXCO_OBJECT) cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy); 00967 else if(texco==TEXCO_GLOB) cubemap_glob(n, t[0], t[1], t[2], &fx, &fy); 00968 else cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy); 00969 } 00970 00971 /* repeat */ 00972 if(tex->extend==TEX_REPEAT) { 00973 if(tex->xrepeat>1) { 00974 float origf= fx *= tex->xrepeat; 00975 00976 if(fx>1.0) fx -= (int)(fx); 00977 else if(fx<0.0) fx+= 1-(int)(fx); 00978 00979 if(tex->flag & TEX_REPEAT_XMIR) { 00980 int orig= (int)floor(origf); 00981 if(orig & 1) 00982 fx= 1.0-fx; 00983 } 00984 } 00985 if(tex->yrepeat>1) { 00986 float origf= fy *= tex->yrepeat; 00987 00988 if(fy>1.0) fy -= (int)(fy); 00989 else if(fy<0.0) fy+= 1-(int)(fy); 00990 00991 if(tex->flag & TEX_REPEAT_YMIR) { 00992 int orig= (int)floor(origf); 00993 if(orig & 1) 00994 fy= 1.0-fy; 00995 } 00996 } 00997 } 00998 /* crop */ 00999 if(tex->cropxmin!=0.0 || tex->cropxmax!=1.0) { 01000 fac1= tex->cropxmax - tex->cropxmin; 01001 fx= tex->cropxmin+ fx*fac1; 01002 } 01003 if(tex->cropymin!=0.0 || tex->cropymax!=1.0) { 01004 fac1= tex->cropymax - tex->cropymin; 01005 fy= tex->cropymin+ fy*fac1; 01006 } 01007 01008 t[0]= fx; 01009 t[1]= fy; 01010 } 01011 else { 01012 01013 if(wrap==MTEX_FLAT) { 01014 fx= (t[0] + 1.0) / 2.0; 01015 fy= (t[1] + 1.0) / 2.0; 01016 dxt[0]/= 2.0; 01017 dxt[1]/= 2.0; 01018 dxt[2]/= 2.0; 01019 dyt[0]/= 2.0; 01020 dyt[1]/= 2.0; 01021 dyt[2]/= 2.0; 01022 } 01023 else if ELEM(wrap, MTEX_TUBE, MTEX_SPHERE) { 01024 /* exception: the seam behind (y<0.0) */ 01025 ok= 1; 01026 if(t[1]<=0.0) { 01027 fx= t[0]+dxt[0]; 01028 fy= t[0]+dyt[0]; 01029 if(fx>=0.0 && fy>=0.0 && t[0]>=0.0); 01030 else if(fx<=0.0 && fy<=0.0 && t[0]<=0.0); 01031 else ok= 0; 01032 } 01033 if(ok) { 01034 if(wrap==MTEX_TUBE) { 01035 map_to_tube( area, area+1,t[0], t[1], t[2]); 01036 map_to_tube( area+2, area+3,t[0]+dxt[0], t[1]+dxt[1], t[2]+dxt[2]); 01037 map_to_tube( area+4, area+5,t[0]+dyt[0], t[1]+dyt[1], t[2]+dyt[2]); 01038 } 01039 else { 01040 map_to_sphere(area,area+1,t[0], t[1], t[2]); 01041 map_to_sphere( area+2, area+3,t[0]+dxt[0], t[1]+dxt[1], t[2]+dxt[2]); 01042 map_to_sphere( area+4, area+5,t[0]+dyt[0], t[1]+dyt[1], t[2]+dyt[2]); 01043 } 01044 areaflag= 1; 01045 } 01046 else { 01047 if(wrap==MTEX_TUBE) map_to_tube( &fx, &fy,t[0], t[1], t[2]); 01048 else map_to_sphere( &fx, &fy,t[0], t[1], t[2]); 01049 dxt[0]/= 2.0; 01050 dxt[1]/= 2.0; 01051 dyt[0]/= 2.0; 01052 dyt[1]/= 2.0; 01053 } 01054 } 01055 else { 01056 01057 if(texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy); 01058 else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, t[0], t[1], t[2], &fx, &fy); 01059 else proj = cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy); 01060 01061 if(proj==1) { 01062 SWAP(float, dxt[1], dxt[2]); 01063 SWAP(float, dyt[1], dyt[2]); 01064 } 01065 else if(proj==2) { 01066 float f1= dxt[0], f2= dyt[0]; 01067 dxt[0]= dxt[1]; 01068 dyt[0]= dyt[1]; 01069 dxt[1]= dxt[2]; 01070 dyt[1]= dyt[2]; 01071 dxt[2]= f1; 01072 dyt[2]= f2; 01073 } 01074 01075 dxt[0] *= 0.5f; 01076 dxt[1] *= 0.5f; 01077 dxt[2] *= 0.5f; 01078 01079 dyt[0] *= 0.5f; 01080 dyt[1] *= 0.5f; 01081 dyt[2] *= 0.5f; 01082 01083 } 01084 01085 /* if area, then reacalculate dxt[] and dyt[] */ 01086 if(areaflag) { 01087 fx= area[0]; 01088 fy= area[1]; 01089 dxt[0]= area[2]-fx; 01090 dxt[1]= area[3]-fy; 01091 dyt[0]= area[4]-fx; 01092 dyt[1]= area[5]-fy; 01093 } 01094 01095 /* repeat */ 01096 if(tex->extend==TEX_REPEAT) { 01097 float max= 1.0f; 01098 if(tex->xrepeat>1) { 01099 float origf= fx *= tex->xrepeat; 01100 01101 // TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call 01102 if (tex->texfilter == TXF_BOX) { 01103 if(fx>1.0f) fx -= (int)(fx); 01104 else if(fx<0.0f) fx+= 1-(int)(fx); 01105 01106 if(tex->flag & TEX_REPEAT_XMIR) { 01107 int orig= (int)floor(origf); 01108 if(orig & 1) 01109 fx= 1.0f-fx; 01110 } 01111 } 01112 01113 max= tex->xrepeat; 01114 01115 dxt[0]*= tex->xrepeat; 01116 dyt[0]*= tex->xrepeat; 01117 } 01118 if(tex->yrepeat>1) { 01119 float origf= fy *= tex->yrepeat; 01120 01121 // TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call 01122 if (tex->texfilter == TXF_BOX) { 01123 if(fy>1.0f) fy -= (int)(fy); 01124 else if(fy<0.0f) fy+= 1-(int)(fy); 01125 01126 if(tex->flag & TEX_REPEAT_YMIR) { 01127 int orig= (int)floor(origf); 01128 if(orig & 1) 01129 fy= 1.0f-fy; 01130 } 01131 } 01132 01133 if(max<tex->yrepeat) 01134 max= tex->yrepeat; 01135 01136 dxt[1]*= tex->yrepeat; 01137 dyt[1]*= tex->yrepeat; 01138 } 01139 if(max!=1.0f) { 01140 dxt[2]*= max; 01141 dyt[2]*= max; 01142 } 01143 01144 } 01145 /* crop */ 01146 if(tex->cropxmin!=0.0 || tex->cropxmax!=1.0) { 01147 fac1= tex->cropxmax - tex->cropxmin; 01148 fx= tex->cropxmin+ fx*fac1; 01149 dxt[0]*= fac1; 01150 dyt[0]*= fac1; 01151 } 01152 if(tex->cropymin!=0.0 || tex->cropymax!=1.0) { 01153 fac1= tex->cropymax - tex->cropymin; 01154 fy= tex->cropymin+ fy*fac1; 01155 dxt[1]*= fac1; 01156 dyt[1]*= fac1; 01157 } 01158 01159 t[0]= fx; 01160 t[1]= fy; 01161 01162 } 01163 } 01164 01165 /* ************************************** */ 01166 01167 static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output) 01168 { 01169 float tmpvec[3]; 01170 int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */ 01171 01172 texres->talpha= 0; /* is set when image texture returns alpha (considered premul) */ 01173 01174 if(tex->use_nodes && tex->nodetree) { 01175 retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread, 01176 tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL); 01177 } 01178 else 01179 switch(tex->type) { 01180 01181 case 0: 01182 texres->tin= 0.0f; 01183 return 0; 01184 case TEX_CLOUDS: 01185 retval= clouds(tex, texvec, texres); 01186 break; 01187 case TEX_WOOD: 01188 retval= wood(tex, texvec, texres); 01189 break; 01190 case TEX_MARBLE: 01191 retval= marble(tex, texvec, texres); 01192 break; 01193 case TEX_MAGIC: 01194 retval= magic(tex, texvec, texres); 01195 break; 01196 case TEX_BLEND: 01197 retval= blend(tex, texvec, texres); 01198 break; 01199 case TEX_STUCCI: 01200 retval= stucci(tex, texvec, texres); 01201 break; 01202 case TEX_NOISE: 01203 retval= texnoise(tex, texres); 01204 break; 01205 case TEX_IMAGE: 01206 if(osatex) retval= imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres); 01207 else retval= imagewrap(tex, tex->ima, NULL, texvec, texres); 01208 tag_image_time(tex->ima); /* tag image as having being used */ 01209 break; 01210 case TEX_PLUGIN: 01211 retval= plugintex(tex, texvec, dxt, dyt, osatex, texres); 01212 break; 01213 case TEX_ENVMAP: 01214 retval= envmaptex(tex, texvec, dxt, dyt, osatex, texres); 01215 break; 01216 case TEX_MUSGRAVE: 01217 /* newnoise: musgrave types */ 01218 01219 /* ton: added this, for Blender convention reason. 01220 * artificer: added the use of tmpvec to avoid scaling texvec 01221 */ 01222 VECCOPY(tmpvec, texvec); 01223 mul_v3_fl(tmpvec, 1.0/tex->noisesize); 01224 01225 switch(tex->stype) { 01226 case TEX_MFRACTAL: 01227 case TEX_FBM: 01228 retval= mg_mFractalOrfBmTex(tex, tmpvec, texres); 01229 break; 01230 case TEX_RIDGEDMF: 01231 case TEX_HYBRIDMF: 01232 retval= mg_ridgedOrHybridMFTex(tex, tmpvec, texres); 01233 break; 01234 case TEX_HTERRAIN: 01235 retval= mg_HTerrainTex(tex, tmpvec, texres); 01236 break; 01237 } 01238 break; 01239 /* newnoise: voronoi type */ 01240 case TEX_VORONOI: 01241 /* ton: added this, for Blender convention reason. 01242 * artificer: added the use of tmpvec to avoid scaling texvec 01243 */ 01244 VECCOPY(tmpvec, texvec); 01245 mul_v3_fl(tmpvec, 1.0/tex->noisesize); 01246 01247 retval= voronoiTex(tex, tmpvec, texres); 01248 break; 01249 case TEX_DISTNOISE: 01250 /* ton: added this, for Blender convention reason. 01251 * artificer: added the use of tmpvec to avoid scaling texvec 01252 */ 01253 VECCOPY(tmpvec, texvec); 01254 mul_v3_fl(tmpvec, 1.0/tex->noisesize); 01255 01256 retval= mg_distNoiseTex(tex, tmpvec, texres); 01257 break; 01258 case TEX_POINTDENSITY: 01259 retval= pointdensitytex(tex, texvec, texres); 01260 break; 01261 case TEX_VOXELDATA: 01262 retval= voxeldatatex(tex, texvec, texres); 01263 break; 01264 01265 } 01266 01267 if (tex->flag & TEX_COLORBAND) { 01268 float col[4]; 01269 if (do_colorband(tex->coba, texres->tin, col)) { 01270 texres->talpha= 1; 01271 texres->tr= col[0]; 01272 texres->tg= col[1]; 01273 texres->tb= col[2]; 01274 texres->ta= col[3]; 01275 retval |= TEX_RGB; 01276 } 01277 } 01278 return retval; 01279 } 01280 01281 /* this is called from the shader and texture nodes */ 01282 int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output, ShadeInput *shi, MTex *mtex) 01283 { 01284 if(tex==NULL) { 01285 memset(texres, 0, sizeof(TexResult)); 01286 return 0; 01287 } 01288 01289 if(mtex) 01290 which_output= mtex->which_output; 01291 01292 if(tex->type==TEX_IMAGE) { 01293 int rgbnor; 01294 01295 if(mtex) { 01296 /* we have mtex, use it for 2d mapping images only */ 01297 do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt); 01298 rgbnor= multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); 01299 01300 if(mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { 01301 ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); 01302 01303 /* don't linearize float buffers, assumed to be linear */ 01304 if(ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT) 01305 srgb_to_linearrgb_v3_v3(&texres->tr, &texres->tr); 01306 } 01307 } 01308 else { 01309 /* we don't have mtex, do default flat 2d projection */ 01310 MTex localmtex; 01311 float texvec_l[3], dxt_l[3], dyt_l[3]; 01312 01313 localmtex.mapping= MTEX_FLAT; 01314 localmtex.tex= tex; 01315 localmtex.object= NULL; 01316 localmtex.texco= TEXCO_ORCO; 01317 01318 copy_v3_v3(texvec_l, texvec); 01319 if(dxt && dyt) { 01320 copy_v3_v3(dxt_l, dxt); 01321 copy_v3_v3(dyt_l, dyt); 01322 } 01323 else { 01324 zero_v3(dxt_l); 01325 zero_v3(dyt_l); 01326 } 01327 01328 do_2d_mapping(&localmtex, texvec_l, NULL, NULL, dxt_l, dyt_l); 01329 rgbnor= multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output); 01330 } 01331 01332 return rgbnor; 01333 } 01334 else 01335 return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); 01336 } 01337 01338 /* this is called for surface shading */ 01339 int multitex_mtex(ShadeInput *shi, MTex *mtex, float *texvec, float *dxt, float *dyt, TexResult *texres) 01340 { 01341 Tex *tex= mtex->tex; 01342 01343 if(tex->use_nodes && tex->nodetree) { 01344 /* stupid exception here .. but we have to pass shi and mtex to 01345 textures nodes for 2d mapping and color management for images */ 01346 return ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, shi->osatex, shi->thread, 01347 tex, mtex->which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, shi, mtex); 01348 } 01349 else 01350 return multitex(mtex->tex, texvec, dxt, dyt, shi->osatex, texres, shi->thread, mtex->which_output); 01351 } 01352 01353 /* Warning, if the texres's values are not declared zero, check the return value to be sure 01354 * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */ 01355 int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) 01356 { 01357 return multitex_nodes(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL); 01358 } 01359 01360 /* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on) */ 01361 int multitex_ext_safe(Tex *tex, float *texvec, TexResult *texres) 01362 { 01363 int use_nodes= tex->use_nodes, retval; 01364 01365 tex->use_nodes= 0; 01366 retval= multitex_nodes(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL); 01367 tex->use_nodes= use_nodes; 01368 01369 return retval; 01370 } 01371 01372 01373 /* ------------------------------------------------------------------------- */ 01374 01375 /* in = destination, tex = texture, out = previous color */ 01376 /* fact = texture strength, facg = button strength value */ 01377 void texture_rgb_blend(float *in, float *tex, float *out, float fact, float facg, int blendtype) 01378 { 01379 float facm, col; 01380 01381 switch(blendtype) { 01382 case MTEX_BLEND: 01383 fact*= facg; 01384 facm= 1.0-fact; 01385 01386 in[0]= (fact*tex[0] + facm*out[0]); 01387 in[1]= (fact*tex[1] + facm*out[1]); 01388 in[2]= (fact*tex[2] + facm*out[2]); 01389 break; 01390 01391 case MTEX_MUL: 01392 fact*= facg; 01393 facm= 1.0-facg; 01394 in[0]= (facm+fact*tex[0])*out[0]; 01395 in[1]= (facm+fact*tex[1])*out[1]; 01396 in[2]= (facm+fact*tex[2])*out[2]; 01397 break; 01398 01399 case MTEX_SCREEN: 01400 fact*= facg; 01401 facm= 1.0-facg; 01402 in[0]= 1.0 - (facm+fact*(1.0-tex[0])) * (1.0-out[0]); 01403 in[1]= 1.0 - (facm+fact*(1.0-tex[1])) * (1.0-out[1]); 01404 in[2]= 1.0 - (facm+fact*(1.0-tex[2])) * (1.0-out[2]); 01405 break; 01406 01407 case MTEX_OVERLAY: 01408 fact*= facg; 01409 facm= 1.0-facg; 01410 01411 if(out[0] < 0.5f) 01412 in[0] = out[0] * (facm + 2.0f*fact*tex[0]); 01413 else 01414 in[0] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[0])) * (1.0 - out[0]); 01415 if(out[1] < 0.5f) 01416 in[1] = out[1] * (facm + 2.0f*fact*tex[1]); 01417 else 01418 in[1] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[1])) * (1.0 - out[1]); 01419 if(out[2] < 0.5f) 01420 in[2] = out[2] * (facm + 2.0f*fact*tex[2]); 01421 else 01422 in[2] = 1.0f - (facm + 2.0f*fact*(1.0 - tex[2])) * (1.0 - out[2]); 01423 break; 01424 01425 case MTEX_SUB: 01426 fact= -fact; 01427 case MTEX_ADD: 01428 fact*= facg; 01429 in[0]= (fact*tex[0] + out[0]); 01430 in[1]= (fact*tex[1] + out[1]); 01431 in[2]= (fact*tex[2] + out[2]); 01432 break; 01433 01434 case MTEX_DIV: 01435 fact*= facg; 01436 facm= 1.0-fact; 01437 01438 if(tex[0]!=0.0) 01439 in[0]= facm*out[0] + fact*out[0]/tex[0]; 01440 if(tex[1]!=0.0) 01441 in[1]= facm*out[1] + fact*out[1]/tex[1]; 01442 if(tex[2]!=0.0) 01443 in[2]= facm*out[2] + fact*out[2]/tex[2]; 01444 01445 break; 01446 01447 case MTEX_DIFF: 01448 fact*= facg; 01449 facm= 1.0-fact; 01450 in[0]= facm*out[0] + fact*fabs(tex[0]-out[0]); 01451 in[1]= facm*out[1] + fact*fabs(tex[1]-out[1]); 01452 in[2]= facm*out[2] + fact*fabs(tex[2]-out[2]); 01453 break; 01454 01455 case MTEX_DARK: 01456 fact*= facg; 01457 facm= 1.0-fact; 01458 01459 col= tex[0]+((1-tex[0])*facm); 01460 if(col < out[0]) in[0]= col; else in[0]= out[0]; 01461 col= tex[1]+((1-tex[1])*facm); 01462 if(col < out[1]) in[1]= col; else in[1]= out[1]; 01463 col= tex[2]+((1-tex[2])*facm); 01464 if(col < out[2]) in[2]= col; else in[2]= out[2]; 01465 break; 01466 01467 case MTEX_LIGHT: 01468 fact*= facg; 01469 01470 col= fact*tex[0]; 01471 if(col > out[0]) in[0]= col; else in[0]= out[0]; 01472 col= fact*tex[1]; 01473 if(col > out[1]) in[1]= col; else in[1]= out[1]; 01474 col= fact*tex[2]; 01475 if(col > out[2]) in[2]= col; else in[2]= out[2]; 01476 break; 01477 01478 case MTEX_BLEND_HUE: 01479 fact*= facg; 01480 VECCOPY(in, out); 01481 ramp_blend(MA_RAMP_HUE, in, in+1, in+2, fact, tex); 01482 break; 01483 case MTEX_BLEND_SAT: 01484 fact*= facg; 01485 VECCOPY(in, out); 01486 ramp_blend(MA_RAMP_SAT, in, in+1, in+2, fact, tex); 01487 break; 01488 case MTEX_BLEND_VAL: 01489 fact*= facg; 01490 VECCOPY(in, out); 01491 ramp_blend(MA_RAMP_VAL, in, in+1, in+2, fact, tex); 01492 break; 01493 case MTEX_BLEND_COLOR: 01494 fact*= facg; 01495 VECCOPY(in, out); 01496 ramp_blend(MA_RAMP_COLOR, in, in+1, in+2, fact, tex); 01497 break; 01498 case MTEX_SOFT_LIGHT: 01499 fact*= facg; 01500 VECCOPY(in, out); 01501 ramp_blend(MA_RAMP_SOFT, in, in+1, in+2, fact, tex); 01502 break; 01503 case MTEX_LIN_LIGHT: 01504 fact*= facg; 01505 VECCOPY(in, out); 01506 ramp_blend(MA_RAMP_LINEAR, in, in+1, in+2, fact, tex); 01507 break; 01508 } 01509 } 01510 01511 float texture_value_blend(float tex, float out, float fact, float facg, int blendtype) 01512 { 01513 float in=0.0, facm, col, scf; 01514 int flip= (facg < 0.0f); 01515 01516 facg= fabsf(facg); 01517 01518 fact*= facg; 01519 facm= 1.0-fact; 01520 if(flip) SWAP(float, fact, facm); 01521 01522 switch(blendtype) { 01523 case MTEX_BLEND: 01524 in= fact*tex + facm*out; 01525 break; 01526 01527 case MTEX_MUL: 01528 facm= 1.0-facg; 01529 in= (facm+fact*tex)*out; 01530 break; 01531 01532 case MTEX_SCREEN: 01533 facm= 1.0-facg; 01534 in= 1.0-(facm+fact*(1.0-tex))*(1.0-out); 01535 break; 01536 01537 case MTEX_OVERLAY: 01538 facm= 1.0-facg; 01539 if(out < 0.5f) 01540 in = out * (facm + 2.0f*fact*tex); 01541 else 01542 in = 1.0f - (facm + 2.0f*fact*(1.0 - tex)) * (1.0 - out); 01543 break; 01544 01545 case MTEX_SUB: 01546 fact= -fact; 01547 case MTEX_ADD: 01548 in= fact*tex + out; 01549 break; 01550 01551 case MTEX_DIV: 01552 if(tex!=0.0) 01553 in= facm*out + fact*out/tex; 01554 break; 01555 01556 case MTEX_DIFF: 01557 in= facm*out + fact*fabs(tex-out); 01558 break; 01559 01560 case MTEX_DARK: 01561 col= fact*tex; 01562 if(col < out) in= col; else in= out; 01563 break; 01564 01565 case MTEX_LIGHT: 01566 col= fact*tex; 01567 if(col > out) in= col; else in= out; 01568 break; 01569 01570 case MTEX_SOFT_LIGHT: 01571 scf=1.0 - (1.0 - tex) * (1.0 - out); 01572 in= facm*out + fact * ((1.0 - out) * tex * out) + (out * scf); 01573 break; 01574 01575 case MTEX_LIN_LIGHT: 01576 if (tex > 0.5) 01577 in = out + fact*(2*(tex - 0.5)); 01578 else 01579 in = out + fact*(2*tex - 1); 01580 break; 01581 } 01582 01583 return in; 01584 } 01585 01586 static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, float* co, float* dx, float* dy, float* texvec, float* dxt, float* dyt) 01587 { 01588 // new: first swap coords, then map, then trans/scale 01589 if (tex->type == TEX_IMAGE) { 01590 // placement 01591 texvec[0] = mtex->projx ? co[mtex->projx - 1] : 0.f; 01592 texvec[1] = mtex->projy ? co[mtex->projy - 1] : 0.f; 01593 texvec[2] = mtex->projz ? co[mtex->projz - 1] : 0.f; 01594 01595 if (shi->osatex) { 01596 if (mtex->projx) { 01597 dxt[0] = dx[mtex->projx - 1]; 01598 dyt[0] = dy[mtex->projx - 1]; 01599 } 01600 else dxt[0] = dyt[0] = 0.f; 01601 if (mtex->projy) { 01602 dxt[1] = dx[mtex->projy - 1]; 01603 dyt[1] = dy[mtex->projy - 1]; 01604 } 01605 else dxt[1] = dyt[1] = 0.f; 01606 if (mtex->projz) { 01607 dxt[2] = dx[mtex->projz - 1]; 01608 dyt[2] = dy[mtex->projz - 1]; 01609 } 01610 else dxt[2] = dyt[2] = 0.f; 01611 } 01612 do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt); 01613 01614 // translate and scale 01615 texvec[0] = mtex->size[0]*(texvec[0] - 0.5f) + mtex->ofs[0] + 0.5f; 01616 texvec[1] = mtex->size[1]*(texvec[1] - 0.5f) + mtex->ofs[1] + 0.5f; 01617 if (shi->osatex) { 01618 dxt[0] = mtex->size[0]*dxt[0]; 01619 dxt[1] = mtex->size[1]*dxt[1]; 01620 dyt[0] = mtex->size[0]*dyt[0]; 01621 dyt[1] = mtex->size[1]*dyt[1]; 01622 } 01623 01624 /* problem: repeat-mirror is not a 'repeat' but 'extend' in imagetexture.c */ 01625 // TXF: bug was here, only modify texvec when repeat mode set, old code affected other modes too. 01626 // New texfilters solve mirroring differently so that it also works correctly when 01627 // textures are scaled (sizeXYZ) as well as repeated. See also modification in do_2d_mapping(). 01628 // (since currently only done in osa mode, results will look incorrect without osa TODO) 01629 if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_XMIR)) { 01630 if (tex->texfilter == TXF_BOX) 01631 texvec[0] -= floorf(texvec[0]); // this line equivalent to old code, same below 01632 else if (texvec[0] < 0.f || texvec[0] > 1.f) { 01633 const float tx = 0.5f*texvec[0]; 01634 texvec[0] = 2.f*(tx - floorf(tx)); 01635 if (texvec[0] > 1.f) texvec[0] = 2.f - texvec[0]; 01636 } 01637 } 01638 if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_YMIR)) { 01639 if (tex->texfilter == TXF_BOX) 01640 texvec[1] -= floorf(texvec[1]); 01641 else if (texvec[1] < 0.f || texvec[1] > 1.f) { 01642 const float ty = 0.5f*texvec[1]; 01643 texvec[1] = 2.f*(ty - floorf(ty)); 01644 if (texvec[1] > 1.f) texvec[1] = 2.f - texvec[1]; 01645 } 01646 } 01647 01648 } 01649 else { // procedural 01650 // placement 01651 texvec[0] = mtex->size[0]*(mtex->projx ? (co[mtex->projx - 1] + mtex->ofs[0]) : mtex->ofs[0]); 01652 texvec[1] = mtex->size[1]*(mtex->projy ? (co[mtex->projy - 1] + mtex->ofs[1]) : mtex->ofs[1]); 01653 texvec[2] = mtex->size[2]*(mtex->projz ? (co[mtex->projz - 1] + mtex->ofs[2]) : mtex->ofs[2]); 01654 01655 if (shi->osatex) { 01656 if (mtex->projx) { 01657 dxt[0] = mtex->size[0]*dx[mtex->projx - 1]; 01658 dyt[0] = mtex->size[0]*dy[mtex->projx - 1]; 01659 } 01660 else dxt[0] = dyt[0] = 0.f; 01661 if (mtex->projy) { 01662 dxt[1] = mtex->size[1]*dx[mtex->projy - 1]; 01663 dyt[1] = mtex->size[1]*dy[mtex->projy - 1]; 01664 } 01665 else dxt[1] = dyt[1] = 0.f; 01666 if (mtex->projz) { 01667 dxt[2] = mtex->size[2]*dx[mtex->projz - 1]; 01668 dyt[2] = mtex->size[2]*dy[mtex->projz - 1]; 01669 } 01670 else dxt[2]= dyt[2] = 0.f; 01671 } 01672 } 01673 } 01674 01675 /* Bump code from 2.5 development cycle, has a number of bugs, but here for compatibility */ 01676 01677 typedef struct CompatibleBump { 01678 float nu[3], nv[3], nn[3]; 01679 float dudnu, dudnv, dvdnu, dvdnv; 01680 int nunvdone; 01681 } CompatibleBump; 01682 01683 static void compatible_bump_init(CompatibleBump *compat_bump) 01684 { 01685 memset(compat_bump, 0, sizeof(*compat_bump)); 01686 01687 compat_bump->dudnu = 1.0f; 01688 compat_bump->dvdnv = 1.0f; 01689 } 01690 01691 static void compatible_bump_uv_derivs(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, int i) 01692 { 01693 // uvmapping only, calculation of normal tangent u/v partial derivatives 01694 // (should not be here, dudnu, dudnv, dvdnu & dvdnv should probably be part of ShadeInputUV struct, 01695 // nu/nv in ShadeInput and this calculation should then move to shadeinput.c, shade_input_set_shade_texco() func.) 01696 // NOTE: test for shi->obr->ob here, since vlr/obr/obi can be 'fake' when called from fastshade(), another reason to move it.. 01697 // NOTE: shi->v1 is NULL when called from displace_render_vert, assigning verts in this case is not trivial because the shi quad face side is not know. 01698 if ((mtex->texflag & MTEX_COMPAT_BUMP) && shi->obr && shi->obr->ob && shi->v1) { 01699 if(mtex->mapto & (MAP_NORM|MAP_WARP) && !((mtex->tex->type==TEX_IMAGE) && (mtex->tex->imaflag & TEX_NORMALMAP))) { 01700 MTFace* tf = RE_vlakren_get_tface(shi->obr, shi->vlr, i, NULL, 0); 01701 int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3; 01702 01703 vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3); 01704 01705 // compute ortho basis around normal 01706 if(!compat_bump->nunvdone) { 01707 // render normal is negated 01708 compat_bump->nn[0] = -shi->vn[0]; 01709 compat_bump->nn[1] = -shi->vn[1]; 01710 compat_bump->nn[2] = -shi->vn[2]; 01711 ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn); 01712 compat_bump->nunvdone= 1; 01713 } 01714 01715 if (tf) { 01716 float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3]; 01717 const float an[3] = {fabsf(compat_bump->nn[0]), fabsf(compat_bump->nn[1]), fabsf(compat_bump->nn[2])}; 01718 const int a1 = (an[0] > an[1] && an[0] > an[2]) ? 1 : 0; 01719 const int a2 = (an[2] > an[0] && an[2] > an[1]) ? 1 : 2; 01720 const float dp1_a1 = shi->v1->co[a1] - shi->v3->co[a1]; 01721 const float dp1_a2 = shi->v1->co[a2] - shi->v3->co[a2]; 01722 const float dp2_a1 = shi->v2->co[a1] - shi->v3->co[a1]; 01723 const float dp2_a2 = shi->v2->co[a2] - shi->v3->co[a2]; 01724 const float du1 = uv1[0] - uv3[0], du2 = uv2[0] - uv3[0]; 01725 const float dv1 = uv1[1] - uv3[1], dv2 = uv2[1] - uv3[1]; 01726 const float dpdu_a1 = dv2*dp1_a1 - dv1*dp2_a1; 01727 const float dpdu_a2 = dv2*dp1_a2 - dv1*dp2_a2; 01728 const float dpdv_a1 = du1*dp2_a1 - du2*dp1_a1; 01729 const float dpdv_a2 = du1*dp2_a2 - du2*dp1_a2; 01730 float d = dpdu_a1*dpdv_a2 - dpdv_a1*dpdu_a2; 01731 float uvd = du1*dv2 - dv1*du2; 01732 01733 if (uvd == 0.f) uvd = 1e-5f; 01734 if (d == 0.f) d = 1e-5f; 01735 d = uvd / d; 01736 01737 compat_bump->dudnu = (dpdv_a2*compat_bump->nu[a1] - dpdv_a1*compat_bump->nu[a2])*d; 01738 compat_bump->dvdnu = (dpdu_a1*compat_bump->nu[a2] - dpdu_a2*compat_bump->nu[a1])*d; 01739 compat_bump->dudnv = (dpdv_a2*compat_bump->nv[a1] - dpdv_a1*compat_bump->nv[a2])*d; 01740 compat_bump->dvdnv = (dpdu_a1*compat_bump->nv[a2] - dpdu_a2*compat_bump->nv[a1])*d; 01741 } 01742 } 01743 } 01744 } 01745 01746 static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float *texvec, float *dxt, float *dyt) 01747 { 01748 TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; // temp TexResult 01749 float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv; 01750 const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0)); 01751 const float bf = 0.04f*Tnor*mtex->norfac; 01752 int rgbnor; 01753 // disable internal bump eval 01754 float* nvec = texres->nor; 01755 texres->nor = NULL; 01756 // du & dv estimates, constant value defaults 01757 du = dv = 0.01f; 01758 01759 // compute ortho basis around normal 01760 if(!compat_bump->nunvdone) { 01761 // render normal is negated 01762 negate_v3_v3(compat_bump->nn, shi->vn); 01763 ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn); 01764 compat_bump->nunvdone= 1; 01765 } 01766 01767 // two methods, either constant based on main image resolution, 01768 // (which also works without osa, though of course not always good (or even very bad) results), 01769 // or based on tex derivative max values (osa only). Not sure which is best... 01770 01771 if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) { 01772 // in case we have no proper derivatives, fall back to 01773 // computing du/dv it based on image size 01774 ImBuf* ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); 01775 if (ibuf) { 01776 du = 1.f/(float)ibuf->x; 01777 dv = 1.f/(float)ibuf->y; 01778 } 01779 } 01780 else if (shi->osatex) { 01781 // we have derivatives, can compute proper du/dv 01782 if (tex->type == TEX_IMAGE) { // 2d image, use u & v max. of dx/dy 2d vecs 01783 const float adx[2] = {fabsf(dx[0]), fabsf(dx[1])}; 01784 const float ady[2] = {fabsf(dy[0]), fabsf(dy[1])}; 01785 du = MAX2(adx[0], ady[0]); 01786 dv = MAX2(adx[1], ady[1]); 01787 } 01788 else { // 3d procedural, estimate from all dx/dy elems 01789 const float adx[3] = {fabsf(dx[0]), fabsf(dx[1]), fabsf(dx[2])}; 01790 const float ady[3] = {fabsf(dy[0]), fabsf(dy[1]), fabsf(dy[2])}; 01791 du = MAX3(adx[0], adx[1], adx[2]); 01792 dv = MAX3(ady[1], ady[1], ady[2]); 01793 } 01794 } 01795 01796 // center, main return value 01797 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); 01798 rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres); 01799 cd = fromrgb ? (texres->tr + texres->tg + texres->tb)*0.33333333f : texres->tin; 01800 01801 if (mtex->texco == TEXCO_UV) { 01802 // for the uv case, use the same value for both du/dv, 01803 // since individually scaling the normal derivatives makes them useless... 01804 du = MIN2(du, dv); 01805 idu = (du < 1e-5f) ? bf : (bf/du); 01806 01807 // +u val 01808 tco[0] = co[0] + compat_bump->dudnu*du; 01809 tco[1] = co[1] + compat_bump->dvdnu*du; 01810 tco[2] = 0.f; 01811 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); 01812 multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr); 01813 ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin)); 01814 01815 // +v val 01816 tco[0] = co[0] + compat_bump->dudnv*du; 01817 tco[1] = co[1] + compat_bump->dvdnv*du; 01818 tco[2] = 0.f; 01819 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); 01820 multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr); 01821 vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin)); 01822 } 01823 else { 01824 float tu[3], tv[3]; 01825 01826 copy_v3_v3(tu, compat_bump->nu); 01827 copy_v3_v3(tv, compat_bump->nv); 01828 01829 idu = (du < 1e-5f) ? bf : (bf/du); 01830 idv = (dv < 1e-5f) ? bf : (bf/dv); 01831 01832 if ((mtex->texco == TEXCO_ORCO) && shi->obr && shi->obr->ob) { 01833 mul_mat3_m4_v3(shi->obr->ob->imat_ren, tu); 01834 mul_mat3_m4_v3(shi->obr->ob->imat_ren, tv); 01835 normalize_v3(tu); 01836 normalize_v3(tv); 01837 } 01838 else if (mtex->texco == TEXCO_GLOB) { 01839 mul_mat3_m4_v3(R.viewinv, tu); 01840 mul_mat3_m4_v3(R.viewinv, tv); 01841 } 01842 else if (mtex->texco == TEXCO_OBJECT && mtex->object) { 01843 mul_mat3_m4_v3(mtex->object->imat_ren, tu); 01844 mul_mat3_m4_v3(mtex->object->imat_ren, tv); 01845 normalize_v3(tu); 01846 normalize_v3(tv); 01847 } 01848 01849 // +u val 01850 tco[0] = co[0] + tu[0]*du; 01851 tco[1] = co[1] + tu[1]*du; 01852 tco[2] = co[2] + tu[2]*du; 01853 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); 01854 multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr); 01855 ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin)); 01856 01857 // +v val 01858 tco[0] = co[0] + tv[0]*dv; 01859 tco[1] = co[1] + tv[1]*dv; 01860 tco[2] = co[2] + tv[2]*dv; 01861 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt); 01862 multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr); 01863 vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin)); 01864 } 01865 01866 // bumped normal 01867 compat_bump->nu[0] += ud*compat_bump->nn[0]; 01868 compat_bump->nu[1] += ud*compat_bump->nn[1]; 01869 compat_bump->nu[2] += ud*compat_bump->nn[2]; 01870 compat_bump->nv[0] += vd*compat_bump->nn[0]; 01871 compat_bump->nv[1] += vd*compat_bump->nn[1]; 01872 compat_bump->nv[2] += vd*compat_bump->nn[2]; 01873 cross_v3_v3v3(nvec, compat_bump->nu, compat_bump->nv); 01874 01875 nvec[0] = -nvec[0]; 01876 nvec[1] = -nvec[1]; 01877 nvec[2] = -nvec[2]; 01878 texres->nor = nvec; 01879 01880 rgbnor |= TEX_NOR; 01881 return rgbnor; 01882 } 01883 01884 /* Improved bump code from later in 2.5 development cycle */ 01885 01886 typedef struct NTapBump { 01887 int init_done; 01888 int iPrevBumpSpace; // 0: uninitialized, 1: objectspace, 2: texturespace, 4: viewspace 01889 // bumpmapping 01890 float vNorg[3]; // backup copy of shi->vn 01891 float vNacc[3]; // original surface normal minus the surface gradient of every bump map which is encountered 01892 float vR1[3], vR2[3]; // cross products (sigma_y, original_normal), (original_normal, sigma_x) 01893 float sgn_det; // sign of the determinant of the matrix {sigma_x, sigma_y, original_normal} 01894 float fPrevMagnitude; // copy of previous magnitude, used for multiple bumps in different spaces 01895 } NTapBump; 01896 01897 static void ntap_bump_init(NTapBump *ntap_bump) 01898 { 01899 memset(ntap_bump, 0, sizeof(*ntap_bump)); 01900 } 01901 01902 static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float *texvec, float *dxt, float *dyt) 01903 { 01904 TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; // temp TexResult 01905 01906 const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0)); 01907 float Hscale = Tnor*mtex->norfac; 01908 01909 // 2 channels for 2D texture and 3 for 3D textures. 01910 const int nr_channels = (mtex->texco == TEXCO_UV)? 2 : 3; 01911 int c, rgbnor, iBumpSpace; 01912 float dHdx, dHdy; 01913 01914 // disable internal bump eval in sampler, save pointer 01915 float *nvec = texres->nor; 01916 texres->nor = NULL; 01917 01918 if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { 01919 if(tex->ima) 01920 Hscale *= 13.0f; // appears to be a sensible default value 01921 } else 01922 Hscale *= 0.1f; // factor 0.1 proved to look like the previous bump code 01923 01924 if( !ntap_bump->init_done ) { 01925 VECCOPY(ntap_bump->vNacc, shi->vn); 01926 VECCOPY(ntap_bump->vNorg, shi->vn); 01927 ntap_bump->fPrevMagnitude = 1.0f; 01928 ntap_bump->iPrevBumpSpace = 0; 01929 01930 ntap_bump->init_done = 1; 01931 } 01932 01933 if(!(mtex->texflag & MTEX_5TAP_BUMP)) { 01934 // compute height derivatives with respect to output image pixel coordinates x and y 01935 float STll[3], STlr[3], STul[3]; 01936 float Hll, Hlr, Hul; 01937 01938 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); 01939 01940 for(c=0; c<nr_channels; c++) { 01941 // dx contains the derivatives (du/dx, dv/dx) 01942 // dy contains the derivatives (du/dy, dv/dy) 01943 STll[c] = texvec[c]; 01944 STlr[c] = texvec[c]+dxt[c]; 01945 STul[c] = texvec[c]+dyt[c]; 01946 } 01947 01948 // clear unused derivatives 01949 for(c=nr_channels; c<3; c++) { 01950 STll[c] = 0.0f; 01951 STlr[c] = 0.0f; 01952 STul[c] = 0.0f; 01953 } 01954 01955 // use texres for the center sample, set rgbnor 01956 rgbnor = multitex_mtex(shi, mtex, STll, dxt, dyt, texres); 01957 Hll = (fromrgb)? RGBTOBW(texres->tr, texres->tg, texres->tb) : texres->tin; 01958 01959 // use ttexr for the other 2 taps 01960 multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr); 01961 Hlr = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin; 01962 01963 multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr); 01964 Hul = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin; 01965 01966 dHdx = Hscale*(Hlr - Hll); 01967 dHdy = Hscale*(Hul - Hll); 01968 } 01969 else { 01970 /* same as above, but doing 5 taps, increasing quality at cost of speed */ 01971 float STc[3], STl[3], STr[3], STd[3], STu[3]; 01972 float Hc, Hl, Hr, Hd, Hu; 01973 01974 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); 01975 01976 for(c=0; c<nr_channels; c++) { 01977 STc[c] = texvec[c]; 01978 STl[c] = texvec[c] - 0.5f*dxt[c]; 01979 STr[c] = texvec[c] + 0.5f*dxt[c]; 01980 STd[c] = texvec[c] - 0.5f*dyt[c]; 01981 STu[c] = texvec[c] + 0.5f*dyt[c]; 01982 } 01983 01984 // clear unused derivatives 01985 for(c=nr_channels; c<3; c++) { 01986 STc[c] = 0.0f; 01987 STl[c] = 0.0f; 01988 STr[c] = 0.0f; 01989 STd[c] = 0.0f; 01990 STu[c] = 0.0f; 01991 } 01992 01993 // use texres for the center sample, set rgbnor 01994 rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres); 01995 Hc = (fromrgb)? RGBTOBW(texres->tr, texres->tg, texres->tb) : texres->tin; 01996 01997 // use ttexr for the other taps 01998 multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr); 01999 Hl = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin; 02000 multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr); 02001 Hr = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin; 02002 multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr); 02003 Hd = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin; 02004 multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr); 02005 Hu = (fromrgb)? RGBTOBW(ttexr.tr, ttexr.tg, ttexr.tb) : ttexr.tin; 02006 02007 dHdx = Hscale*(Hr - Hl); 02008 dHdy = Hscale*(Hu - Hd); 02009 } 02010 02011 // restore pointer 02012 texres->nor = nvec; 02013 02014 /* replaced newbump with code based on listing 1 and 2 of 02015 [Mik10] Mikkelsen M. S.: Bump Mapping Unparametrized Surfaces on the GPU. 02016 -> http://jbit.net/~sparky/sfgrad_bump/mm_sfgrad_bump.pdf */ 02017 02018 if( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) 02019 iBumpSpace = 1; 02020 else if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) 02021 iBumpSpace = 2; 02022 else 02023 iBumpSpace = 4; // ViewSpace 02024 02025 if( ntap_bump->iPrevBumpSpace != iBumpSpace ) { 02026 02027 // initialize normal perturbation vectors 02028 int xyz; 02029 float fDet, abs_fDet, fMagnitude; 02030 // object2view and inverted matrix 02031 float obj2view[3][3], view2obj[3][3], tmp[4][4]; 02032 // local copies of derivatives and normal 02033 float dPdx[3], dPdy[3], vN[3]; 02034 VECCOPY(dPdx, shi->dxco); 02035 VECCOPY(dPdy, shi->dyco); 02036 VECCOPY(vN, ntap_bump->vNorg); 02037 02038 if( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) { 02039 // TODO: these calculations happen for every pixel! 02040 // -> move to shi->obi 02041 mul_m4_m4m4(tmp, shi->obr->ob->obmat, R.viewmat); 02042 copy_m3_m4(obj2view, tmp); // use only upper left 3x3 matrix 02043 invert_m3_m3(view2obj, obj2view); 02044 02045 // generate the surface derivatives in object space 02046 mul_m3_v3(view2obj, dPdx); 02047 mul_m3_v3( view2obj, dPdy ); 02048 // generate the unit normal in object space 02049 mul_transposed_m3_v3( obj2view, vN ); 02050 normalize_v3(vN); 02051 } 02052 02053 cross_v3_v3v3(ntap_bump->vR1, dPdy, vN); 02054 cross_v3_v3v3(ntap_bump->vR2, vN, dPdx); 02055 fDet = dot_v3v3(dPdx, ntap_bump->vR1); 02056 ntap_bump->sgn_det = (fDet < 0)? -1.0f: 1.0f; 02057 abs_fDet = ntap_bump->sgn_det * fDet; 02058 02059 if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { 02060 if(tex->ima) { 02061 // crazy hack solution that gives results similar to normal mapping - part 1 02062 normalize_v3(ntap_bump->vR1); 02063 normalize_v3(ntap_bump->vR2); 02064 abs_fDet = 1.0f; 02065 } 02066 } 02067 02068 fMagnitude = abs_fDet; 02069 if( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) { 02070 // pre do transform of texres->nor by the inverse transposed of obj2view 02071 mul_transposed_m3_v3( view2obj, vN ); 02072 mul_transposed_m3_v3( view2obj, ntap_bump->vR1 ); 02073 mul_transposed_m3_v3( view2obj, ntap_bump->vR2 ); 02074 02075 fMagnitude *= len_v3(vN); 02076 } 02077 02078 for(xyz=0; xyz<3; xyz++) 02079 ntap_bump->vNacc[xyz] *= fMagnitude / ntap_bump->fPrevMagnitude; 02080 02081 ntap_bump->fPrevMagnitude = fMagnitude; 02082 ntap_bump->iPrevBumpSpace = iBumpSpace; 02083 } 02084 02085 if( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) { 02086 if(tex->ima) { 02087 // crazy hack solution that gives results similar to normal mapping - part 2 02088 float vec[2]; 02089 02090 vec[0] = tex->ima->gen_x*dxt[0]; 02091 vec[1] = tex->ima->gen_y*dxt[1]; 02092 dHdx *= 1.0f/len_v2(vec); 02093 vec[0] = tex->ima->gen_x*dyt[0]; 02094 vec[1] = tex->ima->gen_y*dyt[1]; 02095 dHdy *= 1.0f/len_v2(vec); 02096 } 02097 } 02098 02099 // subtract the surface gradient from vNacc 02100 for(c=0; c<3; c++) { 02101 float vSurfGrad_compi = ntap_bump->sgn_det * (dHdx * ntap_bump->vR1[c] + dHdy * ntap_bump->vR2[c]); 02102 ntap_bump->vNacc[c] -= vSurfGrad_compi; 02103 texres->nor[c] = ntap_bump->vNacc[c]; // copy 02104 } 02105 02106 rgbnor |= TEX_NOR; 02107 return rgbnor; 02108 } 02109 02110 void do_material_tex(ShadeInput *shi) 02111 { 02112 CompatibleBump compat_bump; 02113 NTapBump ntap_bump; 02114 MTex *mtex; 02115 Tex *tex; 02116 TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; 02117 float *co = NULL, *dx = NULL, *dy = NULL; 02118 float fact, facm, factt, facmm, stencilTin=1.0; 02119 float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0; 02120 int tex_nr, rgbnor= 0, warpdone=0; 02121 int use_compat_bump = 0, use_ntap_bump = 0; 02122 int found_nmapping = 0; 02123 int iFirstTimeNMap=1; 02124 02125 compatible_bump_init(&compat_bump); 02126 ntap_bump_init(&ntap_bump); 02127 02128 if (R.r.scemode & R_NO_TEX) return; 02129 /* here: test flag if there's a tex (todo) */ 02130 02131 for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { 02132 02133 /* separate tex switching */ 02134 if(shi->mat->septex & (1<<tex_nr)) continue; 02135 02136 if(shi->mat->mtex[tex_nr]) { 02137 mtex= shi->mat->mtex[tex_nr]; 02138 02139 tex= mtex->tex; 02140 if(tex==0) continue; 02141 02142 use_compat_bump= (mtex->texflag & MTEX_COMPAT_BUMP); 02143 use_ntap_bump= (mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP)); 02144 02145 /* XXX texture node trees don't work for this yet */ 02146 if(tex->nodetree && tex->use_nodes) { 02147 use_compat_bump = 0; 02148 use_ntap_bump = 0; 02149 } 02150 02151 /* case displacement mapping */ 02152 if(shi->osatex==0 && use_ntap_bump) { 02153 use_ntap_bump = 0; 02154 use_compat_bump = 1; 02155 } 02156 02157 /* which coords */ 02158 if(mtex->texco==TEXCO_ORCO) { 02159 if(mtex->texflag & MTEX_DUPLI_MAPTO) { 02160 co= shi->duplilo; dx= dxt; dy= dyt; 02161 dxt[0]= dxt[1]= dxt[2]= 0.0f; 02162 dyt[0]= dyt[1]= dyt[2]= 0.0f; 02163 } 02164 else { 02165 co= shi->lo; dx= shi->dxlo; dy= shi->dylo; 02166 } 02167 } 02168 else if(mtex->texco==TEXCO_STICKY) { 02169 co= shi->sticky; dx= shi->dxsticky; dy= shi->dysticky; 02170 } 02171 else if(mtex->texco==TEXCO_OBJECT) { 02172 Object *ob= mtex->object; 02173 if(ob) { 02174 co= tempvec; 02175 dx= dxt; 02176 dy= dyt; 02177 VECCOPY(tempvec, shi->co); 02178 if(mtex->texflag & MTEX_OB_DUPLI_ORIG) 02179 if(shi->obi && shi->obi->duplitexmat) 02180 mul_m4_v3(shi->obi->duplitexmat, tempvec); 02181 mul_m4_v3(ob->imat_ren, tempvec); 02182 if(shi->osatex) { 02183 VECCOPY(dxt, shi->dxco); 02184 VECCOPY(dyt, shi->dyco); 02185 mul_mat3_m4_v3(ob->imat_ren, dxt); 02186 mul_mat3_m4_v3(ob->imat_ren, dyt); 02187 } 02188 } 02189 else { 02190 /* if object doesn't exist, do not use orcos (not initialized) */ 02191 co= shi->co; 02192 dx= shi->dxco; dy= shi->dyco; 02193 } 02194 } 02195 else if(mtex->texco==TEXCO_REFL) { 02196 calc_R_ref(shi); 02197 co= shi->ref; dx= shi->dxref; dy= shi->dyref; 02198 } 02199 else if(mtex->texco==TEXCO_NORM) { 02200 co= shi->orn; dx= shi->dxno; dy= shi->dyno; 02201 } 02202 else if(mtex->texco==TEXCO_TANGENT) { 02203 co= shi->tang; dx= shi->dxno; dy= shi->dyno; 02204 } 02205 else if(mtex->texco==TEXCO_GLOB) { 02206 co= shi->gl; dx= shi->dxgl; dy= shi->dygl; 02207 } 02208 else if(mtex->texco==TEXCO_UV) { 02209 if(mtex->texflag & MTEX_DUPLI_MAPTO) { 02210 co= shi->dupliuv; dx= dxt; dy= dyt; 02211 dxt[0]= dxt[1]= dxt[2]= 0.0f; 02212 dyt[0]= dyt[1]= dyt[2]= 0.0f; 02213 } 02214 else { 02215 ShadeInputUV *suv= &shi->uv[shi->actuv]; 02216 int i = shi->actuv; 02217 02218 if(mtex->uvname[0] != 0) { 02219 for(i = 0; i < shi->totuv; i++) { 02220 if(strcmp(shi->uv[i].name, mtex->uvname)==0) { 02221 suv= &shi->uv[i]; 02222 break; 02223 } 02224 } 02225 } 02226 02227 co= suv->uv; 02228 dx= suv->dxuv; 02229 dy= suv->dyuv; 02230 02231 compatible_bump_uv_derivs(&compat_bump, shi, mtex, i); 02232 } 02233 } 02234 else if(mtex->texco==TEXCO_WINDOW) { 02235 co= shi->winco; dx= shi->dxwin; dy= shi->dywin; 02236 } 02237 else if(mtex->texco==TEXCO_STRAND) { 02238 co= tempvec; dx= dxt; dy= dyt; 02239 co[0]= shi->strandco; 02240 co[1]= co[2]= 0.0f; 02241 dx[0]= shi->dxstrand; 02242 dx[1]= dx[2]= 0.0f; 02243 dy[0]= shi->dystrand; 02244 dy[1]= dy[2]= 0.0f; 02245 } 02246 else if(mtex->texco==TEXCO_STRESS) { 02247 co= tempvec; dx= dxt; dy= dyt; 02248 co[0]= shi->stress; 02249 co[1]= co[2]= 0.0f; 02250 dx[0]= 0.0f; 02251 dx[1]= dx[2]= 0.0f; 02252 dy[0]= 0.0f; 02253 dy[1]= dy[2]= 0.0f; 02254 } 02255 else continue; // can happen when texco defines disappear and it renders old files 02256 02257 /* the pointer defines if bumping happens */ 02258 if(mtex->mapto & (MAP_NORM|MAP_WARP)) { 02259 texres.nor= norvec; 02260 norvec[0]= norvec[1]= norvec[2]= 0.0; 02261 } 02262 else texres.nor= NULL; 02263 02264 if(warpdone) { 02265 VECADD(tempvec, co, warpvec); 02266 co= tempvec; 02267 } 02268 02269 /* XXX texture node trees don't work for this yet */ 02270 if(texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) { 02271 if(use_compat_bump) { 02272 rgbnor = compatible_bump_compute(&compat_bump, shi, mtex, tex, 02273 &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); 02274 } 02275 else if(use_ntap_bump) { 02276 rgbnor = ntap_bump_compute(&ntap_bump, shi, mtex, tex, 02277 &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); 02278 } 02279 else { 02280 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); 02281 rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres); 02282 } 02283 } 02284 else { 02285 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); 02286 rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres); 02287 } 02288 02289 /* texture output */ 02290 02291 if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { 02292 texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); 02293 rgbnor-= TEX_RGB; 02294 } 02295 if(mtex->texflag & MTEX_NEGATIVE) { 02296 if(rgbnor & TEX_RGB) { 02297 texres.tr= 1.0-texres.tr; 02298 texres.tg= 1.0-texres.tg; 02299 texres.tb= 1.0-texres.tb; 02300 } 02301 texres.tin= 1.0-texres.tin; 02302 } 02303 if(mtex->texflag & MTEX_STENCIL) { 02304 if(rgbnor & TEX_RGB) { 02305 fact= texres.ta; 02306 texres.ta*= stencilTin; 02307 stencilTin*= fact; 02308 } 02309 else { 02310 fact= texres.tin; 02311 texres.tin*= stencilTin; 02312 stencilTin*= fact; 02313 } 02314 } 02315 else { 02316 Tnor*= stencilTin; 02317 } 02318 02319 if(texres.nor) { 02320 if((rgbnor & TEX_NOR)==0) { 02321 /* make our own normal */ 02322 if(rgbnor & TEX_RGB) { 02323 texres.nor[0]= texres.tr; 02324 texres.nor[1]= texres.tg; 02325 texres.nor[2]= texres.tb; 02326 } 02327 else { 02328 float co_nor= 0.5*cos(texres.tin-0.5); 02329 float si= 0.5*sin(texres.tin-0.5); 02330 float f1, f2; 02331 02332 f1= shi->vn[0]; 02333 f2= shi->vn[1]; 02334 texres.nor[0]= f1*co_nor+f2*si; 02335 texres.nor[1]= f2*co_nor-f1*si; 02336 f1= shi->vn[1]; 02337 f2= shi->vn[2]; 02338 texres.nor[1]= f1*co_nor+f2*si; 02339 texres.nor[2]= f2*co_nor-f1*si; 02340 } 02341 } 02342 // warping, local space 02343 if(mtex->mapto & MAP_WARP) { 02344 float *warpnor= texres.nor, warpnor_[3]; 02345 02346 if(use_ntap_bump) { 02347 VECCOPY(warpnor_, texres.nor); 02348 warpnor= warpnor_; 02349 normalize_v3(warpnor_); 02350 } 02351 warpvec[0]= mtex->warpfac*warpnor[0]; 02352 warpvec[1]= mtex->warpfac*warpnor[1]; 02353 warpvec[2]= mtex->warpfac*warpnor[2]; 02354 warpdone= 1; 02355 } 02356 #if 0 02357 if(mtex->texflag & MTEX_VIEWSPACE) { 02358 // rotate to global coords 02359 if(mtex->texco==TEXCO_ORCO || mtex->texco==TEXCO_UV) { 02360 if(shi->vlr && shi->obr && shi->obr->ob) { 02361 float len= normalize_v3(texres.nor); 02362 // can be optimized... (ton) 02363 mul_mat3_m4_v3(shi->obr->ob->obmat, texres.nor); 02364 mul_mat3_m4_v3(R.viewmat, texres.nor); 02365 normalize_v3(texres.nor); 02366 mul_v3_fl(texres.nor, len); 02367 } 02368 } 02369 } 02370 #endif 02371 } 02372 02373 /* mapping */ 02374 if(mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { 02375 float tcol[3]; 02376 02377 /* stencil maps on the texture control slider, not texture intensity value */ 02378 02379 tcol[0]=texres.tr; tcol[1]=texres.tg; tcol[2]=texres.tb; 02380 02381 if((rgbnor & TEX_RGB)==0) { 02382 tcol[0]= mtex->r; 02383 tcol[1]= mtex->g; 02384 tcol[2]= mtex->b; 02385 } 02386 else if(mtex->mapto & MAP_ALPHA) { 02387 texres.tin= stencilTin; 02388 } 02389 else texres.tin= texres.ta; 02390 02391 /* inverse gamma correction */ 02392 if (tex->type==TEX_IMAGE) { 02393 Image *ima = tex->ima; 02394 ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); 02395 02396 /* don't linearize float buffers, assumed to be linear */ 02397 if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT) 02398 srgb_to_linearrgb_v3_v3(tcol, tcol); 02399 } 02400 02401 if(mtex->mapto & MAP_COL) { 02402 float colfac= mtex->colfac*stencilTin; 02403 texture_rgb_blend(&shi->r, tcol, &shi->r, texres.tin, colfac, mtex->blendtype); 02404 } 02405 if(mtex->mapto & MAP_COLSPEC) { 02406 float colspecfac= mtex->colspecfac*stencilTin; 02407 texture_rgb_blend(&shi->specr, tcol, &shi->specr, texres.tin, colspecfac, mtex->blendtype); 02408 } 02409 if(mtex->mapto & MAP_COLMIR) { 02410 float mirrfac= mtex->mirrfac*stencilTin; 02411 02412 // exception for envmap only 02413 if(tex->type==TEX_ENVMAP && mtex->blendtype==MTEX_BLEND) { 02414 fact= texres.tin*mirrfac; 02415 facm= 1.0- fact; 02416 shi->refcol[0]= fact + facm*shi->refcol[0]; 02417 shi->refcol[1]= fact*tcol[0] + facm*shi->refcol[1]; 02418 shi->refcol[2]= fact*tcol[1] + facm*shi->refcol[2]; 02419 shi->refcol[3]= fact*tcol[2] + facm*shi->refcol[3]; 02420 } 02421 else { 02422 texture_rgb_blend(&shi->mirr, tcol, &shi->mirr, texres.tin, mirrfac, mtex->blendtype); 02423 } 02424 } 02425 } 02426 if( (mtex->mapto & MAP_NORM) ) { 02427 if(texres.nor) { 02428 float norfac= mtex->norfac; 02429 02430 /* we need to code blending modes for normals too once.. now 1 exception hardcoded */ 02431 02432 if ((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP)) { 02433 02434 found_nmapping = 1; 02435 02436 /* qdn: for normalmaps, to invert the normalmap vector, 02437 it is better to negate x & y instead of subtracting the vector as was done before */ 02438 if (norfac < 0.0f) { 02439 texres.nor[0] = -texres.nor[0]; 02440 texres.nor[1] = -texres.nor[1]; 02441 } 02442 fact = Tnor*fabs(norfac); 02443 if (fact>1.f) fact = 1.f; 02444 facm = 1.f-fact; 02445 if(mtex->normapspace == MTEX_NSPACE_TANGENT) { 02446 /* qdn: tangent space */ 02447 float B[3], tv[3]; 02448 const float * no = iFirstTimeNMap!=0 ? shi->nmapnorm : shi->vn; 02449 iFirstTimeNMap=0; 02450 cross_v3_v3v3(B, no, shi->nmaptang); /* bitangent */ 02451 mul_v3_fl(B, shi->nmaptang[3]); 02452 /* transform norvec from tangent space to object surface in camera space */ 02453 tv[0] = texres.nor[0]*shi->nmaptang[0] + texres.nor[1]*B[0] + texres.nor[2]*no[0]; 02454 tv[1] = texres.nor[0]*shi->nmaptang[1] + texres.nor[1]*B[1] + texres.nor[2]*no[1]; 02455 tv[2] = texres.nor[0]*shi->nmaptang[2] + texres.nor[1]*B[2] + texres.nor[2]*no[2]; 02456 shi->vn[0]= facm*no[0] + fact*tv[0]; 02457 shi->vn[1]= facm*no[1] + fact*tv[1]; 02458 shi->vn[2]= facm*no[2] + fact*tv[2]; 02459 } 02460 else { 02461 float nor[3]; 02462 02463 VECCOPY(nor, texres.nor); 02464 02465 if(mtex->normapspace == MTEX_NSPACE_CAMERA); 02466 else if(mtex->normapspace == MTEX_NSPACE_WORLD) { 02467 mul_mat3_m4_v3(R.viewmat, nor); 02468 } 02469 else if(mtex->normapspace == MTEX_NSPACE_OBJECT) { 02470 if(shi->obr && shi->obr->ob) 02471 mul_mat3_m4_v3(shi->obr->ob->obmat, nor); 02472 mul_mat3_m4_v3(R.viewmat, nor); 02473 } 02474 02475 normalize_v3(nor); 02476 02477 /* qdn: worldspace */ 02478 shi->vn[0]= facm*shi->vn[0] + fact*nor[0]; 02479 shi->vn[1]= facm*shi->vn[1] + fact*nor[1]; 02480 shi->vn[2]= facm*shi->vn[2] + fact*nor[2]; 02481 } 02482 } 02483 else { 02484 /* XXX texture node trees don't work for this yet */ 02485 if (use_compat_bump || use_ntap_bump) { 02486 shi->vn[0] = texres.nor[0]; 02487 shi->vn[1] = texres.nor[1]; 02488 shi->vn[2] = texres.nor[2]; 02489 } 02490 else { 02491 float nor[3], dot; 02492 02493 if(shi->mat->mode & MA_TANGENT_V) { 02494 shi->tang[0]+= Tnor*norfac*texres.nor[0]; 02495 shi->tang[1]+= Tnor*norfac*texres.nor[1]; 02496 shi->tang[2]+= Tnor*norfac*texres.nor[2]; 02497 } 02498 02499 /* prevent bump to become negative normal */ 02500 nor[0]= Tnor*norfac*texres.nor[0]; 02501 nor[1]= Tnor*norfac*texres.nor[1]; 02502 nor[2]= Tnor*norfac*texres.nor[2]; 02503 02504 dot= 0.5f + 0.5f*INPR(nor, shi->vn); 02505 02506 shi->vn[0]+= dot*nor[0]; 02507 shi->vn[1]+= dot*nor[1]; 02508 shi->vn[2]+= dot*nor[2]; 02509 } 02510 } 02511 normalize_v3(shi->vn); 02512 02513 /* this makes sure the bump is passed on to the next texture */ 02514 shi->orn[0]= -shi->vn[0]; 02515 shi->orn[1]= -shi->vn[1]; 02516 shi->orn[2]= -shi->vn[2]; 02517 } 02518 } 02519 02520 if( mtex->mapto & MAP_DISPLACE ) { 02521 /* Now that most textures offer both Nor and Intensity, allow */ 02522 /* both to work, and let user select with slider. */ 02523 if(texres.nor) { 02524 float norfac= mtex->norfac; 02525 02526 shi->displace[0]+= 0.2f*Tnor*norfac*texres.nor[0]; 02527 shi->displace[1]+= 0.2f*Tnor*norfac*texres.nor[1]; 02528 shi->displace[2]+= 0.2f*Tnor*norfac*texres.nor[2]; 02529 } 02530 02531 if(rgbnor & TEX_RGB) { 02532 texres.tin= (0.35f*texres.tr+0.45f*texres.tg+0.2f*texres.tb); 02533 } 02534 02535 factt= (0.5f-texres.tin)*mtex->dispfac*stencilTin; facmm= 1.0f-factt; 02536 02537 if(mtex->blendtype==MTEX_BLEND) { 02538 shi->displace[0]= factt*shi->vn[0] + facmm*shi->displace[0]; 02539 shi->displace[1]= factt*shi->vn[1] + facmm*shi->displace[1]; 02540 shi->displace[2]= factt*shi->vn[2] + facmm*shi->displace[2]; 02541 } 02542 else if(mtex->blendtype==MTEX_MUL) { 02543 shi->displace[0]*= factt*shi->vn[0]; 02544 shi->displace[1]*= factt*shi->vn[1]; 02545 shi->displace[2]*= factt*shi->vn[2]; 02546 } 02547 else { /* add or sub */ 02548 if(mtex->blendtype==MTEX_SUB) factt= -factt; 02549 shi->displace[0]+= factt*shi->vn[0]; 02550 shi->displace[1]+= factt*shi->vn[1]; 02551 shi->displace[2]+= factt*shi->vn[2]; 02552 } 02553 } 02554 02555 if(mtex->mapto & MAP_VARS) { 02556 /* stencil maps on the texture control slider, not texture intensity value */ 02557 02558 if(rgbnor & TEX_RGB) { 02559 if(texres.talpha) texres.tin= texres.ta; 02560 else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); 02561 } 02562 02563 if(mtex->mapto & MAP_REF) { 02564 float difffac= mtex->difffac*stencilTin; 02565 02566 shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, difffac, mtex->blendtype); 02567 if(shi->refl<0.0) shi->refl= 0.0; 02568 } 02569 if(mtex->mapto & MAP_SPEC) { 02570 float specfac= mtex->specfac*stencilTin; 02571 02572 shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, specfac, mtex->blendtype); 02573 if(shi->spec<0.0) shi->spec= 0.0; 02574 } 02575 if(mtex->mapto & MAP_EMIT) { 02576 float emitfac= mtex->emitfac*stencilTin; 02577 02578 shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, emitfac, mtex->blendtype); 02579 if(shi->emit<0.0) shi->emit= 0.0; 02580 } 02581 if(mtex->mapto & MAP_ALPHA) { 02582 float alphafac= mtex->alphafac*stencilTin; 02583 02584 shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, alphafac, mtex->blendtype); 02585 if(shi->alpha<0.0) shi->alpha= 0.0; 02586 else if(shi->alpha>1.0) shi->alpha= 1.0; 02587 } 02588 if(mtex->mapto & MAP_HAR) { 02589 float har; // have to map to 0-1 02590 float hardfac= mtex->hardfac*stencilTin; 02591 02592 har= ((float)shi->har)/128.0; 02593 har= 128.0*texture_value_blend(mtex->def_var, har, texres.tin, hardfac, mtex->blendtype); 02594 02595 if(har<1.0) shi->har= 1; 02596 else if(har>511.0) shi->har= 511; 02597 else shi->har= (int)har; 02598 } 02599 if(mtex->mapto & MAP_RAYMIRR) { 02600 float raymirrfac= mtex->raymirrfac*stencilTin; 02601 02602 shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, raymirrfac, mtex->blendtype); 02603 if(shi->ray_mirror<0.0) shi->ray_mirror= 0.0; 02604 else if(shi->ray_mirror>1.0) shi->ray_mirror= 1.0; 02605 } 02606 if(mtex->mapto & MAP_TRANSLU) { 02607 float translfac= mtex->translfac*stencilTin; 02608 02609 shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, translfac, mtex->blendtype); 02610 if(shi->translucency<0.0) shi->translucency= 0.0; 02611 else if(shi->translucency>1.0) shi->translucency= 1.0; 02612 } 02613 if(mtex->mapto & MAP_AMB) { 02614 float ambfac= mtex->ambfac*stencilTin; 02615 02616 shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, ambfac, mtex->blendtype); 02617 if(shi->amb<0.0) shi->amb= 0.0; 02618 else if(shi->amb>1.0) shi->amb= 1.0; 02619 02620 shi->ambr= shi->amb*R.wrld.ambr; 02621 shi->ambg= shi->amb*R.wrld.ambg; 02622 shi->ambb= shi->amb*R.wrld.ambb; 02623 } 02624 } 02625 } 02626 } 02627 if ((use_compat_bump || use_ntap_bump || found_nmapping) && (shi->mat->mode & MA_TANGENT_V)!=0) { 02628 const float fnegdot = -dot_v3v3(shi->vn, shi->tang); 02629 // apply Gram-Schmidt projection 02630 madd_v3_v3fl(shi->tang, shi->vn, fnegdot); 02631 normalize_v3(shi->tang); 02632 } 02633 } 02634 02635 02636 void do_volume_tex(ShadeInput *shi, float *xyz, int mapto_flag, float *col, float *val) 02637 { 02638 MTex *mtex; 02639 Tex *tex; 02640 TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; 02641 int tex_nr, rgbnor= 0; 02642 float co[3], texvec[3]; 02643 float fact, stencilTin=1.0; 02644 02645 if (R.r.scemode & R_NO_TEX) return; 02646 /* here: test flag if there's a tex (todo) */ 02647 02648 for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { 02649 /* separate tex switching */ 02650 if(shi->mat->septex & (1<<tex_nr)) continue; 02651 02652 if(shi->mat->mtex[tex_nr]) { 02653 mtex= shi->mat->mtex[tex_nr]; 02654 tex= mtex->tex; 02655 if(tex==0) continue; 02656 02657 /* only process if this texture is mapped 02658 * to one that we're interested in */ 02659 if (!(mtex->mapto & mapto_flag)) continue; 02660 02661 /* which coords */ 02662 if(mtex->texco==TEXCO_OBJECT) { 02663 Object *ob= mtex->object; 02664 if(ob) { 02665 VECCOPY(co, xyz); 02666 if(mtex->texflag & MTEX_OB_DUPLI_ORIG) { 02667 if(shi->obi && shi->obi->duplitexmat) 02668 mul_m4_v3(shi->obi->duplitexmat, co); 02669 } 02670 mul_m4_v3(ob->imat_ren, co); 02671 } 02672 } 02673 /* not really orco, but 'local' */ 02674 else if(mtex->texco==TEXCO_ORCO) { 02675 02676 if(mtex->texflag & MTEX_DUPLI_MAPTO) { 02677 VECCOPY(co, shi->duplilo); 02678 } 02679 else { 02680 Object *ob= shi->obi->ob; 02681 VECCOPY(co, xyz); 02682 mul_m4_v3(ob->imat_ren, co); 02683 } 02684 } 02685 else if(mtex->texco==TEXCO_GLOB) { 02686 VECCOPY(co, xyz); 02687 mul_m4_v3(R.viewinv, co); 02688 } 02689 else continue; // can happen when texco defines disappear and it renders old files 02690 02691 texres.nor= NULL; 02692 02693 if(tex->type==TEX_IMAGE) { 02694 continue; /* not supported yet */ 02695 //do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); 02696 } 02697 else { 02698 /* placement */ 02699 if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]); 02700 else texvec[0]= mtex->size[0]*(mtex->ofs[0]); 02701 02702 if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]); 02703 else texvec[1]= mtex->size[1]*(mtex->ofs[1]); 02704 02705 if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]); 02706 else texvec[2]= mtex->size[2]*(mtex->ofs[2]); 02707 } 02708 02709 rgbnor= multitex(tex, texvec, NULL, NULL, 0, &texres, 0, mtex->which_output); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */ 02710 02711 /* texture output */ 02712 02713 if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) { 02714 texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); 02715 rgbnor-= TEX_RGB; 02716 } 02717 if(mtex->texflag & MTEX_NEGATIVE) { 02718 if(rgbnor & TEX_RGB) { 02719 texres.tr= 1.0-texres.tr; 02720 texres.tg= 1.0-texres.tg; 02721 texres.tb= 1.0-texres.tb; 02722 } 02723 texres.tin= 1.0-texres.tin; 02724 } 02725 if(mtex->texflag & MTEX_STENCIL) { 02726 if(rgbnor & TEX_RGB) { 02727 fact= texres.ta; 02728 texres.ta*= stencilTin; 02729 stencilTin*= fact; 02730 } 02731 else { 02732 fact= texres.tin; 02733 texres.tin*= stencilTin; 02734 stencilTin*= fact; 02735 } 02736 } 02737 02738 02739 if((mapto_flag & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL)) && (mtex->mapto & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL))) { 02740 float tcol[3]; 02741 02742 /* stencil maps on the texture control slider, not texture intensity value */ 02743 02744 if((rgbnor & TEX_RGB)==0) { 02745 tcol[0]= mtex->r; 02746 tcol[1]= mtex->g; 02747 tcol[2]= mtex->b; 02748 } else { 02749 tcol[0]=texres.tr; 02750 tcol[1]=texres.tg; 02751 tcol[2]=texres.tb; 02752 if(texres.talpha) 02753 texres.tin= texres.ta; 02754 } 02755 02756 /* used for emit */ 02757 if((mapto_flag & MAP_EMISSION_COL) && (mtex->mapto & MAP_EMISSION_COL)) { 02758 float colemitfac= mtex->colemitfac*stencilTin; 02759 texture_rgb_blend(col, tcol, col, texres.tin, colemitfac, mtex->blendtype); 02760 } 02761 02762 if((mapto_flag & MAP_REFLECTION_COL) && (mtex->mapto & MAP_REFLECTION_COL)) { 02763 float colreflfac= mtex->colreflfac*stencilTin; 02764 texture_rgb_blend(col, tcol, col, texres.tin, colreflfac, mtex->blendtype); 02765 } 02766 02767 if((mapto_flag & MAP_TRANSMISSION_COL) && (mtex->mapto & MAP_TRANSMISSION_COL)) { 02768 float coltransfac= mtex->coltransfac*stencilTin; 02769 texture_rgb_blend(col, tcol, col, texres.tin, coltransfac, mtex->blendtype); 02770 } 02771 } 02772 02773 if((mapto_flag & MAP_VARS) && (mtex->mapto & MAP_VARS)) { 02774 /* stencil maps on the texture control slider, not texture intensity value */ 02775 02776 /* convert RGB to intensity if intensity info isn't provided */ 02777 if (!(rgbnor & TEX_INT)) { 02778 if (rgbnor & TEX_RGB) { 02779 if(texres.talpha) texres.tin= texres.ta; 02780 else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); 02781 } 02782 } 02783 02784 if((mapto_flag & MAP_EMISSION) && (mtex->mapto & MAP_EMISSION)) { 02785 float emitfac= mtex->emitfac*stencilTin; 02786 02787 *val = texture_value_blend(mtex->def_var, *val, texres.tin, emitfac, mtex->blendtype); 02788 if(*val<0.0) *val= 0.0; 02789 } 02790 if((mapto_flag & MAP_DENSITY) && (mtex->mapto & MAP_DENSITY)) { 02791 float densfac= mtex->densfac*stencilTin; 02792 02793 *val = texture_value_blend(mtex->def_var, *val, texres.tin, densfac, mtex->blendtype); 02794 CLAMP(*val, 0.0, 1.0); 02795 } 02796 if((mapto_flag & MAP_SCATTERING) && (mtex->mapto & MAP_SCATTERING)) { 02797 float scatterfac= mtex->scatterfac*stencilTin; 02798 02799 *val = texture_value_blend(mtex->def_var, *val, texres.tin, scatterfac, mtex->blendtype); 02800 CLAMP(*val, 0.0, 1.0); 02801 } 02802 if((mapto_flag & MAP_REFLECTION) && (mtex->mapto & MAP_REFLECTION)) { 02803 float reflfac= mtex->reflfac*stencilTin; 02804 02805 *val = texture_value_blend(mtex->def_var, *val, texres.tin, reflfac, mtex->blendtype); 02806 CLAMP(*val, 0.0, 1.0); 02807 } 02808 } 02809 } 02810 } 02811 } 02812 02813 02814 /* ------------------------------------------------------------------------- */ 02815 02816 void do_halo_tex(HaloRen *har, float xn, float yn, float *colf) 02817 { 02818 MTex *mtex; 02819 TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; 02820 float texvec[3], dxt[3], dyt[3], fact, facm, dx; 02821 int rgb, osatex; 02822 02823 if (R.r.scemode & R_NO_TEX) return; 02824 02825 mtex= har->mat->mtex[0]; 02826 if(har->mat->septex & (1<<0)) return; 02827 if(mtex->tex==NULL) return; 02828 02829 /* no normal mapping */ 02830 texres.nor= NULL; 02831 02832 texvec[0]= xn/har->rad; 02833 texvec[1]= yn/har->rad; 02834 texvec[2]= 0.0; 02835 02836 osatex= (har->mat->texco & TEXCO_OSA); 02837 02838 /* placement */ 02839 if(mtex->projx) texvec[0]= mtex->size[0]*(texvec[mtex->projx-1]+mtex->ofs[0]); 02840 else texvec[0]= mtex->size[0]*(mtex->ofs[0]); 02841 02842 if(mtex->projy) texvec[1]= mtex->size[1]*(texvec[mtex->projy-1]+mtex->ofs[1]); 02843 else texvec[1]= mtex->size[1]*(mtex->ofs[1]); 02844 02845 if(mtex->projz) texvec[2]= mtex->size[2]*(texvec[mtex->projz-1]+mtex->ofs[2]); 02846 else texvec[2]= mtex->size[2]*(mtex->ofs[2]); 02847 02848 if(osatex) { 02849 02850 dx= 1.0/har->rad; 02851 02852 if(mtex->projx) { 02853 dxt[0]= mtex->size[0]*dx; 02854 dyt[0]= mtex->size[0]*dx; 02855 } 02856 else dxt[0]= dyt[0]= 0.0; 02857 02858 if(mtex->projy) { 02859 dxt[1]= mtex->size[1]*dx; 02860 dyt[1]= mtex->size[1]*dx; 02861 } 02862 else dxt[1]= dyt[1]= 0.0; 02863 02864 if(mtex->projz) { 02865 dxt[2]= 0.0; 02866 dyt[2]= 0.0; 02867 } 02868 else dxt[2]= dyt[2]= 0.0; 02869 02870 } 02871 02872 if(mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); 02873 02874 rgb= multitex(mtex->tex, texvec, dxt, dyt, osatex, &texres, 0, mtex->which_output); 02875 02876 /* texture output */ 02877 if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { 02878 texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); 02879 rgb= 0; 02880 } 02881 if(mtex->texflag & MTEX_NEGATIVE) { 02882 if(rgb) { 02883 texres.tr= 1.0-texres.tr; 02884 texres.tg= 1.0-texres.tg; 02885 texres.tb= 1.0-texres.tb; 02886 } 02887 else texres.tin= 1.0-texres.tin; 02888 } 02889 02890 /* mapping */ 02891 if(mtex->mapto & MAP_COL) { 02892 02893 if(rgb==0) { 02894 texres.tr= mtex->r; 02895 texres.tg= mtex->g; 02896 texres.tb= mtex->b; 02897 } 02898 else if(mtex->mapto & MAP_ALPHA) { 02899 texres.tin= 1.0; 02900 } 02901 else texres.tin= texres.ta; 02902 02903 /* inverse gamma correction */ 02904 if (mtex->tex->type==TEX_IMAGE) { 02905 Image *ima = mtex->tex->ima; 02906 ImBuf *ibuf = BKE_image_get_ibuf(ima, &mtex->tex->iuser); 02907 02908 /* don't linearize float buffers, assumed to be linear */ 02909 if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT) 02910 srgb_to_linearrgb_v3_v3(&texres.tr, &texres.tr); 02911 } 02912 02913 fact= texres.tin*mtex->colfac; 02914 facm= 1.0-fact; 02915 02916 if(mtex->blendtype==MTEX_MUL) { 02917 facm= 1.0-mtex->colfac; 02918 } 02919 02920 if(mtex->blendtype==MTEX_SUB) fact= -fact; 02921 02922 if(mtex->blendtype==MTEX_BLEND) { 02923 colf[0]= (fact*texres.tr + facm*har->r); 02924 colf[1]= (fact*texres.tg + facm*har->g); 02925 colf[2]= (fact*texres.tb + facm*har->b); 02926 } 02927 else if(mtex->blendtype==MTEX_MUL) { 02928 colf[0]= (facm+fact*texres.tr)*har->r; 02929 colf[1]= (facm+fact*texres.tg)*har->g; 02930 colf[2]= (facm+fact*texres.tb)*har->b; 02931 } 02932 else { 02933 colf[0]= (fact*texres.tr + har->r); 02934 colf[1]= (fact*texres.tg + har->g); 02935 colf[2]= (fact*texres.tb + har->b); 02936 02937 CLAMP(colf[0], 0.0, 1.0); 02938 CLAMP(colf[1], 0.0, 1.0); 02939 CLAMP(colf[2], 0.0, 1.0); 02940 } 02941 } 02942 if(mtex->mapto & MAP_ALPHA) { 02943 if(rgb) { 02944 if(texres.talpha) texres.tin= texres.ta; 02945 else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); 02946 } 02947 02948 colf[3]*= texres.tin; 02949 } 02950 } 02951 02952 /* ------------------------------------------------------------------------- */ 02953 02954 /* hor and zen are RGB vectors, blend is 1 float, should all be initialized */ 02955 void do_sky_tex(float *rco, float *lo, float *dxyview, float *hor, float *zen, float *blend, int skyflag, short thread) 02956 { 02957 MTex *mtex; 02958 Tex *tex; 02959 TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; 02960 float *co, fact, stencilTin=1.0; 02961 float tempvec[3], texvec[3], dxt[3], dyt[3]; 02962 int tex_nr, rgb= 0, ok; 02963 02964 if (R.r.scemode & R_NO_TEX) return; 02965 /* todo: add flag to test if there's a tex */ 02966 texres.nor= NULL; 02967 02968 for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) { 02969 if(R.wrld.mtex[tex_nr]) { 02970 mtex= R.wrld.mtex[tex_nr]; 02971 02972 tex= mtex->tex; 02973 if(tex==0) continue; 02974 /* if(mtex->mapto==0) continue; */ 02975 02976 /* which coords */ 02977 co= lo; 02978 02979 /* dxt dyt just from 1 value */ 02980 if(dxyview) { 02981 dxt[0]= dxt[1]= dxt[2]= dxyview[0]; 02982 dyt[0]= dyt[1]= dyt[2]= dxyview[1]; 02983 } 02984 else { 02985 dxt[0]= dxt[1]= dxt[2]= 0.0; 02986 dyt[0]= dyt[1]= dyt[2]= 0.0; 02987 } 02988 02989 /* Grab the mapping settings for this texture */ 02990 switch(mtex->texco) { 02991 case TEXCO_ANGMAP: 02992 /* only works with texture being "real" */ 02993 /* use saacos(), fixes bug [#22398], float precision caused lo[2] to be slightly less then -1.0 */ 02994 if(lo[0] || lo[1]) { /* check for zero case [#24807] */ 02995 fact= (1.0/M_PI)*saacos(lo[2])/(sqrt(lo[0]*lo[0] + lo[1]*lo[1])); 02996 tempvec[0]= lo[0]*fact; 02997 tempvec[1]= lo[1]*fact; 02998 tempvec[2]= 0.0; 02999 } 03000 else { 03001 /* this value has no angle, the vector is directly along the view. 03002 * avoide divide by zero and use a dummy value. */ 03003 tempvec[0]= 1.0f; 03004 tempvec[1]= 0.0; 03005 tempvec[2]= 0.0; 03006 } 03007 co= tempvec; 03008 break; 03009 03010 case TEXCO_H_SPHEREMAP: 03011 case TEXCO_H_TUBEMAP: 03012 if(skyflag & WO_ZENUP) { 03013 if(mtex->texco==TEXCO_H_TUBEMAP) map_to_tube( tempvec, tempvec+1,lo[0], lo[2], lo[1]); 03014 else map_to_sphere( tempvec, tempvec+1,lo[0], lo[2], lo[1]); 03015 /* tube/spheremap maps for outside view, not inside */ 03016 tempvec[0]= 1.0-tempvec[0]; 03017 /* only top half */ 03018 tempvec[1]= 2.0*tempvec[1]-1.0; 03019 tempvec[2]= 0.0; 03020 /* and correction for do_2d_mapping */ 03021 tempvec[0]= 2.0*tempvec[0]-1.0; 03022 tempvec[1]= 2.0*tempvec[1]-1.0; 03023 co= tempvec; 03024 } 03025 else { 03026 /* potentially dangerous... check with multitex! */ 03027 continue; 03028 } 03029 break; 03030 case TEXCO_OBJECT: 03031 if(mtex->object) { 03032 VECCOPY(tempvec, lo); 03033 mul_m4_v3(mtex->object->imat_ren, tempvec); 03034 co= tempvec; 03035 } 03036 break; 03037 03038 case TEXCO_GLOB: 03039 if(rco) { 03040 VECCOPY(tempvec, rco); 03041 mul_m4_v3(R.viewinv, tempvec); 03042 co= tempvec; 03043 } 03044 else 03045 co= lo; 03046 03047 // VECCOPY(shi->dxgl, shi->dxco); 03048 // mul_m3_v3(R.imat, shi->dxco); 03049 // VECCOPY(shi->dygl, shi->dyco); 03050 // mul_m3_v3(R.imat, shi->dyco); 03051 break; 03052 } 03053 03054 /* placement */ 03055 if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]); 03056 else texvec[0]= mtex->size[0]*(mtex->ofs[0]); 03057 03058 if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]); 03059 else texvec[1]= mtex->size[1]*(mtex->ofs[1]); 03060 03061 if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]); 03062 else texvec[2]= mtex->size[2]*(mtex->ofs[2]); 03063 03064 /* texture */ 03065 if(tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); 03066 03067 rgb= multitex(mtex->tex, texvec, dxt, dyt, R.osa, &texres, thread, mtex->which_output); 03068 03069 /* texture output */ 03070 if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { 03071 texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); 03072 rgb= 0; 03073 } 03074 if(mtex->texflag & MTEX_NEGATIVE) { 03075 if(rgb) { 03076 texres.tr= 1.0-texres.tr; 03077 texres.tg= 1.0-texres.tg; 03078 texres.tb= 1.0-texres.tb; 03079 } 03080 else texres.tin= 1.0-texres.tin; 03081 } 03082 if(mtex->texflag & MTEX_STENCIL) { 03083 if(rgb) { 03084 fact= texres.ta; 03085 texres.ta*= stencilTin; 03086 stencilTin*= fact; 03087 } 03088 else { 03089 fact= texres.tin; 03090 texres.tin*= stencilTin; 03091 stencilTin*= fact; 03092 } 03093 } 03094 else { 03095 if(rgb) texres.ta *= stencilTin; 03096 else texres.tin*= stencilTin; 03097 } 03098 03099 /* color mapping */ 03100 if(mtex->mapto & (WOMAP_HORIZ+WOMAP_ZENUP+WOMAP_ZENDOWN)) { 03101 float tcol[3]; 03102 03103 if(rgb==0) { 03104 texres.tr= mtex->r; 03105 texres.tg= mtex->g; 03106 texres.tb= mtex->b; 03107 } 03108 else texres.tin= texres.ta; 03109 03110 tcol[0]= texres.tr; tcol[1]= texres.tg; tcol[2]= texres.tb; 03111 03112 /* inverse gamma correction */ 03113 if (tex->type==TEX_IMAGE) { 03114 Image *ima = tex->ima; 03115 ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); 03116 03117 /* don't linearize float buffers, assumed to be linear */ 03118 if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT) 03119 srgb_to_linearrgb_v3_v3(tcol, tcol); 03120 } 03121 03122 if(mtex->mapto & WOMAP_HORIZ) { 03123 texture_rgb_blend(hor, tcol, hor, texres.tin, mtex->colfac, mtex->blendtype); 03124 } 03125 if(mtex->mapto & (WOMAP_ZENUP+WOMAP_ZENDOWN)) { 03126 ok= 0; 03127 if(R.wrld.skytype & WO_SKYREAL) { 03128 if((skyflag & WO_ZENUP)) { 03129 if(mtex->mapto & WOMAP_ZENUP) ok= 1; 03130 } 03131 else if(mtex->mapto & WOMAP_ZENDOWN) ok= 1; 03132 } 03133 else ok= 1; 03134 03135 if(ok) { 03136 texture_rgb_blend(zen, tcol, zen, texres.tin, mtex->colfac, mtex->blendtype); 03137 } 03138 } 03139 } 03140 if(mtex->mapto & WOMAP_BLEND) { 03141 if(rgb) texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); 03142 03143 *blend= texture_value_blend(mtex->def_var, *blend, texres.tin, mtex->blendfac, mtex->blendtype); 03144 } 03145 } 03146 } 03147 } 03148 03149 /* ------------------------------------------------------------------------- */ 03150 /* colf supposed to be initialized with la->r,g,b */ 03151 03152 void do_lamp_tex(LampRen *la, float *lavec, ShadeInput *shi, float *colf, int effect) 03153 { 03154 Object *ob; 03155 MTex *mtex; 03156 Tex *tex; 03157 TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL}; 03158 float *co = NULL, *dx = NULL, *dy = NULL, fact, stencilTin=1.0; 03159 float texvec[3], dxt[3], dyt[3], tempvec[3]; 03160 int i, tex_nr, rgb= 0; 03161 03162 if (R.r.scemode & R_NO_TEX) return; 03163 tex_nr= 0; 03164 03165 for(; tex_nr<MAX_MTEX; tex_nr++) { 03166 03167 if(la->mtex[tex_nr]) { 03168 mtex= la->mtex[tex_nr]; 03169 03170 tex= mtex->tex; 03171 if(tex==NULL) continue; 03172 texres.nor= NULL; 03173 03174 /* which coords */ 03175 if(mtex->texco==TEXCO_OBJECT) { 03176 ob= mtex->object; 03177 if(ob) { 03178 co= tempvec; 03179 dx= dxt; 03180 dy= dyt; 03181 VECCOPY(tempvec, shi->co); 03182 mul_m4_v3(ob->imat_ren, tempvec); 03183 if(shi->osatex) { 03184 VECCOPY(dxt, shi->dxco); 03185 VECCOPY(dyt, shi->dyco); 03186 mul_mat3_m4_v3(ob->imat_ren, dxt); 03187 mul_mat3_m4_v3(ob->imat_ren, dyt); 03188 } 03189 } 03190 else { 03191 co= shi->co; 03192 dx= shi->dxco; dy= shi->dyco; 03193 } 03194 } 03195 else if(mtex->texco==TEXCO_GLOB) { 03196 co= shi->gl; dx= shi->dxco; dy= shi->dyco; 03197 VECCOPY(shi->gl, shi->co); 03198 mul_m4_v3(R.viewinv, shi->gl); 03199 } 03200 else if(mtex->texco==TEXCO_VIEW) { 03201 03202 VECCOPY(tempvec, lavec); 03203 mul_m3_v3(la->imat, tempvec); 03204 03205 if(la->type==LA_SPOT) { 03206 tempvec[0]*= la->spottexfac; 03207 tempvec[1]*= la->spottexfac; 03208 /* project from 3d to 2d */ 03209 tempvec[0] /= -tempvec[2]; 03210 tempvec[1] /= -tempvec[2]; 03211 } 03212 co= tempvec; 03213 03214 dx= dxt; dy= dyt; 03215 if(shi->osatex) { 03216 VECCOPY(dxt, shi->dxlv); 03217 VECCOPY(dyt, shi->dylv); 03218 /* need some matrix conversion here? la->imat is a [3][3] matrix!!! **/ 03219 mul_m3_v3(la->imat, dxt); 03220 mul_m3_v3(la->imat, dyt); 03221 03222 mul_v3_fl(dxt, la->spottexfac); 03223 mul_v3_fl(dyt, la->spottexfac); 03224 } 03225 } 03226 03227 03228 /* placement */ 03229 if(mtex->projx && co) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]); 03230 else texvec[0]= mtex->size[0]*(mtex->ofs[0]); 03231 03232 if(mtex->projy && co) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]); 03233 else texvec[1]= mtex->size[1]*(mtex->ofs[1]); 03234 03235 if(mtex->projz && co) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]); 03236 else texvec[2]= mtex->size[2]*(mtex->ofs[2]); 03237 03238 if(shi->osatex) { 03239 if (!dx) { 03240 for(i=0;i<2;i++) { 03241 dxt[i] = dyt[i] = 0.0; 03242 } 03243 } else { 03244 if(mtex->projx) { 03245 dxt[0]= mtex->size[0]*dx[mtex->projx-1]; 03246 dyt[0]= mtex->size[0]*dy[mtex->projx-1]; 03247 } else { 03248 dxt[0]= 0.0; 03249 dyt[0]= 0.0; 03250 } 03251 if(mtex->projy) { 03252 dxt[1]= mtex->size[1]*dx[mtex->projy-1]; 03253 dyt[1]= mtex->size[1]*dy[mtex->projy-1]; 03254 } else { 03255 dxt[1]= 0.0; 03256 dyt[1]= 0.0; 03257 } 03258 if(mtex->projz) { 03259 dxt[2]= mtex->size[2]*dx[mtex->projz-1]; 03260 dyt[2]= mtex->size[2]*dy[mtex->projz-1]; 03261 } else { 03262 dxt[2]= 0.0; 03263 dyt[2]= 0.0; 03264 } 03265 } 03266 } 03267 03268 /* texture */ 03269 if(tex->type==TEX_IMAGE) { 03270 do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); 03271 } 03272 03273 rgb= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output); 03274 03275 /* texture output */ 03276 if(rgb && (mtex->texflag & MTEX_RGBTOINT)) { 03277 texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb); 03278 rgb= 0; 03279 } 03280 if(mtex->texflag & MTEX_NEGATIVE) { 03281 if(rgb) { 03282 texres.tr= 1.0-texres.tr; 03283 texres.tg= 1.0-texres.tg; 03284 texres.tb= 1.0-texres.tb; 03285 } 03286 else texres.tin= 1.0-texres.tin; 03287 } 03288 if(mtex->texflag & MTEX_STENCIL) { 03289 if(rgb) { 03290 fact= texres.ta; 03291 texres.ta*= stencilTin; 03292 stencilTin*= fact; 03293 } 03294 else { 03295 fact= texres.tin; 03296 texres.tin*= stencilTin; 03297 stencilTin*= fact; 03298 } 03299 } 03300 else { 03301 if(rgb) texres.ta*= stencilTin; 03302 else texres.tin*= stencilTin; 03303 } 03304 03305 /* mapping */ 03306 if(((mtex->mapto & LAMAP_COL) && (effect & LA_TEXTURE))||((mtex->mapto & LAMAP_SHAD) && (effect & LA_SHAD_TEX))) { 03307 float col[3]; 03308 03309 if(rgb==0) { 03310 texres.tr= mtex->r; 03311 texres.tg= mtex->g; 03312 texres.tb= mtex->b; 03313 } 03314 else if(mtex->mapto & MAP_ALPHA) { 03315 texres.tin= stencilTin; 03316 } 03317 else texres.tin= texres.ta; 03318 03319 /* inverse gamma correction */ 03320 if (tex->type==TEX_IMAGE) { 03321 Image *ima = tex->ima; 03322 ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); 03323 03324 /* don't linearize float buffers, assumed to be linear */ 03325 if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT) 03326 srgb_to_linearrgb_v3_v3(&texres.tr, &texres.tr); 03327 } 03328 03329 /* lamp colors were premultiplied with this */ 03330 col[0]= texres.tr*la->energy; 03331 col[1]= texres.tg*la->energy; 03332 col[2]= texres.tb*la->energy; 03333 03334 texture_rgb_blend(colf, col, colf, texres.tin, mtex->colfac, mtex->blendtype); 03335 } 03336 } 03337 } 03338 } 03339 03340 /* ------------------------------------------------------------------------- */ 03341 03342 int externtex(MTex *mtex, float *vec, float *tin, float *tr, float *tg, float *tb, float *ta, const int thread) 03343 { 03344 Tex *tex; 03345 TexResult texr; 03346 float dxt[3], dyt[3], texvec[3]; 03347 int rgb; 03348 03349 tex= mtex->tex; 03350 if(tex==NULL) return 0; 03351 texr.nor= NULL; 03352 03353 /* placement */ 03354 if(mtex->projx) texvec[0]= mtex->size[0]*(vec[mtex->projx-1]+mtex->ofs[0]); 03355 else texvec[0]= mtex->size[0]*(mtex->ofs[0]); 03356 03357 if(mtex->projy) texvec[1]= mtex->size[1]*(vec[mtex->projy-1]+mtex->ofs[1]); 03358 else texvec[1]= mtex->size[1]*(mtex->ofs[1]); 03359 03360 if(mtex->projz) texvec[2]= mtex->size[2]*(vec[mtex->projz-1]+mtex->ofs[2]); 03361 else texvec[2]= mtex->size[2]*(mtex->ofs[2]); 03362 03363 /* texture */ 03364 if(tex->type==TEX_IMAGE) { 03365 do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt); 03366 } 03367 03368 rgb= multitex(tex, texvec, dxt, dyt, 0, &texr, thread, mtex->which_output); 03369 03370 if(rgb) { 03371 texr.tin= (0.35*texr.tr+0.45*texr.tg+0.2*texr.tb); 03372 } 03373 else { 03374 texr.tr= mtex->r; 03375 texr.tg= mtex->g; 03376 texr.tb= mtex->b; 03377 } 03378 03379 *tin= texr.tin; 03380 *tr= texr.tr; 03381 *tg= texr.tg; 03382 *tb= texr.tb; 03383 *ta= texr.ta; 03384 03385 return (rgb != 0); 03386 } 03387 03388 03389 /* ------------------------------------------------------------------------- */ 03390 03391 void render_realtime_texture(ShadeInput *shi, Image *ima) 03392 { 03393 TexResult texr; 03394 static Tex imatex[BLENDER_MAX_THREADS]; // threadsafe 03395 static int firsttime= 1; 03396 Tex *tex; 03397 float texvec[3], dx[2], dy[2]; 03398 ShadeInputUV *suv= &shi->uv[shi->actuv]; 03399 int a; 03400 03401 if(R.r.scemode & R_NO_TEX) return; 03402 03403 if(firsttime) { 03404 BLI_lock_thread(LOCK_IMAGE); 03405 if(firsttime) { 03406 for(a=0; a<BLENDER_MAX_THREADS; a++) { 03407 memset(&imatex[a], 0, sizeof(Tex)); 03408 default_tex(&imatex[a]); 03409 imatex[a].type= TEX_IMAGE; 03410 } 03411 03412 firsttime= 0; 03413 } 03414 BLI_unlock_thread(LOCK_IMAGE); 03415 } 03416 03417 tex= &imatex[shi->thread]; 03418 tex->iuser.ok= ima->ok; 03419 03420 texvec[0]= 0.5+0.5*suv->uv[0]; 03421 texvec[1]= 0.5+0.5*suv->uv[1]; 03422 texvec[2] = 0; // initalize it because imagewrap looks at it. 03423 if(shi->osatex) { 03424 dx[0]= 0.5*suv->dxuv[0]; 03425 dx[1]= 0.5*suv->dxuv[1]; 03426 dy[0]= 0.5*suv->dyuv[0]; 03427 dy[1]= 0.5*suv->dyuv[1]; 03428 } 03429 03430 texr.nor= NULL; 03431 03432 if(shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr); 03433 else imagewrap(tex, ima, NULL, texvec, &texr); 03434 03435 shi->vcol[0]*= texr.tr; 03436 shi->vcol[1]*= texr.tg; 03437 shi->vcol[2]*= texr.tb; 03438 shi->vcol[3]*= texr.ta; 03439 } 03440 03441 /* eof */