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