2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19 * All rights reserved.
21 * Contributor(s): 2004-2006, Blender Foundation, full recode
23 * ***** END GPL LICENSE BLOCK *****
26 /** \file blender/render/intern/source/render_texture.c
36 #include "BLI_blenlib.h"
39 #include "BLI_utildefines.h"
41 #include "DNA_anim_types.h"
42 #include "DNA_texture_types.h"
43 #include "DNA_object_types.h"
44 #include "DNA_lamp_types.h"
45 #include "DNA_mesh_types.h"
46 #include "DNA_meshdata_types.h"
47 #include "DNA_material_types.h"
48 #include "DNA_image_types.h"
49 #include "DNA_node_types.h"
51 #include "IMB_imbuf_types.h"
52 #include "IMB_imbuf.h"
54 #include "BKE_colortools.h"
55 #include "BKE_image.h"
57 #include "BKE_plugin_types.h"
59 #include "BKE_animsys.h"
60 #include "BKE_DerivedMesh.h"
61 #include "BKE_global.h"
63 #include "BKE_material.h"
64 #include "BKE_scene.h"
66 #include "BKE_library.h"
67 #include "BKE_image.h"
68 #include "BKE_texture.h"
72 #include "MEM_guardedalloc.h"
75 #include "pointdensity.h"
76 #include "voxeldata.h"
77 #include "renderpipeline.h"
78 #include "render_types.h"
79 #include "rendercore.h"
82 #include "texture_ocean.h"
84 #include "renderdatabase.h" /* needed for UV */
86 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
87 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
88 /* only to be used here in this file, it's for speed */
89 extern struct Render R;
90 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
95 static void init_render_texture(Render *re, Tex *tex)
97 int cfra= re->scene->r.cfra;
99 if (re) cfra= re->r.cfra;
102 if (tex->ima && ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
103 BKE_image_user_frame_calc(&tex->iuser, cfra, re?re->flag & R_SEC_FIELD:0);
106 if (tex->type==TEX_PLUGIN) {
107 if (tex->plugin && tex->plugin->doit) {
108 if (tex->plugin->cfra) {
109 *(tex->plugin->cfra)= (float)cfra; //BKE_scene_frame_get(re->scene); // XXX old animsys - timing stuff to be fixed
113 else if (tex->type==TEX_ENVMAP) {
115 tex->imaflag |= TEX_INTERPOL | TEX_MIPMAP;
116 tex->extend= TEX_CLIP;
119 if (tex->env->type==ENV_PLANE)
120 tex->extend= TEX_EXTEND;
122 /* only free envmap when rendermode was set to render envmaps, for previewrender */
123 if (G.rendering && re) {
124 if (re->r.mode & R_ENVMAP)
125 if (tex->env->stype==ENV_ANIM)
126 BKE_free_envmapdata(tex->env);
131 if (tex->nodetree && tex->use_nodes) {
132 ntreeTexBeginExecTree(tex->nodetree, 1); /* has internal flag to detect it only does it once */
136 /* ------------------------------------------------------------------------- */
138 void init_render_textures(Render *re)
142 tex= re->main->tex.first;
144 if (tex->id.us) init_render_texture(re, tex);
149 static void end_render_texture(Tex *tex)
151 if (tex && tex->use_nodes && tex->nodetree && tex->nodetree->execdata)
152 ntreeTexEndExecTree(tex->nodetree->execdata, 1);
155 void end_render_textures(Render *re)
158 for (tex= re->main->tex.first; tex; tex= tex->id.next)
160 end_render_texture(tex);
163 /* ------------------------------------------------------------------------- */
166 /* this allows colorbanded textures to control normals as well */
167 static void tex_normal_derivate(Tex *tex, TexResult *texres)
169 if (tex->flag & TEX_COLORBAND) {
171 if (do_colorband(tex->coba, texres->tin, col)) {
172 float fac0, fac1, fac2, fac3;
174 fac0= (col[0]+col[1]+col[2]);
175 do_colorband(tex->coba, texres->nor[0], col);
176 fac1= (col[0]+col[1]+col[2]);
177 do_colorband(tex->coba, texres->nor[1], col);
178 fac2= (col[0]+col[1]+col[2]);
179 do_colorband(tex->coba, texres->nor[2], col);
180 fac3= (col[0]+col[1]+col[2]);
182 texres->nor[0]= 0.3333f*(fac0 - fac1);
183 texres->nor[1]= 0.3333f*(fac0 - fac2);
184 texres->nor[2]= 0.3333f*(fac0 - fac3);
189 texres->nor[0]= texres->tin - texres->nor[0];
190 texres->nor[1]= texres->tin - texres->nor[1];
191 texres->nor[2]= texres->tin - texres->nor[2];
196 static int blend(Tex *tex, float *texvec, TexResult *texres)
200 if (tex->flag & TEX_FLIPBLEND) {
209 if (tex->stype==TEX_LIN) { /* lin */
210 texres->tin= (1.0f+x)/2.0f;
212 else if (tex->stype==TEX_QUAD) { /* quad */
213 texres->tin= (1.0f+x)/2.0f;
214 if (texres->tin<0.0f) texres->tin= 0.0f;
215 else texres->tin*= texres->tin;
217 else if (tex->stype==TEX_EASE) { /* ease */
218 texres->tin= (1.0f+x)/2.0f;
219 if (texres->tin<=0.0f) texres->tin= 0.0f;
220 else if (texres->tin>=1.0f) texres->tin= 1.0f;
222 t= texres->tin*texres->tin;
223 texres->tin= (3.0f*t-2.0f*t*texres->tin);
226 else if (tex->stype==TEX_DIAG) { /* diag */
227 texres->tin= (2.0f+x+y)/4.0f;
229 else if (tex->stype==TEX_RAD) { /* radial */
230 texres->tin= (atan2(y, x) / (2*M_PI) + 0.5);
232 else { /* sphere TEX_SPHERE */
233 texres->tin= 1.0-sqrt(x*x+ y*y+texvec[2]*texvec[2]);
234 if (texres->tin<0.0f) texres->tin= 0.0f;
235 if (tex->stype==TEX_HALO) texres->tin*= texres->tin; /* halo */
243 /* ------------------------------------------------------------------------- */
244 /* ************************************************************************* */
246 /* newnoise: all noisebased types now have different noisebases to choose from */
248 static int clouds(Tex *tex, float *texvec, TexResult *texres)
252 texres->tin = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
254 if (texres->nor!=NULL) {
255 // calculate bumpnormal
256 texres->nor[0] = BLI_gTurbulence(tex->noisesize, texvec[0] + tex->nabla, texvec[1], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
257 texres->nor[1] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1] + tex->nabla, texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
258 texres->nor[2] = BLI_gTurbulence(tex->noisesize, texvec[0], texvec[1], texvec[2] + tex->nabla, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
260 tex_normal_derivate(tex, texres);
264 if (tex->stype==TEX_COLOR) {
265 // in this case, int. value should really be computed from color,
266 // and bumpnormal from that, would be too slow, looks ok as is
267 texres->tr = texres->tin;
268 texres->tg = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[0], texvec[2], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
269 texres->tb = BLI_gTurbulence(tex->noisesize, texvec[1], texvec[2], texvec[0], tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
272 return (rv | TEX_RGB);
281 /* creates a sine wave */
282 static float tex_sin(float a)
284 a = 0.5 + 0.5*sin(a);
289 /* creates a saw wave */
290 static float tex_saw(float a)
292 const float b = 2*M_PI;
294 int n = (int)(a / b);
300 /* creates a triangle wave */
301 static float tex_tri(float a)
303 const float b = 2*M_PI;
304 const float rmax = 1.0;
306 a = rmax - 2.0f*fabsf(floorf((a*(1.0f/b))+0.5f) - (a*(1.0f/b)));
311 /* computes basic wood intensity value at x,y,z */
312 static float wood_int(Tex *tex, float x, float y, float z)
315 short wf = tex->noisebasis2; /* wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2 */
316 short wt = tex->stype; /* wood type: TEX_BAND=0, TEX_RING=1, TEX_BANDNOISE=2, TEX_RINGNOISE=3 */
318 float (*waveform[3])(float); /* create array of pointers to waveform functions */
319 waveform[0] = tex_sin; /* assign address of tex_sin() function to pointer array */
320 waveform[1] = tex_saw;
321 waveform[2] = tex_tri;
323 if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 is initialized ahead of time */
326 wi = waveform[wf]((x + y + z)*10.0f);
328 else if (wt==TEX_RING) {
329 wi = waveform[wf](sqrtf(x*x + y*y + z*z)*20.0f);
331 else if (wt==TEX_BANDNOISE) {
332 wi = tex->turbul*BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
333 wi = waveform[wf]((x + y + z)*10.0f + wi);
335 else if (wt==TEX_RINGNOISE) {
336 wi = tex->turbul*BLI_gNoise(tex->noisesize, x, y, z, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
337 wi = waveform[wf](sqrtf(x*x + y*y + z*z)*20.0f + wi);
343 static int wood(Tex *tex, float *texvec, TexResult *texres)
347 texres->tin = wood_int(tex, texvec[0], texvec[1], texvec[2]);
348 if (texres->nor!=NULL) {
349 /* calculate bumpnormal */
350 texres->nor[0] = wood_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]);
351 texres->nor[1] = wood_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]);
352 texres->nor[2] = wood_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla);
354 tex_normal_derivate(tex, texres);
363 /* computes basic marble intensity at x,y,z */
364 static float marble_int(Tex *tex, float x, float y, float z)
367 short wf = tex->noisebasis2; /* wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2 */
368 short mt = tex->stype; /* marble type: TEX_SOFT=0, TEX_SHARP=1,TEX_SHAPER=2 */
370 float (*waveform[3])(float); /* create array of pointers to waveform functions */
371 waveform[0] = tex_sin; /* assign address of tex_sin() function to pointer array */
372 waveform[1] = tex_saw;
373 waveform[2] = tex_tri;
375 if ((wf>TEX_TRI) || (wf<TEX_SIN)) wf=0; /* check to be sure noisebasis2 isn't initialized ahead of time */
377 n = 5.0f * (x + y + z);
379 mi = n + tex->turbul * BLI_gTurbulence(tex->noisesize, x, y, z, tex->noisedepth, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
381 if (mt>=TEX_SOFT) { /* TEX_SOFT always true */
382 mi = waveform[wf](mi);
386 else if (mt==TEX_SHARPER) {
394 static int marble(Tex *tex, float *texvec, TexResult *texres)
398 texres->tin = marble_int(tex, texvec[0], texvec[1], texvec[2]);
400 if (texres->nor!=NULL) {
401 /* calculate bumpnormal */
402 texres->nor[0] = marble_int(tex, texvec[0] + tex->nabla, texvec[1], texvec[2]);
403 texres->nor[1] = marble_int(tex, texvec[0], texvec[1] + tex->nabla, texvec[2]);
404 texres->nor[2] = marble_int(tex, texvec[0], texvec[1], texvec[2] + tex->nabla);
406 tex_normal_derivate(tex, texres);
416 /* ------------------------------------------------------------------------- */
418 static int magic(Tex *tex, float *texvec, TexResult *texres)
420 float x, y, z, turb=1.0;
424 turb= tex->turbul/5.0f;
426 x= sin( ( texvec[0]+texvec[1]+texvec[2])*5.0f );
427 y= cos( (-texvec[0]+texvec[1]-texvec[2])*5.0f );
428 z= -cos( (-texvec[0]-texvec[1]+texvec[2])*5.0f );
479 texres->tr = 0.5f - x;
480 texres->tg = 0.5f - y;
481 texres->tb = 0.5f - z;
483 texres->tin= (1.0f / 3.0f) * (texres->tr + texres->tg + texres->tb);
491 /* ------------------------------------------------------------------------- */
493 /* newnoise: stucci also modified to use different noisebasis */
494 static int stucci(Tex *tex, float *texvec, TexResult *texres)
496 float nor[3], b2, ofs;
499 b2= BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
501 ofs= tex->turbul/200.0f;
503 if (tex->stype) ofs*=(b2*b2);
504 nor[0] = BLI_gNoise(tex->noisesize, texvec[0]+ofs, texvec[1], texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
505 nor[1] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1]+ofs, texvec[2], (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
506 nor[2] = BLI_gNoise(tex->noisesize, texvec[0], texvec[1], texvec[2]+ofs, (tex->noisetype!=TEX_NOISESOFT), tex->noisebasis);
512 copy_v3_v3(texres->nor, nor);
513 tex_normal_derivate(tex, texres);
515 if (tex->stype==TEX_WALLOUT) {
516 texres->nor[0]= -texres->nor[0];
517 texres->nor[1]= -texres->nor[1];
518 texres->nor[2]= -texres->nor[2];
524 if (tex->stype==TEX_WALLOUT)
525 texres->tin= 1.0f-texres->tin;
527 if (texres->tin<0.0f)
533 /* ------------------------------------------------------------------------- */
534 /* newnoise: musgrave terrain noise types */
536 static float mg_mFractalOrfBmTex(Tex *tex, float *texvec, TexResult *texres)
539 float (*mgravefunc)(float, float, float, float, float, float, int);
541 if (tex->stype==TEX_MFRACTAL)
542 mgravefunc = mg_MultiFractal;
546 texres->tin = tex->ns_outscale*mgravefunc(texvec[0], texvec[1], texvec[2], tex->mg_H, tex->mg_lacunarity, tex->mg_octaves, tex->noisebasis);
548 if (texres->nor!=NULL) {
549 float offs= tex->nabla/tex->noisesize; // also scaling of texvec
551 /* calculate bumpnormal */
552 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);
553 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);
554 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);
556 tex_normal_derivate(tex, texres);
566 static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec, TexResult *texres)
569 float (*mgravefunc)(float, float, float, float, float, float, float, float, int);
571 if (tex->stype==TEX_RIDGEDMF)
572 mgravefunc = mg_RidgedMultiFractal;
574 mgravefunc = mg_HybridMultiFractal;
576 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);
578 if (texres->nor!=NULL) {
579 float offs= tex->nabla/tex->noisesize; // also scaling of texvec
581 /* calculate bumpnormal */
582 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);
583 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);
584 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);
586 tex_normal_derivate(tex, texres);
597 static float mg_HTerrainTex(Tex *tex, float *texvec, TexResult *texres)
601 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);
603 if (texres->nor!=NULL) {
604 float offs= tex->nabla/tex->noisesize; // also scaling of texvec
606 /* calculate bumpnormal */
607 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);
608 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);
609 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);
611 tex_normal_derivate(tex, texres);
622 static float mg_distNoiseTex(Tex *tex, float *texvec, TexResult *texres)
626 texres->tin = mg_VLNoise(texvec[0], texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
628 if (texres->nor!=NULL) {
629 float offs= tex->nabla/tex->noisesize; // also scaling of texvec
631 /* calculate bumpnormal */
632 texres->nor[0] = mg_VLNoise(texvec[0] + offs, texvec[1], texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
633 texres->nor[1] = mg_VLNoise(texvec[0], texvec[1] + offs, texvec[2], tex->dist_amount, tex->noisebasis, tex->noisebasis2);
634 texres->nor[2] = mg_VLNoise(texvec[0], texvec[1], texvec[2] + offs, tex->dist_amount, tex->noisebasis, tex->noisebasis2);
636 tex_normal_derivate(tex, texres);
648 /* ------------------------------------------------------------------------- */
649 /* newnoise: Voronoi texture type, probably the slowest, especially with minkovsky, bumpmapping, could be done another way */
651 static float voronoiTex(Tex *tex, float *texvec, TexResult *texres)
654 float da[4], pa[12]; /* distance and point coordinate arrays of 4 nearest neighbors */
655 float aw1 = fabs(tex->vn_w1);
656 float aw2 = fabs(tex->vn_w2);
657 float aw3 = fabs(tex->vn_w3);
658 float aw4 = fabs(tex->vn_w4);
659 float sc = (aw1 + aw2 + aw3 + aw4);
660 if (sc!=0.f) sc = tex->ns_outscale/sc;
662 voronoi(texvec[0], texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm);
663 texres->tin = sc * fabsf(tex->vn_w1*da[0] + tex->vn_w2*da[1] + tex->vn_w3*da[2] + tex->vn_w4*da[3]);
665 if (tex->vn_coltype) {
666 float ca[3]; /* cell color */
667 cellNoiseV(pa[0], pa[1], pa[2], ca);
668 texres->tr = aw1*ca[0];
669 texres->tg = aw1*ca[1];
670 texres->tb = aw1*ca[2];
671 cellNoiseV(pa[3], pa[4], pa[5], ca);
672 texres->tr += aw2*ca[0];
673 texres->tg += aw2*ca[1];
674 texres->tb += aw2*ca[2];
675 cellNoiseV(pa[6], pa[7], pa[8], ca);
676 texres->tr += aw3*ca[0];
677 texres->tg += aw3*ca[1];
678 texres->tb += aw3*ca[2];
679 cellNoiseV(pa[9], pa[10], pa[11], ca);
680 texres->tr += aw4*ca[0];
681 texres->tg += aw4*ca[1];
682 texres->tb += aw4*ca[2];
683 if (tex->vn_coltype>=2) {
684 float t1 = (da[1]-da[0])*10;
686 if (tex->vn_coltype==3) t1*=texres->tin; else t1*=sc;
698 if (texres->nor!=NULL) {
699 float offs= tex->nabla/tex->noisesize; // also scaling of texvec
701 /* calculate bumpnormal */
702 voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, tex->vn_mexp, tex->vn_distm);
703 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]);
704 voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, tex->vn_mexp, tex->vn_distm);
705 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]);
706 voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, tex->vn_mexp, tex->vn_distm);
707 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]);
709 tex_normal_derivate(tex, texres);
713 if (tex->vn_coltype) {
716 return (rv | TEX_RGB);
725 /* ------------------------------------------------------------------------- */
727 static int texnoise(Tex *tex, TexResult *texres)
735 loop= tex->noisedepth;
742 texres->tin= ((float)val)/div;
748 /* ------------------------------------------------------------------------- */
750 static int plugintex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
754 float result[8]= {0.0f};
759 if (pit && pit->doit) {
761 if (pit->version < 6) {
762 copy_v3_v3(pit->result+5, texres->nor);
765 copy_v3_v3(result+5, texres->nor);
768 if (pit->version < 6) {
769 if (osatex) rgbnor= ((TexDoitold)pit->doit)(tex->stype,
770 pit->data, texvec, dxt, dyt);
771 else rgbnor= ((TexDoitold)pit->doit)(tex->stype,
772 pit->data, texvec, NULL, NULL);
775 if (osatex) rgbnor= ((TexDoit)pit->doit)(tex->stype,
776 pit->data, texvec, dxt, dyt, result);
777 else rgbnor= ((TexDoit)pit->doit)(tex->stype,
778 pit->data, texvec, NULL, NULL, result);
781 if (pit->version < 6) {
782 texres->tin = pit->result[0];
785 texres->tin = result[0]; /* XXX, assigning garbage value, fixme! */
788 if (rgbnor & TEX_NOR) {
790 if (pit->version < 6) {
791 copy_v3_v3(texres->nor, pit->result+5);
794 copy_v3_v3(texres->nor, result+5);
799 if (rgbnor & TEX_RGB) {
800 if (pit->version < 6) {
801 copy_v4_v4(&texres->tr, pit->result + 1);
804 copy_v4_v4(&texres->tr, result + 1);
817 static int cubemap_glob(const float n[3], float x, float y, float z, float *adr1, float *adr2)
819 float x1, y1, z1, nor[3];
823 nor[0]= x; nor[1]= y; nor[2]= z; // use local render coord
828 mul_mat3_m4_v3(R.viewinv, nor);
834 if (z1>=x1 && z1>=y1) {
835 *adr1 = (x + 1.0f) / 2.0f;
836 *adr2 = (y + 1.0f) / 2.0f;
839 else if (y1>=x1 && y1>=z1) {
840 *adr1 = (x + 1.0f) / 2.0f;
841 *adr2 = (z + 1.0f) / 2.0f;
845 *adr1 = (y + 1.0f) / 2.0f;
846 *adr2 = (z + 1.0f) / 2.0f;
852 /* ------------------------------------------------------------------------- */
854 /* mtex argument only for projection switches */
855 static int cubemap(MTex *mtex, VlakRen *vlr, const float n[3], float x, float y, float z, float *adr1, float *adr2)
857 int proj[4]={0, ME_PROJXY, ME_PROJXZ, ME_PROJYZ}, ret= 0;
862 /* Mesh vertices have such flags, for others we calculate it once based on orco */
863 if ((vlr->puno & (ME_PROJXY|ME_PROJXZ|ME_PROJYZ))==0) {
864 /* test for v1, vlr can be faked for baking */
865 if (vlr->v1 && vlr->v1->orco) {
867 normal_tri_v3(nor, vlr->v1->orco, vlr->v2->orco, vlr->v3->orco);
869 if ( fabs(nor[0])<fabs(nor[2]) && fabs(nor[1])<fabs(nor[2]) ) vlr->puno |= ME_PROJXY;
870 else if ( fabs(nor[0])<fabs(nor[1]) && fabs(nor[2])<fabs(nor[1]) ) vlr->puno |= ME_PROJXZ;
871 else vlr->puno |= ME_PROJYZ;
873 else return cubemap_glob(n, x, y, z, adr1, adr2);
877 /* the mtex->proj{xyz} have type char. maybe this should be wider? */
878 /* casting to int ensures that the index type is right. */
879 index = (int) mtex->projx;
880 proj[index]= ME_PROJXY;
882 index = (int) mtex->projy;
883 proj[index]= ME_PROJXZ;
885 index = (int) mtex->projz;
886 proj[index]= ME_PROJYZ;
889 if (vlr->puno & proj[1]) {
890 *adr1 = (x + 1.0f) / 2.0f;
891 *adr2 = (y + 1.0f) / 2.0f;
893 else if (vlr->puno & proj[2]) {
894 *adr1 = (x + 1.0f) / 2.0f;
895 *adr2 = (z + 1.0f) / 2.0f;
899 *adr1 = (y + 1.0f) / 2.0f;
900 *adr2 = (z + 1.0f) / 2.0f;
905 return cubemap_glob(n, x, y, z, adr1, adr2);
911 /* ------------------------------------------------------------------------- */
913 static int cubemap_ob(Object *ob, const float n[3], float x, float y, float z, float *adr1, float *adr2)
915 float x1, y1, z1, nor[3];
918 if (n==NULL) return 0;
921 if (ob) mul_mat3_m4_v3(ob->imat, nor);
927 if (z1>=x1 && z1>=y1) {
928 *adr1 = (x + 1.0f) / 2.0f;
929 *adr2 = (y + 1.0f) / 2.0f;
932 else if (y1>=x1 && y1>=z1) {
933 *adr1 = (x + 1.0f) / 2.0f;
934 *adr2 = (z + 1.0f) / 2.0f;
938 *adr1 = (y + 1.0f) / 2.0f;
939 *adr2 = (z + 1.0f) / 2.0f;
945 /* ------------------------------------------------------------------------- */
947 static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], float *dxt, float *dyt)
951 float fx, fy, fac1, area[8];
952 int ok, proj, areaflag= 0, wrap, texco;
954 /* mtex variables localized, only cubemap doesn't cooperate yet... */
962 if (wrap==MTEX_FLAT) {
963 fx = (t[0] + 1.0f) / 2.0f;
964 fy = (t[1] + 1.0f) / 2.0f;
966 else if (wrap==MTEX_TUBE) map_to_tube( &fx, &fy, t[0], t[1], t[2]);
967 else if (wrap==MTEX_SPHERE) map_to_sphere(&fx, &fy, t[0], t[1], t[2]);
969 if (texco==TEXCO_OBJECT) cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy);
970 else if (texco==TEXCO_GLOB) cubemap_glob(n, t[0], t[1], t[2], &fx, &fy);
971 else cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy);
975 if (tex->extend==TEX_REPEAT) {
976 if (tex->xrepeat>1) {
977 float origf= fx *= tex->xrepeat;
979 if (fx>1.0f) fx -= (int)(fx);
980 else if (fx<0.0f) fx+= 1-(int)(fx);
982 if (tex->flag & TEX_REPEAT_XMIR) {
983 int orig= (int)floor(origf);
988 if (tex->yrepeat>1) {
989 float origf= fy *= tex->yrepeat;
991 if (fy>1.0f) fy -= (int)(fy);
992 else if (fy<0.0f) fy+= 1-(int)(fy);
994 if (tex->flag & TEX_REPEAT_YMIR) {
995 int orig= (int)floor(origf);
1002 if (tex->cropxmin!=0.0f || tex->cropxmax!=1.0f) {
1003 fac1= tex->cropxmax - tex->cropxmin;
1004 fx= tex->cropxmin+ fx*fac1;
1006 if (tex->cropymin!=0.0f || tex->cropymax!=1.0f) {
1007 fac1= tex->cropymax - tex->cropymin;
1008 fy= tex->cropymin+ fy*fac1;
1016 if (wrap==MTEX_FLAT) {
1017 fx= (t[0] + 1.0f) / 2.0f;
1018 fy= (t[1] + 1.0f) / 2.0f;
1026 else if (ELEM(wrap, MTEX_TUBE, MTEX_SPHERE)) {
1027 /* exception: the seam behind (y<0.0) */
1032 if (fx>=0.0f && fy>=0.0f && t[0]>=0.0f);
1033 else if (fx<=0.0f && fy<=0.0f && t[0]<=0.0f);
1037 if (wrap==MTEX_TUBE) {
1038 map_to_tube(area, area+1, t[0], t[1], t[2]);
1039 map_to_tube(area + 2, area + 3, t[0] + dxt[0], t[1] + dxt[1], t[2] + dxt[2]);
1040 map_to_tube(area + 4, area + 5, t[0] + dyt[0], t[1] + dyt[1], t[2] + dyt[2]);
1043 map_to_sphere(area, area+1, t[0], t[1], t[2]);
1044 map_to_sphere(area + 2, area + 3, t[0] + dxt[0], t[1] + dxt[1], t[2] + dxt[2]);
1045 map_to_sphere(area + 4, area + 5, t[0] + dyt[0], t[1] + dyt[1], t[2] + dyt[2]);
1050 if (wrap==MTEX_TUBE) map_to_tube( &fx, &fy, t[0], t[1], t[2]);
1051 else map_to_sphere(&fx, &fy, t[0], t[1], t[2]);
1060 if (texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy);
1061 else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, t[0], t[1], t[2], &fx, &fy);
1062 else proj = cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy);
1065 SWAP(float, dxt[1], dxt[2]);
1066 SWAP(float, dyt[1], dyt[2]);
1069 float f1= dxt[0], f2= dyt[0];
1088 /* if area, then reacalculate dxt[] and dyt[] */
1099 if (tex->extend==TEX_REPEAT) {
1101 if (tex->xrepeat>1) {
1102 float origf= fx *= tex->xrepeat;
1104 // TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call
1105 if (tex->texfilter == TXF_BOX) {
1106 if (fx>1.0f) fx -= (int)(fx);
1107 else if (fx<0.0f) fx+= 1-(int)(fx);
1109 if (tex->flag & TEX_REPEAT_XMIR) {
1110 int orig= (int)floor(origf);
1118 dxt[0]*= tex->xrepeat;
1119 dyt[0]*= tex->xrepeat;
1121 if (tex->yrepeat>1) {
1122 float origf= fy *= tex->yrepeat;
1124 // TXF: omit mirror here, see comments in do_material_tex() after do_2d_mapping() call
1125 if (tex->texfilter == TXF_BOX) {
1126 if (fy>1.0f) fy -= (int)(fy);
1127 else if (fy<0.0f) fy+= 1-(int)(fy);
1129 if (tex->flag & TEX_REPEAT_YMIR) {
1130 int orig= (int)floor(origf);
1136 if (max<tex->yrepeat)
1139 dxt[1]*= tex->yrepeat;
1140 dyt[1]*= tex->yrepeat;
1149 if (tex->cropxmin!=0.0f || tex->cropxmax!=1.0f) {
1150 fac1= tex->cropxmax - tex->cropxmin;
1151 fx= tex->cropxmin+ fx*fac1;
1155 if (tex->cropymin!=0.0f || tex->cropymax!=1.0f) {
1156 fac1= tex->cropymax - tex->cropymin;
1157 fy= tex->cropymin+ fy*fac1;
1168 /* ************************************** */
1170 static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output)
1173 int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */
1175 texres->talpha= 0; /* is set when image texture returns alpha (considered premul) */
1177 if (tex->use_nodes && tex->nodetree) {
1178 retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread,
1179 tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL);
1182 switch (tex->type) {
1188 retval= clouds(tex, texvec, texres);
1191 retval= wood(tex, texvec, texres);
1194 retval= marble(tex, texvec, texres);
1197 retval= magic(tex, texvec, texres);
1200 retval= blend(tex, texvec, texres);
1203 retval= stucci(tex, texvec, texres);
1206 retval= texnoise(tex, texres);
1209 if (osatex) retval= imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres);
1210 else retval= imagewrap(tex, tex->ima, NULL, texvec, texres);
1211 BKE_image_tag_time(tex->ima); /* tag image as having being used */
1214 retval= plugintex(tex, texvec, dxt, dyt, osatex, texres);
1217 retval= envmaptex(tex, texvec, dxt, dyt, osatex, texres);
1220 /* newnoise: musgrave types */
1222 /* ton: added this, for Blender convention reason.
1223 * artificer: added the use of tmpvec to avoid scaling texvec
1225 copy_v3_v3(tmpvec, texvec);
1226 mul_v3_fl(tmpvec, 1.0f/tex->noisesize);
1228 switch (tex->stype) {
1231 retval= mg_mFractalOrfBmTex(tex, tmpvec, texres);
1235 retval= mg_ridgedOrHybridMFTex(tex, tmpvec, texres);
1238 retval= mg_HTerrainTex(tex, tmpvec, texres);
1242 /* newnoise: voronoi type */
1244 /* ton: added this, for Blender convention reason.
1245 * artificer: added the use of tmpvec to avoid scaling texvec
1247 copy_v3_v3(tmpvec, texvec);
1248 mul_v3_fl(tmpvec, 1.0f/tex->noisesize);
1250 retval= voronoiTex(tex, tmpvec, texres);
1253 /* ton: added this, for Blender convention reason.
1254 * artificer: added the use of tmpvec to avoid scaling texvec
1256 copy_v3_v3(tmpvec, texvec);
1257 mul_v3_fl(tmpvec, 1.0f/tex->noisesize);
1259 retval= mg_distNoiseTex(tex, tmpvec, texres);
1261 case TEX_POINTDENSITY:
1262 retval= pointdensitytex(tex, texvec, texres);
1265 retval= voxeldatatex(tex, texvec, texres);
1268 retval= ocean_texture(tex, texvec, texres);
1272 if (tex->flag & TEX_COLORBAND) {
1274 if (do_colorband(tex->coba, texres->tin, col)) {
1286 /* this is called from the shader and texture nodes */
1287 int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output, ShadeInput *shi, MTex *mtex)
1290 memset(texres, 0, sizeof(TexResult));
1295 which_output= mtex->which_output;
1297 if (tex->type==TEX_IMAGE) {
1301 /* we have mtex, use it for 2d mapping images only */
1302 do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt);
1303 rgbnor= multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output);
1305 if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
1306 ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
1308 /* don't linearize float buffers, assumed to be linear */
1309 if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
1310 srgb_to_linearrgb_v3_v3(&texres->tr, &texres->tr);
1314 /* we don't have mtex, do default flat 2d projection */
1316 float texvec_l[3], dxt_l[3], dyt_l[3];
1318 localmtex.mapping= MTEX_FLAT;
1320 localmtex.object= NULL;
1321 localmtex.texco= TEXCO_ORCO;
1323 copy_v3_v3(texvec_l, texvec);
1325 copy_v3_v3(dxt_l, dxt);
1326 copy_v3_v3(dyt_l, dyt);
1333 do_2d_mapping(&localmtex, texvec_l, NULL, NULL, dxt_l, dyt_l);
1334 rgbnor= multitex(tex, texvec_l, dxt_l, dyt_l, osatex, texres, thread, which_output);
1340 return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output);
1343 /* this is called for surface shading */
1344 int multitex_mtex(ShadeInput *shi, MTex *mtex, float *texvec, float *dxt, float *dyt, TexResult *texres)
1346 Tex *tex= mtex->tex;
1348 if (tex->use_nodes && tex->nodetree) {
1349 /* stupid exception here .. but we have to pass shi and mtex to
1350 * textures nodes for 2d mapping and color management for images */
1351 return ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, shi->osatex, shi->thread,
1352 tex, mtex->which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, shi, mtex);
1355 return multitex(mtex->tex, texvec, dxt, dyt, shi->osatex, texres, shi->thread, mtex->which_output);
1358 /* Warning, if the texres's values are not declared zero, check the return value to be sure
1359 * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */
1360 int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres)
1362 return multitex_nodes(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL);
1365 /* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on) */
1366 int multitex_ext_safe(Tex *tex, float *texvec, TexResult *texres)
1368 int use_nodes= tex->use_nodes, retval;
1370 tex->use_nodes = FALSE;
1371 retval= multitex_nodes(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL);
1372 tex->use_nodes= use_nodes;
1378 /* ------------------------------------------------------------------------- */
1380 /* in = destination, tex = texture, out = previous color */
1381 /* fact = texture strength, facg = button strength value */
1382 void texture_rgb_blend(float in[3], const float tex[3], const float out[3], float fact, float facg, int blendtype)
1386 switch (blendtype) {
1391 in[0]= (fact*tex[0] + facm*out[0]);
1392 in[1]= (fact*tex[1] + facm*out[1]);
1393 in[2]= (fact*tex[2] + facm*out[2]);
1399 in[0]= (facm+fact*tex[0])*out[0];
1400 in[1]= (facm+fact*tex[1])*out[1];
1401 in[2]= (facm+fact*tex[2])*out[2];
1407 in[0]= 1.0f - (facm+fact*(1.0f-tex[0])) * (1.0f-out[0]);
1408 in[1]= 1.0f - (facm+fact*(1.0f-tex[1])) * (1.0f-out[1]);
1409 in[2]= 1.0f - (facm+fact*(1.0f-tex[2])) * (1.0f-out[2]);
1417 in[0] = out[0] * (facm + 2.0f*fact*tex[0]);
1419 in[0] = 1.0f - (facm + 2.0f*fact*(1.0f - tex[0])) * (1.0f - out[0]);
1421 in[1] = out[1] * (facm + 2.0f*fact*tex[1]);
1423 in[1] = 1.0f - (facm + 2.0f*fact*(1.0f - tex[1])) * (1.0f - out[1]);
1425 in[2] = out[2] * (facm + 2.0f*fact*tex[2]);
1427 in[2] = 1.0f - (facm + 2.0f*fact*(1.0f - tex[2])) * (1.0f - out[2]);
1434 in[0]= (fact*tex[0] + out[0]);
1435 in[1]= (fact*tex[1] + out[1]);
1436 in[2]= (fact*tex[2] + out[2]);
1444 in[0]= facm*out[0] + fact*out[0]/tex[0];
1446 in[1]= facm*out[1] + fact*out[1]/tex[1];
1448 in[2]= facm*out[2] + fact*out[2]/tex[2];
1455 in[0]= facm*out[0] + fact*fabsf(tex[0]-out[0]);
1456 in[1]= facm*out[1] + fact*fabsf(tex[1]-out[1]);
1457 in[2]= facm*out[2] + fact*fabsf(tex[2]-out[2]);
1464 col= tex[0]+((1-tex[0])*facm);
1465 if (col < out[0]) in[0]= col; else in[0]= out[0];
1466 col= tex[1]+((1-tex[1])*facm);
1467 if (col < out[1]) in[1]= col; else in[1]= out[1];
1468 col= tex[2]+((1-tex[2])*facm);
1469 if (col < out[2]) in[2]= col; else in[2]= out[2];
1476 if (col > out[0]) in[0]= col; else in[0]= out[0];
1478 if (col > out[1]) in[1]= col; else in[1]= out[1];
1480 if (col > out[2]) in[2]= col; else in[2]= out[2];
1483 case MTEX_BLEND_HUE:
1485 copy_v3_v3(in, out);
1486 ramp_blend(MA_RAMP_HUE, in, fact, tex);
1488 case MTEX_BLEND_SAT:
1490 copy_v3_v3(in, out);
1491 ramp_blend(MA_RAMP_SAT, in, fact, tex);
1493 case MTEX_BLEND_VAL:
1495 copy_v3_v3(in, out);
1496 ramp_blend(MA_RAMP_VAL, in, fact, tex);
1498 case MTEX_BLEND_COLOR:
1500 copy_v3_v3(in, out);
1501 ramp_blend(MA_RAMP_COLOR, in, fact, tex);
1503 case MTEX_SOFT_LIGHT:
1505 copy_v3_v3(in, out);
1506 ramp_blend(MA_RAMP_SOFT, in, fact, tex);
1508 case MTEX_LIN_LIGHT:
1510 copy_v3_v3(in, out);
1511 ramp_blend(MA_RAMP_LINEAR, in, fact, tex);
1516 float texture_value_blend(float tex, float out, float fact, float facg, int blendtype)
1518 float in=0.0, facm, col, scf;
1519 int flip= (facg < 0.0f);
1525 if (flip) SWAP(float, fact, facm);
1527 switch (blendtype) {
1529 in= fact*tex + facm*out;
1534 in= (facm+fact*tex)*out;
1539 in= 1.0f-(facm+fact*(1.0f-tex))*(1.0f-out);
1545 in = out * (facm + 2.0f*fact*tex);
1547 in = 1.0f - (facm + 2.0f*fact*(1.0f - tex)) * (1.0f - out);
1558 in= facm*out + fact*out/tex;
1562 in= facm*out + fact*fabsf(tex-out);
1567 if (col < out) in= col; else in= out;
1572 if (col > out) in= col; else in= out;
1575 case MTEX_SOFT_LIGHT:
1576 scf=1.0f - (1.0f - tex) * (1.0f - out);
1577 in= facm*out + fact * ((1.0f - out) * tex * out) + (out * scf);
1580 case MTEX_LIN_LIGHT:
1582 in = out + fact*(2.0f*(tex - 0.5f));
1584 in = out + fact*(2.0f*tex - 1.0f);
1591 static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, float* co, float* dx, float* dy, float* texvec, float* dxt, float* dyt)
1593 // new: first swap coords, then map, then trans/scale
1594 if (tex->type == TEX_IMAGE) {
1596 texvec[0] = mtex->projx ? co[mtex->projx - 1] : 0.f;
1597 texvec[1] = mtex->projy ? co[mtex->projy - 1] : 0.f;
1598 texvec[2] = mtex->projz ? co[mtex->projz - 1] : 0.f;
1602 dxt[0] = dx[mtex->projx - 1];
1603 dyt[0] = dy[mtex->projx - 1];
1605 else dxt[0] = dyt[0] = 0.f;
1607 dxt[1] = dx[mtex->projy - 1];
1608 dyt[1] = dy[mtex->projy - 1];
1610 else dxt[1] = dyt[1] = 0.f;
1612 dxt[2] = dx[mtex->projz - 1];
1613 dyt[2] = dy[mtex->projz - 1];
1615 else dxt[2] = dyt[2] = 0.f;
1617 do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt);
1619 // translate and scale
1620 texvec[0] = mtex->size[0]*(texvec[0] - 0.5f) + mtex->ofs[0] + 0.5f;
1621 texvec[1] = mtex->size[1]*(texvec[1] - 0.5f) + mtex->ofs[1] + 0.5f;
1623 dxt[0] = mtex->size[0]*dxt[0];
1624 dxt[1] = mtex->size[1]*dxt[1];
1625 dyt[0] = mtex->size[0]*dyt[0];
1626 dyt[1] = mtex->size[1]*dyt[1];
1629 /* problem: repeat-mirror is not a 'repeat' but 'extend' in imagetexture.c */
1630 // TXF: bug was here, only modify texvec when repeat mode set, old code affected other modes too.
1631 // New texfilters solve mirroring differently so that it also works correctly when
1632 // textures are scaled (sizeXYZ) as well as repeated. See also modification in do_2d_mapping().
1633 // (since currently only done in osa mode, results will look incorrect without osa TODO)
1634 if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_XMIR)) {
1635 if (tex->texfilter == TXF_BOX)
1636 texvec[0] -= floorf(texvec[0]); // this line equivalent to old code, same below
1637 else if (texvec[0] < 0.f || texvec[0] > 1.f) {
1638 const float tx = 0.5f*texvec[0];
1639 texvec[0] = 2.f*(tx - floorf(tx));
1640 if (texvec[0] > 1.f) texvec[0] = 2.f - texvec[0];
1643 if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_YMIR)) {
1644 if (tex->texfilter == TXF_BOX)
1645 texvec[1] -= floorf(texvec[1]);
1646 else if (texvec[1] < 0.f || texvec[1] > 1.f) {
1647 const float ty = 0.5f*texvec[1];
1648 texvec[1] = 2.f*(ty - floorf(ty));
1649 if (texvec[1] > 1.f) texvec[1] = 2.f - texvec[1];
1654 else { // procedural
1656 texvec[0] = mtex->size[0]*(mtex->projx ? (co[mtex->projx - 1] + mtex->ofs[0]) : mtex->ofs[0]);
1657 texvec[1] = mtex->size[1]*(mtex->projy ? (co[mtex->projy - 1] + mtex->ofs[1]) : mtex->ofs[1]);
1658 texvec[2] = mtex->size[2]*(mtex->projz ? (co[mtex->projz - 1] + mtex->ofs[2]) : mtex->ofs[2]);
1662 dxt[0] = mtex->size[0]*dx[mtex->projx - 1];
1663 dyt[0] = mtex->size[0]*dy[mtex->projx - 1];
1665 else dxt[0] = dyt[0] = 0.f;
1667 dxt[1] = mtex->size[1]*dx[mtex->projy - 1];
1668 dyt[1] = mtex->size[1]*dy[mtex->projy - 1];
1670 else dxt[1] = dyt[1] = 0.f;
1672 dxt[2] = mtex->size[2]*dx[mtex->projz - 1];
1673 dyt[2] = mtex->size[2]*dy[mtex->projz - 1];
1675 else dxt[2]= dyt[2] = 0.f;
1680 /* Bump code from 2.5 development cycle, has a number of bugs, but here for compatibility */
1682 typedef struct CompatibleBump {
1683 float nu[3], nv[3], nn[3];
1684 float dudnu, dudnv, dvdnu, dvdnv;
1688 static void compatible_bump_init(CompatibleBump *compat_bump)
1690 memset(compat_bump, 0, sizeof(*compat_bump));
1692 compat_bump->dudnu = 1.0f;
1693 compat_bump->dvdnv = 1.0f;
1696 static void compatible_bump_uv_derivs(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, int i)
1698 // uvmapping only, calculation of normal tangent u/v partial derivatives
1699 // (should not be here, dudnu, dudnv, dvdnu & dvdnv should probably be part of ShadeInputUV struct,
1700 // nu/nv in ShadeInput and this calculation should then move to shadeinput.c, shade_input_set_shade_texco() func.)
1701 // NOTE: test for shi->obr->ob here, since vlr/obr/obi can be 'fake' when called from fastshade(), another reason to move it..
1702 // 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.
1703 if ((mtex->texflag & MTEX_COMPAT_BUMP) && shi->obr && shi->obr->ob && shi->v1) {
1704 if (mtex->mapto & (MAP_NORM|MAP_WARP) && !((mtex->tex->type==TEX_IMAGE) && (mtex->tex->imaflag & TEX_NORMALMAP))) {
1705 MTFace* tf = RE_vlakren_get_tface(shi->obr, shi->vlr, i, NULL, 0);
1706 int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3;
1708 vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3);
1710 // compute ortho basis around normal
1711 if (!compat_bump->nunvdone) {
1712 // render normal is negated
1713 compat_bump->nn[0] = -shi->vn[0];
1714 compat_bump->nn[1] = -shi->vn[1];
1715 compat_bump->nn[2] = -shi->vn[2];
1716 ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn);
1717 compat_bump->nunvdone = TRUE;
1721 float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3];
1722 const float an[3] = {fabsf(compat_bump->nn[0]), fabsf(compat_bump->nn[1]), fabsf(compat_bump->nn[2])};
1723 const int a1 = (an[0] > an[1] && an[0] > an[2]) ? 1 : 0;
1724 const int a2 = (an[2] > an[0] && an[2] > an[1]) ? 1 : 2;
1725 const float dp1_a1 = shi->v1->co[a1] - shi->v3->co[a1];
1726 const float dp1_a2 = shi->v1->co[a2] - shi->v3->co[a2];
1727 const float dp2_a1 = shi->v2->co[a1] - shi->v3->co[a1];
1728 const float dp2_a2 = shi->v2->co[a2] - shi->v3->co[a2];
1729 const float du1 = uv1[0] - uv3[0], du2 = uv2[0] - uv3[0];
1730 const float dv1 = uv1[1] - uv3[1], dv2 = uv2[1] - uv3[1];
1731 const float dpdu_a1 = dv2*dp1_a1 - dv1*dp2_a1;
1732 const float dpdu_a2 = dv2*dp1_a2 - dv1*dp2_a2;
1733 const float dpdv_a1 = du1*dp2_a1 - du2*dp1_a1;
1734 const float dpdv_a2 = du1*dp2_a2 - du2*dp1_a2;
1735 float d = dpdu_a1*dpdv_a2 - dpdv_a1*dpdu_a2;
1736 float uvd = du1*dv2 - dv1*du2;
1738 if (uvd == 0.f) uvd = 1e-5f;
1739 if (d == 0.f) d = 1e-5f;
1742 compat_bump->dudnu = (dpdv_a2*compat_bump->nu[a1] - dpdv_a1*compat_bump->nu[a2])*d;
1743 compat_bump->dvdnu = (dpdu_a1*compat_bump->nu[a2] - dpdu_a2*compat_bump->nu[a1])*d;
1744 compat_bump->dudnv = (dpdv_a2*compat_bump->nv[a1] - dpdv_a1*compat_bump->nv[a2])*d;
1745 compat_bump->dvdnv = (dpdu_a1*compat_bump->nv[a2] - dpdu_a2*compat_bump->nv[a1])*d;
1751 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)
1753 TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; // temp TexResult
1754 float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv;
1755 const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
1756 const float bf = -0.04f*Tnor*mtex->norfac;
1758 // disable internal bump eval
1759 float* nvec = texres->nor;
1761 // du & dv estimates, constant value defaults
1764 // compute ortho basis around normal
1765 if (!compat_bump->nunvdone) {
1766 // render normal is negated
1767 negate_v3_v3(compat_bump->nn, shi->vn);
1768 ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn);
1769 compat_bump->nunvdone = TRUE;
1772 // two methods, either constant based on main image resolution,
1773 // (which also works without osa, though of course not always good (or even very bad) results),
1774 // or based on tex derivative max values (osa only). Not sure which is best...
1776 if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) {
1777 // in case we have no proper derivatives, fall back to
1778 // computing du/dv it based on image size
1779 ImBuf* ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
1781 du = 1.f/(float)ibuf->x;
1782 dv = 1.f/(float)ibuf->y;
1785 else if (shi->osatex) {
1786 // we have derivatives, can compute proper du/dv
1787 if (tex->type == TEX_IMAGE) { // 2d image, use u & v max. of dx/dy 2d vecs
1788 const float adx[2] = {fabsf(dx[0]), fabsf(dx[1])};
1789 const float ady[2] = {fabsf(dy[0]), fabsf(dy[1])};
1790 du = MAX2(adx[0], ady[0]);
1791 dv = MAX2(adx[1], ady[1]);
1793 else { // 3d procedural, estimate from all dx/dy elems
1794 const float adx[3] = {fabsf(dx[0]), fabsf(dx[1]), fabsf(dx[2])};
1795 const float ady[3] = {fabsf(dy[0]), fabsf(dy[1]), fabsf(dy[2])};
1796 du = MAX3(adx[0], adx[1], adx[2]);
1797 dv = MAX3(ady[0], ady[1], ady[2]);
1801 // center, main return value
1802 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
1803 rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres);
1804 cd = fromrgb ? (texres->tr + texres->tg + texres->tb)*0.33333333f : texres->tin;
1806 if (mtex->texco == TEXCO_UV) {
1807 // for the uv case, use the same value for both du/dv,
1808 // since individually scaling the normal derivatives makes them useless...
1810 idu = (du < 1e-5f) ? bf : (bf/du);
1813 tco[0] = co[0] + compat_bump->dudnu*du;
1814 tco[1] = co[1] + compat_bump->dvdnu*du;
1816 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
1817 multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
1818 ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
1821 tco[0] = co[0] + compat_bump->dudnv*du;
1822 tco[1] = co[1] + compat_bump->dvdnv*du;
1824 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
1825 multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
1826 vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
1831 copy_v3_v3(tu, compat_bump->nu);
1832 copy_v3_v3(tv, compat_bump->nv);
1834 idu = (du < 1e-5f) ? bf : (bf/du);
1835 idv = (dv < 1e-5f) ? bf : (bf/dv);
1837 if ((mtex->texco == TEXCO_ORCO) && shi->obr && shi->obr->ob) {
1838 mul_mat3_m4_v3(shi->obr->ob->imat_ren, tu);
1839 mul_mat3_m4_v3(shi->obr->ob->imat_ren, tv);
1843 else if (mtex->texco == TEXCO_GLOB) {
1844 mul_mat3_m4_v3(R.viewinv, tu);
1845 mul_mat3_m4_v3(R.viewinv, tv);
1847 else if (mtex->texco == TEXCO_OBJECT && mtex->object) {
1848 mul_mat3_m4_v3(mtex->object->imat_ren, tu);
1849 mul_mat3_m4_v3(mtex->object->imat_ren, tv);
1855 tco[0] = co[0] + tu[0]*du;
1856 tco[1] = co[1] + tu[1]*du;
1857 tco[2] = co[2] + tu[2]*du;
1858 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
1859 multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
1860 ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
1863 tco[0] = co[0] + tv[0]*dv;
1864 tco[1] = co[1] + tv[1]*dv;
1865 tco[2] = co[2] + tv[2]*dv;
1866 texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
1867 multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr);
1868 vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
1872 compat_bump->nu[0] += ud*compat_bump->nn[0];
1873 compat_bump->nu[1] += ud*compat_bump->nn[1];
1874 compat_bump->nu[2] += ud*compat_bump->nn[2];
1875 compat_bump->nv[0] += vd*compat_bump->nn[0];
1876 compat_bump->nv[1] += vd*compat_bump->nn[1];
1877 compat_bump->nv[2] += vd*compat_bump->nn[2];
1878 cross_v3_v3v3(nvec, compat_bump->nu, compat_bump->nv);
1889 /* Improved bump code from later in 2.5 development cycle */
1891 typedef struct NTapBump {
1893 int iPrevBumpSpace; // 0: uninitialized, 1: objectspace, 2: texturespace, 4: viewspace
1895 float vNorg[3]; // backup copy of shi->vn
1896 float vNacc[3]; // original surface normal minus the surface gradient of every bump map which is encountered
1897 float vR1[3], vR2[3]; // cross products (sigma_y, original_normal), (original_normal, sigma_x)
1898 float sgn_det; // sign of the determinant of the matrix {sigma_x, sigma_y, original_normal}
1899 float fPrevMagnitude; // copy of previous magnitude, used for multiple bumps in different spaces
1902 static void ntap_bump_init(NTapBump *ntap_bump)
1904 memset(ntap_bump, 0, sizeof(*ntap_bump));
1907 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)
1909 TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; // temp TexResult
1911 const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
1913 // The negate on Hscale is done because the
1914 // normal in the renderer points inward which corresponds
1915 // to inverting the bump map. The normals are generated
1916 // this way in calc_vertexnormals(). Should this ever change
1917 // this negate must be removed.
1918 float Hscale = -Tnor*mtex->norfac;
1920 int dimx=512, dimy=512;
1921 const int imag_tspace_dimension_x = 1024; // only used for texture space variant
1922 float aspect = 1.0f;
1924 // 2 channels for 2D texture and 3 for 3D textures.
1925 const int nr_channels = (mtex->texco == TEXCO_UV)? 2 : 3;
1926 int c, rgbnor, iBumpSpace;
1928 int found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP);
1930 // disable internal bump eval in sampler, save pointer
1931 float *nvec = texres->nor;
1934 if (found_deriv_map==0) {
1935 if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
1937 Hscale *= 13.0f; // appears to be a sensible default value
1940 Hscale *= 0.1f; // factor 0.1 proved to look like the previous bump code
1943 if ( !ntap_bump->init_done ) {
1944 copy_v3_v3(ntap_bump->vNacc, shi->vn);
1945 copy_v3_v3(ntap_bump->vNorg, shi->vn);
1946 ntap_bump->fPrevMagnitude = 1.0f;
1947 ntap_bump->iPrevBumpSpace = 0;
1949 ntap_bump->init_done = TRUE;
1952 // resolve image dimensions
1953 if (found_deriv_map || (mtex->texflag&MTEX_BUMP_TEXTURESPACE)!=0) {
1954 ImBuf* ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
1958 aspect = ((float) dimy) / dimx;
1962 if (found_deriv_map) {
1963 float dBdu, dBdv, auto_bump = 1.0f;
1964 float s = 1; // negate this if flipped texture coordinate
1965 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
1966 rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres);
1968 if (shi->obr->ob->derivedFinal) {
1969 auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale;
1973 float fVirtDim = sqrtf(fabsf((float) (dimx*dimy)*mtex->size[0]*mtex->size[1]));
1974 auto_bump /= MAX2(fVirtDim, FLT_EPSILON);
1977 // this variant using a derivative map is described here
1978 // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
1979 dBdu = auto_bump*Hscale*dimx*(2*texres->tr-1);
1980 dBdv = auto_bump*Hscale*dimy*(2*texres->tg-1);
1982 dHdx = dBdu*dxt[0] + s * dBdv*dxt[1];
1983 dHdy = dBdu*dyt[0] + s * dBdv*dyt[1];
1985 else if (!(mtex->texflag & MTEX_5TAP_BUMP)) {
1986 // compute height derivatives with respect to output image pixel coordinates x and y
1987 float STll[3], STlr[3], STul[3];
1988 float Hll, Hlr, Hul;
1990 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
1992 for (c=0; c<nr_channels; c++) {
1993 // dx contains the derivatives (du/dx, dv/dx)
1994 // dy contains the derivatives (du/dy, dv/dy)
1995 STll[c] = texvec[c];
1996 STlr[c] = texvec[c]+dxt[c];
1997 STul[c] = texvec[c]+dyt[c];
2000 // clear unused derivatives
2001 for (c=nr_channels; c<3; c++) {
2007 // use texres for the center sample, set rgbnor
2008 rgbnor = multitex_mtex(shi, mtex, STll, dxt, dyt, texres);
2009 Hll = (fromrgb) ? rgb_to_grayscale(&texres->tr) : texres->tin;
2011 // use ttexr for the other 2 taps
2012 multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr);
2013 Hlr = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
2015 multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr);
2016 Hul = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
2018 dHdx = Hscale*(Hlr - Hll);
2019 dHdy = Hscale*(Hul - Hll);
2022 /* same as above, but doing 5 taps, increasing quality at cost of speed */
2023 float STc[3], STl[3], STr[3], STd[3], STu[3];
2024 float /* Hc, */ /* UNUSED */ Hl, Hr, Hd, Hu;
2026 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
2028 for (c=0; c<nr_channels; c++) {
2030 STl[c] = texvec[c] - 0.5f*dxt[c];
2031 STr[c] = texvec[c] + 0.5f*dxt[c];
2032 STd[c] = texvec[c] - 0.5f*dyt[c];
2033 STu[c] = texvec[c] + 0.5f*dyt[c];
2036 // clear unused derivatives
2037 for (c=nr_channels; c<3; c++) {
2045 // use texres for the center sample, set rgbnor
2046 rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres);
2047 /* Hc = (fromrgb) ? rgb_to_grayscale(&texres->tr) : texres->tin; */ /* UNUSED */
2049 // use ttexr for the other taps
2050 multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr);
2051 Hl = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
2052 multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr);
2053 Hr = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
2054 multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr);
2055 Hd = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
2056 multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr);
2057 Hu = (fromrgb) ? rgb_to_grayscale(&ttexr.tr) : ttexr.tin;
2059 dHdx = Hscale*(Hr - Hl);
2060 dHdy = Hscale*(Hu - Hd);
2066 /* replaced newbump with code based on listing 1 and 2 of
2067 * [Mik10] Mikkelsen M. S.: Bump Mapping Unparameterized Surfaces on the GPU.
2068 * -> http://jbit.net/~sparky/sfgrad_bump/mm_sfgrad_bump.pdf */
2070 if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
2072 else if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
2075 iBumpSpace = 4; // ViewSpace
2077 if ( ntap_bump->iPrevBumpSpace != iBumpSpace ) {
2079 // initialize normal perturbation vectors
2081 float fDet, abs_fDet, fMagnitude;
2082 // object2view and inverted matrix
2083 float obj2view[3][3], view2obj[3][3], tmp[4][4];
2084 // local copies of derivatives and normal
2085 float dPdx[3], dPdy[3], vN[3];
2086 copy_v3_v3(dPdx, shi->dxco);
2087 copy_v3_v3(dPdy, shi->dyco);
2088 copy_v3_v3(vN, ntap_bump->vNorg);
2090 if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) {
2091 // TODO: these calculations happen for every pixel!
2092 // -> move to shi->obi
2093 mult_m4_m4m4(tmp, R.viewmat, shi->obr->ob->obmat);
2094 copy_m3_m4(obj2view, tmp); // use only upper left 3x3 matrix
2095 invert_m3_m3(view2obj, obj2view);
2097 // generate the surface derivatives in object space
2098 mul_m3_v3(view2obj, dPdx);
2099 mul_m3_v3(view2obj, dPdy);
2100 // generate the unit normal in object space
2101 mul_transposed_m3_v3(obj2view, vN);
2105 cross_v3_v3v3(ntap_bump->vR1, dPdy, vN);
2106 cross_v3_v3v3(ntap_bump->vR2, vN, dPdx);
2107 fDet = dot_v3v3(dPdx, ntap_bump->vR1);
2108 ntap_bump->sgn_det = (fDet < 0)? -1.0f: 1.0f;
2109 abs_fDet = ntap_bump->sgn_det * fDet;
2111 if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
2113 // crazy hack solution that gives results similar to normal mapping - part 1
2114 normalize_v3(ntap_bump->vR1);
2115 normalize_v3(ntap_bump->vR2);
2120 fMagnitude = abs_fDet;
2121 if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) {
2122 // pre do transform of texres->nor by the inverse transposed of obj2view
2123 mul_transposed_m3_v3(view2obj, vN);
2124 mul_transposed_m3_v3(view2obj, ntap_bump->vR1);
2125 mul_transposed_m3_v3(view2obj, ntap_bump->vR2);
2127 fMagnitude *= len_v3(vN);
2130 if (ntap_bump->fPrevMagnitude > 0.0f)
2131 for (xyz=0; xyz<3; xyz++)
2132 ntap_bump->vNacc[xyz] *= fMagnitude / ntap_bump->fPrevMagnitude;
2134 ntap_bump->fPrevMagnitude = fMagnitude;
2135 ntap_bump->iPrevBumpSpace = iBumpSpace;
2138 if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
2140 // crazy hack solution that gives results similar to normal mapping - part 2
2142 const float imag_tspace_dimension_y = aspect*imag_tspace_dimension_x;
2144 vec[0] = imag_tspace_dimension_x*dxt[0];
2145 vec[1] = imag_tspace_dimension_y*dxt[1];
2146 dHdx *= 1.0f/len_v2(vec);
2147 vec[0] = imag_tspace_dimension_x*dyt[0];
2148 vec[1] = imag_tspace_dimension_y*dyt[1];
2149 dHdy *= 1.0f/len_v2(vec);
2153 // subtract the surface gradient from vNacc
2154 for (c=0; c<3; c++) {
2155 float vSurfGrad_compi = ntap_bump->sgn_det * (dHdx * ntap_bump->vR1[c] + dHdy * ntap_bump->vR2[c]);
2156 ntap_bump->vNacc[c] -= vSurfGrad_compi;
2157 texres->nor[c] = ntap_bump->vNacc[c]; // copy
2164 void do_material_tex(ShadeInput *shi, Render *re)
2166 CompatibleBump compat_bump;
2170 TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
2171 float *co = NULL, *dx = NULL, *dy = NULL;
2172 float fact, facm, factt, facmm, stencilTin=1.0;
2173 float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0;
2174 int tex_nr, rgbnor= 0, warp_done = FALSE;
2175 int use_compat_bump = FALSE, use_ntap_bump = FALSE;
2176 int found_nmapping = 0, found_deriv_map = 0;
2177 int iFirstTimeNMap=1;
2179 compatible_bump_init(&compat_bump);
2180 ntap_bump_init(&ntap_bump);
2182 if (re->r.scemode & R_NO_TEX) return;
2183 /* here: test flag if there's a tex (todo) */
2185 for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
2187 /* separate tex switching */
2188 if (shi->mat->septex & (1<<tex_nr)) continue;
2190 if (shi->mat->mtex[tex_nr]) {
2191 mtex= shi->mat->mtex[tex_nr];
2194 if (tex==0) continue;
2196 found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP);
2197 use_compat_bump= (mtex->texflag & MTEX_COMPAT_BUMP);
2198 use_ntap_bump = ((mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP))!=0 || found_deriv_map!=0) ? TRUE : FALSE;
2200 /* XXX texture node trees don't work for this yet */
2201 if (tex->nodetree && tex->use_nodes) {
2202 use_compat_bump = FALSE;
2203 use_ntap_bump = FALSE;
2206 /* case displacement mapping */
2207 if (shi->osatex == 0 && use_ntap_bump) {
2208 use_ntap_bump = FALSE;
2209 use_compat_bump = TRUE;
2213 if (tex->type == TEX_OCEAN) {
2214 use_ntap_bump = FALSE;
2215 use_compat_bump = FALSE;
2219 if (mtex->texco==TEXCO_ORCO) {
2220 if (mtex->texflag & MTEX_DUPLI_MAPTO) {
2221 co= shi->duplilo; dx= dxt; dy= dyt;
2222 dxt[0]= dxt[1]= dxt[2]= 0.0f;
2223 dyt[0]= dyt[1]= dyt[2]= 0.0f;
2226 co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
2229 else if (mtex->texco==TEXCO_STICKY) {
2230 co= shi->sticky; dx= shi->dxsticky; dy= shi->dysticky;
2232 else if (mtex->texco==TEXCO_OBJECT) {
2233 Object *ob= mtex->object;
2238 copy_v3_v3(tempvec, shi->co);
2239 if (mtex->texflag & MTEX_OB_DUPLI_ORIG)
2240 if (shi->obi && shi->obi->duplitexmat)
2241 mul_m4_v3(shi->obi->duplitexmat, tempvec);
2242 mul_m4_v3(ob->imat_ren, tempvec);
2244 copy_v3_v3(dxt, shi->dxco);
2245 copy_v3_v3(dyt, shi->dyco);
2246 mul_mat3_m4_v3(ob->imat_ren, dxt);
2247 mul_mat3_m4_v3(ob->imat_ren, dyt);
2251 /* if object doesn't exist, do not use orcos (not initialized) */
2253 dx= shi->dxco; dy= shi->dyco;
2256 else if (mtex->texco==TEXCO_REFL) {
2258 co= shi->ref; dx= shi->dxref; dy= shi->dyref;
2260 else if (mtex->texco==TEXCO_NORM) {
2261 co= shi->orn; dx= shi->dxno; dy= shi->dyno;
2263 else if (mtex->texco==TEXCO_TANGENT) {
2264 co= shi->tang; dx= shi->dxno; dy= shi->dyno;
2266 else if (mtex->texco==TEXCO_GLOB) {
2267 co= shi->gl; dx= shi->dxgl; dy= shi->dygl;
2269 else if (mtex->texco==TEXCO_UV) {
2270 if (mtex->texflag & MTEX_DUPLI_MAPTO) {
2271 co= shi->dupliuv; dx= dxt; dy= dyt;
2272 dxt[0]= dxt[1]= dxt[2]= 0.0f;
2273 dyt[0]= dyt[1]= dyt[2]= 0.0f;
2276 ShadeInputUV *suv= &shi->uv[shi->actuv];
2279 if (mtex->uvname[0] != 0) {
2280 for (i = 0; i < shi->totuv; i++) {
2281 if (strcmp(shi->uv[i].name, mtex->uvname)==0) {
2292 compatible_bump_uv_derivs(&compat_bump, shi, mtex, i);
2295 else if (mtex->texco==TEXCO_WINDOW) {
2296 co= shi->winco; dx= shi->dxwin; dy= shi->dywin;
2298 else if (mtex->texco==TEXCO_STRAND) {
2299 co= tempvec; dx= dxt; dy= dyt;
2300 co[0]= shi->strandco;
2302 dx[0]= shi->dxstrand;
2304 dy[0]= shi->dystrand;
2307 else if (mtex->texco==TEXCO_STRESS) {
2308 co= tempvec; dx= dxt; dy= dyt;
2316 else continue; // can happen when texco defines disappear and it renders old files
2318 /* the pointer defines if bumping happens */
2319 if (mtex->mapto & (MAP_NORM|MAP_WARP)) {
2321 norvec[0]= norvec[1]= norvec[2]= 0.0;
2323 else texres.nor= NULL;
2326 add_v3_v3v3(tempvec, co, warpvec);
2330 /* XXX texture node trees don't work for this yet */
2331 if (texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) {
2332 if (use_compat_bump) {
2333 rgbnor = compatible_bump_compute(&compat_bump, shi, mtex, tex,
2334 &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt);
2336 else if (use_ntap_bump) {
2337 rgbnor = ntap_bump_compute(&ntap_bump, shi, mtex, tex,
2338 &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt);
2341 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
2342 rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres);
2346 texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
2347 rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres);
2350 /* texture output */
2352 if ( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
2353 texres.tin = rgb_to_grayscale(&texres.tr);
2356 if (mtex->texflag & MTEX_NEGATIVE) {
2357 if (rgbnor & TEX_RGB) {
2358 texres.tr= 1.0f-texres.tr;
2359 texres.tg= 1.0f-texres.tg;
2360 texres.tb= 1.0f-texres.tb;
2362 texres.tin= 1.0f-texres.tin;
2364 if (mtex->texflag & MTEX_STENCIL) {
2365 if (rgbnor & TEX_RGB) {
2367 texres.ta*= stencilTin;
2372 texres.tin*= stencilTin;
2381 if ((rgbnor & TEX_NOR)==0) {
2382 /* make our own normal */
2383 if (rgbnor & TEX_RGB) {
2384 copy_v3_v3(texres.nor, &texres.tr);
2387 float co_nor= 0.5*cos(texres.tin-0.5f);
2388 float si= 0.5*sin(texres.tin-0.5f);
2393 texres.nor[0]= f1*co_nor+f2*si;
2396 texres.nor[1]= f1*co_nor+f2*si;
2397 texres.nor[2]= f2*co_nor-f1*si;
2400 // warping, local space
2401 if (mtex->mapto & MAP_WARP) {
2402 float *warpnor= texres.nor, warpnor_[3];
2404 if (use_ntap_bump) {
2405 copy_v3_v3(warpnor_, texres.nor);
2407 normalize_v3(warpnor_);
2409 warpvec[0]= mtex->warpfac*warpnor[0];
2410 warpvec[1]= mtex->warpfac*warpnor[1];
2411 warpvec[2]= mtex->warpfac*warpnor[2];
2415 if (mtex->texflag & MTEX_VIEWSPACE) {
2416 // rotate to global coords
2417 if (mtex->texco==TEXCO_ORCO || mtex->texco==TEXCO_UV) {
2418 if (shi->vlr && shi->obr && shi->obr->ob) {
2419 float len= normalize_v3(texres.nor);
2420 // can be optimized... (ton)
2421 mul_mat3_m4_v3(shi->obr->ob->obmat, texres.nor);
2422 mul_mat3_m4_v3(re->viewmat, texres.nor);
2423 normalize_v3(texres.nor);
2424 mul_v3_fl(texres.nor, len);
2432 if (mtex->mapto & (MAP_COL | MAP_COLSPEC | MAP_COLMIR)) {
2435 /* stencil maps on the texture control slider, not texture intensity value */
2436 copy_v3_v3(tcol, &texres.tr);
2438 if ((rgbnor & TEX_RGB) == 0) {
2439 copy_v3_v3(tcol, &mtex->r);
2441 else if (mtex->mapto & MAP_ALPHA) {
2442 texres.tin = stencilTin;
2445 texres.tin = texres.ta;
2448 /* inverse gamma correction */
2449 if (tex->type==TEX_IMAGE) {
2450 Image *ima = tex->ima;
2451 ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
2453 /* don't linearize float buffers, assumed to be linear */
2454 if (ibuf && !(ibuf->rect_float) && re->r.color_mgt_flag & R_COLOR_MANAGEMENT)
2455 srgb_to_linearrgb_v3_v3(tcol, tcol);
2458 if (mtex->mapto & MAP_COL) {
2459 float colfac= mtex->colfac*stencilTin;
2460 texture_rgb_blend(&shi->r, tcol, &shi->r, texres.tin, colfac, mtex->blendtype);
2462 if (mtex->mapto & MAP_COLSPEC) {
2463 float colspecfac= mtex->colspecfac*stencilTin;
2464 texture_rgb_blend(&shi->specr, tcol, &shi->specr, texres.tin, colspecfac, mtex->blendtype);
2466 if (mtex->mapto & MAP_COLMIR) {
2467 float mirrfac= mtex->mirrfac*stencilTin;
2469 // exception for envmap only
2470 if (tex->type==TEX_ENVMAP && mtex->blendtype==MTEX_BLEND) {
2471 fact= texres.tin*mirrfac;
2473 shi->refcol[0]= fact + facm*shi->refcol[0];
2474 shi->refcol[1]= fact*tcol[0] + facm*shi->refcol[1];
2475 shi->refcol[2]= fact*tcol[1] + facm*shi->refcol[2];
2476 shi->refcol[3]= fact*tcol[2] + facm*shi->refcol[3];
2479 texture_rgb_blend(&shi->mirr, tcol, &shi->mirr, texres.tin, mirrfac, mtex->blendtype);
2483 if ( (mtex->mapto & MAP_NORM) ) {
2485 float norfac= mtex->norfac;
2487 /* we need to code blending modes for normals too once.. now 1 exception hardcoded */
2489 if ((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP)) {
2493 /* qdn: for normalmaps, to invert the normalmap vector,
2494 * it is better to negate x & y instead of subtracting the vector as was done before */
2495 if (norfac < 0.0f) {
2496 texres.nor[0] = -texres.nor[0];
2497 texres.nor[1] = -texres.nor[1];
2499 fact = Tnor*fabsf(norfac);
2500 if (fact>1.f) fact = 1.f;
2502 if (mtex->normapspace == MTEX_NSPACE_TANGENT) {
2503 /* qdn: tangent space */
2505 const float * no = iFirstTimeNMap!=0 ? shi->nmapnorm : shi->vn;
2507 cross_v3_v3v3(B, no, shi->nmaptang); /* bitangent */
2508 mul_v3_fl(B, shi->nmaptang[3]);
2509 /* transform norvec from tangent space to object surface in camera space */
2510 tv[0] = texres.nor[0]*shi->nmaptang[0] + texres.nor[1]*B[0] + texres.nor[2]*no[0];
2511 tv[1] = texres.nor[0]*shi->nmaptang[1] + texres.nor[1]*B[1] + texres.nor[2]*no[1];
2512 tv[2] = texres.nor[0]*shi->nmaptang[2] + texres.nor[1]*B[2] + texres.nor[2]*no[2];
2513 shi->vn[0]= facm*no[0] + fact*tv[0];
2514 shi->vn[1]= facm*no[1] + fact*tv[1];
2515 shi->vn[2]= facm*no[2] + fact*tv[2];
2520 copy_v3_v3(nor, texres.nor);
2522 if (mtex->normapspace == MTEX_NSPACE_CAMERA);
2523 else if (mtex->normapspace == MTEX_NSPACE_WORLD) {
2524 mul_mat3_m4_v3(re->viewmat, nor);
2526 else if (mtex->normapspace == MTEX_NSPACE_OBJECT) {
2527 if (shi->obr && shi->obr->ob)
2528 mul_mat3_m4_v3(shi->obr->ob->obmat, nor);
2529 mul_mat3_m4_v3(re->viewmat, nor);
2534 /* qdn: worldspace */
2535 shi->vn[0]= facm*shi->vn[0] + fact*nor[0];
2536 shi->vn[1]= facm*shi->vn[1] + fact*nor[1];
2537 shi->vn[2]= facm*shi->vn[2] + fact*nor[2];
2541 /* XXX texture node trees don't work for this yet */
2542 if (use_compat_bump || use_ntap_bump) {
2543 shi->vn[0] = texres.nor[0];
2544 shi->vn[1] = texres.nor[1];
2545 shi->vn[2] = texres.nor[2];
2550 if (shi->mat->mode & MA_TANGENT_V) {
2551 shi->tang[0]+= Tnor*norfac*texres.nor[0];
2552 shi->tang[1]+= Tnor*norfac*texres.nor[1];
2553 shi->tang[2]+= Tnor*norfac*texres.nor[2];
2556 /* prevent bump to become negative normal */
2557 nor[0]= Tnor*norfac*texres.nor[0];
2558 nor[1]= Tnor*norfac*texres.nor[1];
2559 nor[2]= Tnor*norfac*texres.nor[2];
2561 dot= 0.5f + 0.5f * dot_v3v3(nor, shi->vn);
2563 shi->vn[0]+= dot*nor[0];
2564 shi->vn[1]+= dot*nor[1];
2565 shi->vn[2]+= dot*nor[2];
2568 normalize_v3(shi->vn);
2570 /* this makes sure the bump is passed on to the next texture */
2571 shi->orn[0]= -shi->vn[0];
2572 shi->orn[1]= -shi->vn[1];
2573 shi->orn[2]= -shi->vn[2];
2577 if ( mtex->mapto & MAP_DISPLACE ) {
2578 /* Now that most textures offer both Nor and Intensity, allow */
2579 /* both to work, and let user select with slider. */
2581 float norfac= mtex->norfac;
2583 shi->displace[0]+= 0.2f*Tnor*norfac*texres.nor[0];
2584 shi->displace[1]+= 0.2f*Tnor*norfac*texres.nor[1];
2585 shi->displace[2]+= 0.2f*Tnor*norfac*texres.nor[2];
2588 if (rgbnor & TEX_RGB) {
2589 texres.tin = rgb_to_grayscale(&texres.tr);
2592 factt= (0.5f-texres.tin)*mtex->dispfac*stencilTin; facmm= 1.0f-factt;
2594 if (mtex->blendtype==MTEX_BLEND) {
2595 shi->displace[0]= factt*shi->vn[0] + facmm*shi->displace[0];
2596 shi->displace[1]= factt*shi->vn[1] + facmm*shi->displace[1];
2597 shi->displace[2]= factt*shi->vn[2] + facmm*shi->displace[2];
2599 else if (mtex->blendtype==MTEX_MUL) {
2600 shi->displace[0]*= factt*shi->vn[0];
2601 shi->displace[1]*= factt*shi->vn[1];
2602 shi->displace[2]*= factt*shi->vn[2];
2604 else { /* add or sub */
2605 if (mtex->blendtype==MTEX_SUB) factt= -factt;
2606 shi->displace[0]+= factt*shi->vn[0];
2607 shi->displace[1]+= factt*shi->vn[1];
2608 shi->displace[2]+= factt*shi->vn[2];
2612 if (mtex->mapto & MAP_VARS) {
2613 /* stencil maps on the texture control slider, not texture intensity value */
2615 if (rgbnor & TEX_RGB) {
2616 if (texres.talpha) texres.tin = texres.ta;
2617 else texres.tin = rgb_to_grayscale(&texres.tr);
2620 if (mtex->mapto & MAP_REF) {
2621 float difffac= mtex->difffac*stencilTin;
2623 shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, difffac, mtex->blendtype);
2624 if (shi->refl<0.0f) shi->refl= 0.0f;
2626 if (mtex->mapto & MAP_SPEC) {
2627 float specfac= mtex->specfac*stencilTin;
2629 shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, specfac, mtex->blendtype);
2630 if (shi->spec<0.0f) shi->spec= 0.0f;
2632 if (mtex->mapto & MAP_EMIT) {
2633 float emitfac= mtex->emitfac*stencilTin;
2635 shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, emitfac, mtex->blendtype);
2636 if (shi->emit<0.0f) shi->emit= 0.0f;
2638 if (mtex->mapto & MAP_ALPHA) {
2639 float alphafac= mtex->alphafac*stencilTin;
2641 shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, alphafac, mtex->blendtype);
2642 if (shi->alpha<0.0f) shi->alpha= 0.0f;
2643 else if (shi->alpha>1.0f) shi->alpha= 1.0f;
2645 if (mtex->mapto & MAP_HAR) {
2646 float har; // have to map to 0-1
2647 float hardfac= mtex->hardfac*stencilTin;
2649 har= ((float)shi->har)/128.0f;
2650 har= 128.0f*texture_value_blend(mtex->def_var, har, texres.tin, hardfac, mtex->blendtype);
2652 if (har<1.0f) shi->har= 1;
2653 else if (har>511) shi->har= 511;
2654 else shi->har= (int)har;
2656 if (mtex->mapto & MAP_RAYMIRR) {
2657 float raymirrfac= mtex->raymirrfac*stencilTin;
2659 shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, raymirrfac, mtex->blendtype);
2660 if (shi->ray_mirror<0.0f) shi->ray_mirror= 0.0f;
2661 else if (shi->ray_mirror>1.0f) shi->ray_mirror= 1.0f;
2663 if (mtex->mapto & MAP_TRANSLU) {
2664 float translfac= mtex->translfac*stencilTin;
2666 shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, translfac, mtex->blendtype);
2667 if (shi->translucency<0.0f) shi->translucency= 0.0f;
2668 else if (shi->translucency>1.0f) shi->translucency= 1.0f;
2670 if (mtex->mapto & MAP_AMB) {
2671 float ambfac= mtex->ambfac*stencilTin;
2673 shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, ambfac, mtex->blendtype);
2674 if (shi->amb<0.0f) shi->amb= 0.0f;
2675 else if (shi->amb>1.0f) shi->amb= 1.0f;
2677 shi->ambr= shi->amb*re->wrld.ambr;
2678 shi->ambg= shi->amb*re->wrld.ambg;
2679 shi->ambb= shi->amb*re->wrld.ambb;
2684 if ((use_compat_bump || use_ntap_bump || found_nmapping) && (shi->mat->mode & MA_TANGENT_V) != 0) {
2685 const float fnegdot = -dot_v3v3(shi->vn, shi->tang);
2686 // apply Gram-Schmidt projection
2687 madd_v3_v3fl(shi->tang, shi->vn, fnegdot);
2688 normalize_v3(shi->tang);
2693 void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_r[3], float *val, Render *re)
2697 TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
2698 int tex_nr, rgbnor= 0;
2699 float co[3], texvec[3];
2700 float fact, stencilTin=1.0;
2702 if (re->r.scemode & R_NO_TEX) return;
2703 /* here: test flag if there's a tex (todo) */
2705 for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
2706 /* separate tex switching */
2707 if (shi->mat->septex & (1<<tex_nr)) continue;
2709 if (shi->mat->mtex[tex_nr]) {