Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/render/intern/source/render_texture.c')
-rw-r--r--source/blender/render/intern/source/render_texture.c2510
1 files changed, 18 insertions, 2492 deletions
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 929fc3cc9c3..79d13ecab5b 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -65,23 +65,11 @@
#include "MEM_guardedalloc.h"
-#include "envmap.h"
-#include "pointdensity.h"
-#include "voxeldata.h"
#include "render_types.h"
-#include "shading.h"
#include "texture.h"
-#include "texture_ocean.h"
-
-#include "renderdatabase.h" /* needed for UV */
#include "RE_render_ext.h"
-
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
-/* only to be used here in this file, it's for speed */
-extern struct Render R;
-/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+#include "RE_shader_ext.h"
static RNG_THREAD_ARRAY *random_tex_array;
@@ -97,63 +85,6 @@ void RE_texture_rng_exit(void)
}
-static void init_render_texture(Render *re, Tex *tex)
-{
- /* imap test */
- if (tex->ima && BKE_image_is_animated(tex->ima)) {
- BKE_image_user_frame_calc(&tex->iuser, re ? re->r.cfra : 0, re ? re->flag & R_SEC_FIELD:0);
- }
-
- else if (tex->type==TEX_ENVMAP) {
- /* just in case */
- tex->imaflag |= TEX_INTERPOL | TEX_MIPMAP;
- tex->extend= TEX_CLIP;
-
- if (tex->env) {
- if (tex->env->type==ENV_PLANE)
- tex->extend= TEX_EXTEND;
-
- /* only free envmap when rendermode was set to render envmaps, for previewrender */
- if (G.is_rendering && re) {
- if (re->r.mode & R_ENVMAP)
- if (tex->env->stype==ENV_ANIM)
- BKE_texture_envmap_free_data(tex->env);
- }
- }
- }
-
- if (tex->nodetree && tex->use_nodes) {
- ntreeTexBeginExecTree(tex->nodetree); /* has internal flag to detect it only does it once */
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-void init_render_textures(Render *re)
-{
- Tex *tex;
-
- tex= re->main->tex.first;
- while (tex) {
- if (tex->id.us) init_render_texture(re, tex);
- tex= tex->id.next;
- }
-}
-
-static void end_render_texture(Tex *tex)
-{
- if (tex && tex->use_nodes && tex->nodetree && tex->nodetree->execdata)
- ntreeTexEndExecTree(tex->nodetree->execdata);
-}
-
-void end_render_textures(Render *re)
-{
- Tex *tex;
- for (tex= re->main->tex.first; tex; tex= tex->id.next)
- if (tex->id.us)
- end_render_texture(tex);
-}
-
/* ------------------------------------------------------------------------- */
@@ -755,7 +686,6 @@ static int cubemap_glob(const float n[3], float x, float y, float z, float *adr1
else {
copy_v3_v3(nor, n);
}
- mul_mat3_m4_v3(R.viewinv, nor);
x1 = fabsf(nor[0]);
y1 = fabsf(nor[1]);
@@ -781,115 +711,20 @@ static int cubemap_glob(const float n[3], float x, float y, float z, float *adr1
/* ------------------------------------------------------------------------- */
-/* mtex argument only for projection switches */
-static int cubemap(
- const MTex *mtex, VlakRen *vlr, const float n[3], float x, float y, float z, float *adr1, float *adr2)
-{
- int proj[4]={0, ME_PROJXY, ME_PROJXZ, ME_PROJYZ}, ret= 0;
-
- if (vlr) {
- int index;
-
- /* Mesh vertices have such flags, for others we calculate it once based on orco */
- if ((vlr->puno & (ME_PROJXY|ME_PROJXZ|ME_PROJYZ))==0) {
- /* test for v1, vlr can be faked for baking */
- if (vlr->v1 && vlr->v1->orco) {
- float nor[3];
- normal_tri_v3(nor, vlr->v1->orco, vlr->v2->orco, vlr->v3->orco);
-
- if (fabsf(nor[0]) < fabsf(nor[2]) && fabsf(nor[1]) < fabsf(nor[2])) vlr->puno |= ME_PROJXY;
- else if (fabsf(nor[0]) < fabsf(nor[1]) && fabsf(nor[2]) < fabsf(nor[1])) vlr->puno |= ME_PROJXZ;
- else vlr->puno |= ME_PROJYZ;
- }
- else return cubemap_glob(n, x, y, z, adr1, adr2);
- }
-
- if (mtex) {
- /* the mtex->proj{xyz} have type char. maybe this should be wider? */
- /* casting to int ensures that the index type is right. */
- index = (int) mtex->projx;
- proj[index]= ME_PROJXY;
-
- index = (int) mtex->projy;
- proj[index]= ME_PROJXZ;
-
- index = (int) mtex->projz;
- proj[index]= ME_PROJYZ;
- }
-
- if (vlr->puno & proj[1]) {
- *adr1 = (x + 1.0f) / 2.0f;
- *adr2 = (y + 1.0f) / 2.0f;
- }
- else if (vlr->puno & proj[2]) {
- *adr1 = (x + 1.0f) / 2.0f;
- *adr2 = (z + 1.0f) / 2.0f;
- ret= 1;
- }
- else {
- *adr1 = (y + 1.0f) / 2.0f;
- *adr2 = (z + 1.0f) / 2.0f;
- ret= 2;
- }
- }
- else {
- return cubemap_glob(n, x, y, z, adr1, adr2);
- }
-
- return ret;
-}
-
-/* ------------------------------------------------------------------------- */
-
-static int cubemap_ob(Object *ob, const float n[3], float x, float y, float z, float *adr1, float *adr2)
-{
- float x1, y1, z1, nor[3];
- int ret;
-
- if (n==NULL) return 0;
-
- copy_v3_v3(nor, n);
- if (ob) mul_mat3_m4_v3(ob->imat, nor);
-
- x1 = fabsf(nor[0]);
- y1 = fabsf(nor[1]);
- z1 = fabsf(nor[2]);
-
- if (z1>=x1 && z1>=y1) {
- *adr1 = (x + 1.0f) / 2.0f;
- *adr2 = (y + 1.0f) / 2.0f;
- ret= 0;
- }
- else if (y1>=x1 && y1>=z1) {
- *adr1 = (x + 1.0f) / 2.0f;
- *adr2 = (z + 1.0f) / 2.0f;
- ret= 1;
- }
- else {
- *adr1 = (y + 1.0f) / 2.0f;
- *adr2 = (z + 1.0f) / 2.0f;
- ret= 2;
- }
- return ret;
-}
-
/* ------------------------------------------------------------------------- */
static void do_2d_mapping(
- const MTex *mtex, float texvec[3], VlakRen *vlr, const float n[3], float dxt[3], float dyt[3])
+ const MTex *mtex, float texvec[3], const float n[3], float dxt[3], float dyt[3])
{
Tex *tex;
- Object *ob= NULL;
float fx, fy, fac1, area[8];
- int ok, proj, areaflag= 0, wrap, texco;
+ int ok, proj, areaflag= 0, wrap;
/* mtex variables localized, only cubemap doesn't cooperate yet... */
wrap= mtex->mapping;
tex= mtex->tex;
- ob= mtex->object;
- texco= mtex->texco;
- if (R.osa==0) {
+ if (!(dxt && dyt)) {
if (wrap==MTEX_FLAT) {
fx = (texvec[0] + 1.0f) / 2.0f;
@@ -898,9 +733,7 @@ static void do_2d_mapping(
else if (wrap == MTEX_TUBE) map_to_tube( &fx, &fy, texvec[0], texvec[1], texvec[2]);
else if (wrap == MTEX_SPHERE) map_to_sphere(&fx, &fy, texvec[0], texvec[1], texvec[2]);
else {
- if (texco == TEXCO_OBJECT) cubemap_ob(ob, n, texvec[0], texvec[1], texvec[2], &fx, &fy);
- else if (texco == TEXCO_GLOB) cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy);
- else cubemap(mtex, vlr, n, texvec[0], texvec[1], texvec[2], &fx, &fy);
+ cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy);
}
/* repeat */
@@ -996,9 +829,7 @@ static void do_2d_mapping(
}
else {
- if (texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, texvec[0], texvec[1], texvec[2], &fx, &fy);
- else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy);
- else proj = cubemap(mtex, vlr, n, texvec[0], texvec[1], texvec[2], &fx, &fy);
+ proj = cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy);
if (proj==1) {
SWAP(float, dxt[1], dxt[2]);
@@ -1124,8 +955,9 @@ static int multitex(Tex *tex,
texres->talpha = false; /* is set when image texture returns alpha (considered premul) */
if (use_nodes && tex->use_nodes && tex->nodetree) {
+ const float cfra = 1.0f; /* This was only set for Blender Internal render before. */
retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread,
- tex, which_output, R.r.cfra, texnode_preview, NULL, NULL);
+ tex, which_output, cfra, texnode_preview, NULL);
}
else {
switch (tex->type) {
@@ -1160,9 +992,6 @@ static int multitex(Tex *tex,
BKE_image_tag_time(tex->ima);
}
break;
- case TEX_ENVMAP:
- retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres, pool, skip_load_image);
- break;
case TEX_MUSGRAVE:
/* newnoise: musgrave types */
@@ -1205,15 +1034,6 @@ static int multitex(Tex *tex,
retval = mg_distNoiseTex(tex, tmpvec, texres);
break;
- case TEX_POINTDENSITY:
- retval = pointdensitytex(tex, texvec, texres);
- break;
- case TEX_VOXELDATA:
- retval = voxeldatatex(tex, texvec, texres);
- break;
- case TEX_OCEAN:
- retval = ocean_texture(tex, texvec, texres);
- break;
}
}
@@ -1238,7 +1058,6 @@ static int multitex_nodes_intern(Tex *tex,
TexResult *texres,
const short thread,
short which_output,
- ShadeInput *shi,
MTex *mtex, struct
ImagePool *pool,
const bool scene_color_manage,
@@ -1259,7 +1078,7 @@ static int multitex_nodes_intern(Tex *tex,
if (mtex) {
/* we have mtex, use it for 2d mapping images only */
- do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt);
+ do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
rgbnor = multitex(tex,
texvec,
dxt, dyt,
@@ -1272,7 +1091,7 @@ static int multitex_nodes_intern(Tex *tex,
texnode_preview,
use_nodes);
- if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
+ if (mtex->mapto & (MAP_COL)) {
ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
/* don't linearize float buffers, assumed to be linear */
@@ -1307,7 +1126,7 @@ static int multitex_nodes_intern(Tex *tex,
zero_v3(dyt_l);
}
- do_2d_mapping(&localmtex, texvec_l, NULL, NULL, dxt_l, dyt_l);
+ do_2d_mapping(&localmtex, texvec_l, NULL, dxt_l, dyt_l);
rgbnor = multitex(tex,
texvec_l,
dxt_l, dyt_l,
@@ -1357,41 +1176,15 @@ static int multitex_nodes_intern(Tex *tex,
* Use it from render pipeline only!
*/
int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres,
- const short thread, short which_output, ShadeInput *shi, MTex *mtex, struct ImagePool *pool)
+ const short thread, short which_output, MTex *mtex, struct ImagePool *pool)
{
return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres,
- thread, which_output, shi, mtex, pool, R.scene_color_manage,
- (R.r.scemode & R_NO_IMAGE_LOAD) != 0,
- (R.r.scemode & R_TEXNODE_PREVIEW) != 0,
+ thread, which_output, mtex, pool, true,
+ false,
+ false,
true);
}
-/* this is called for surface shading */
-static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres, struct ImagePool *pool, const bool skip_load_image)
-{
- Tex *tex = mtex->tex;
- /* TODO(sergey): Texture preview should become an argument? */
- if (tex->use_nodes && tex->nodetree) {
- /* stupid exception here .. but we have to pass shi and mtex to
- * textures nodes for 2d mapping and color management for images */
- return ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, shi->osatex, shi->thread,
- tex, mtex->which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, shi, mtex);
- }
- else {
- return multitex(mtex->tex,
- texvec,
- dxt, dyt,
- shi->osatex,
- texres,
- shi->thread,
- mtex->which_output,
- pool,
- skip_load_image,
- (R.r.scemode & R_TEXNODE_PREVIEW) != 0,
- true);
- }
-}
-
/* Warning, if the texres's values are not declared zero, check the return value to be sure
* the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell
*
@@ -1414,7 +1207,7 @@ int multitex_ext(Tex *tex,
texres,
thread,
0,
- NULL, NULL,
+ NULL,
pool,
scene_color_manage,
skip_load_image,
@@ -1435,7 +1228,7 @@ int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct Image
texres,
0,
0,
- NULL, NULL,
+ NULL,
pool,
scene_color_manage,
skip_load_image,
@@ -1652,1949 +1445,6 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen
return in;
}
-static void texco_mapping(ShadeInput *shi, Tex *tex, MTex *mtex,
- const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3])
-{
- /* new: first swap coords, then map, then trans/scale */
- if (tex->type == TEX_IMAGE) {
- /* placement */
- texvec[0] = mtex->projx ? co[mtex->projx - 1] : 0.f;
- texvec[1] = mtex->projy ? co[mtex->projy - 1] : 0.f;
- texvec[2] = mtex->projz ? co[mtex->projz - 1] : 0.f;
-
- if (shi->osatex) {
- if (mtex->projx) {
- dxt[0] = dx[mtex->projx - 1];
- dyt[0] = dy[mtex->projx - 1];
- }
- else dxt[0] = dyt[0] = 0.f;
- if (mtex->projy) {
- dxt[1] = dx[mtex->projy - 1];
- dyt[1] = dy[mtex->projy - 1];
- }
- else dxt[1] = dyt[1] = 0.f;
- if (mtex->projz) {
- dxt[2] = dx[mtex->projz - 1];
- dyt[2] = dy[mtex->projz - 1];
- }
- else dxt[2] = dyt[2] = 0.f;
- }
- do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt);
-
- /* translate and scale */
- texvec[0] = mtex->size[0]*(texvec[0] - 0.5f) + mtex->ofs[0] + 0.5f;
- texvec[1] = mtex->size[1]*(texvec[1] - 0.5f) + mtex->ofs[1] + 0.5f;
- if (shi->osatex) {
- dxt[0] = mtex->size[0] * dxt[0];
- dxt[1] = mtex->size[1] * dxt[1];
- dyt[0] = mtex->size[0] * dyt[0];
- dyt[1] = mtex->size[1] * dyt[1];
- }
-
- /* problem: repeat-mirror is not a 'repeat' but 'extend' in imagetexture.c */
- /* TXF: bug was here, only modify texvec when repeat mode set, old code affected other modes too.
- * New texfilters solve mirroring differently so that it also works correctly when
- * textures are scaled (sizeXYZ) as well as repeated. See also modification in do_2d_mapping().
- * (since currently only done in osa mode, results will look incorrect without osa TODO) */
- if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_XMIR)) {
- if (tex->texfilter == TXF_BOX)
- texvec[0] -= floorf(texvec[0]); /* this line equivalent to old code, same below */
- else if (texvec[0] < 0.f || texvec[0] > 1.f) {
- const float tx = 0.5f*texvec[0];
- texvec[0] = 2.f*(tx - floorf(tx));
- if (texvec[0] > 1.f) texvec[0] = 2.f - texvec[0];
- }
- }
- if (tex->extend == TEX_REPEAT && (tex->flag & TEX_REPEAT_YMIR)) {
- if (tex->texfilter == TXF_BOX)
- texvec[1] -= floorf(texvec[1]);
- else if (texvec[1] < 0.f || texvec[1] > 1.f) {
- const float ty = 0.5f*texvec[1];
- texvec[1] = 2.f*(ty - floorf(ty));
- if (texvec[1] > 1.f) texvec[1] = 2.f - texvec[1];
- }
- }
-
- }
- else { /* procedural */
- /* placement */
- texvec[0] = mtex->size[0]*(mtex->projx ? (co[mtex->projx - 1] + mtex->ofs[0]) : mtex->ofs[0]);
- texvec[1] = mtex->size[1]*(mtex->projy ? (co[mtex->projy - 1] + mtex->ofs[1]) : mtex->ofs[1]);
- texvec[2] = mtex->size[2]*(mtex->projz ? (co[mtex->projz - 1] + mtex->ofs[2]) : mtex->ofs[2]);
-
- if (shi->osatex) {
- if (mtex->projx) {
- dxt[0] = mtex->size[0]*dx[mtex->projx - 1];
- dyt[0] = mtex->size[0]*dy[mtex->projx - 1];
- }
- else dxt[0] = dyt[0] = 0.f;
- if (mtex->projy) {
- dxt[1] = mtex->size[1]*dx[mtex->projy - 1];
- dyt[1] = mtex->size[1]*dy[mtex->projy - 1];
- }
- else dxt[1] = dyt[1] = 0.f;
- if (mtex->projz) {
- dxt[2] = mtex->size[2]*dx[mtex->projz - 1];
- dyt[2] = mtex->size[2]*dy[mtex->projz - 1];
- }
- else dxt[2]= dyt[2] = 0.f;
- }
-
- if (mtex->tex->type == TEX_ENVMAP) {
- EnvMap *env = tex->env;
- if (!env->object) {
- // env->object is a view point for envmap rendering
- // if it's not set, return the result depending on the world_space_shading flag
- if (BKE_scene_use_world_space_shading(R.scene)) {
- mul_mat3_m4_v3(R.viewinv, texvec);
- if (shi->osatex) {
- mul_mat3_m4_v3(R.viewinv, dxt);
- mul_mat3_m4_v3(R.viewinv, dyt);
- }
- }
- }
- }
- }
-}
-
-/* Bump code from 2.5 development cycle, has a number of bugs, but here for compatibility */
-
-typedef struct CompatibleBump {
- float nu[3], nv[3], nn[3];
- float dudnu, dudnv, dvdnu, dvdnv;
- bool nunvdone;
-} CompatibleBump;
-
-static void compatible_bump_init(CompatibleBump *compat_bump)
-{
- memset(compat_bump, 0, sizeof(*compat_bump));
-
- compat_bump->dudnu = 1.0f;
- compat_bump->dvdnv = 1.0f;
-}
-
-static void compatible_bump_uv_derivs(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, int i)
-{
- /* uvmapping only, calculation of normal tangent u/v partial derivatives
- * (should not be here, dudnu, dudnv, dvdnu & dvdnv should probably be part of ShadeInputUV struct,
- * nu/nv in ShadeInput and this calculation should then move to shadeinput.c,
- * shade_input_set_shade_texco() func.) */
-
- /* NOTE: test for shi->obr->ob here,
- * since vlr/obr/obi can be 'fake' when called from fastshade(), another reason to move it.. */
-
- /* 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. */
- if ((mtex->texflag & MTEX_COMPAT_BUMP) && shi->obr && shi->obr->ob && shi->v1) {
- if (mtex->mapto & (MAP_NORM|MAP_WARP) && !((mtex->tex->type==TEX_IMAGE) && (mtex->tex->imaflag & TEX_NORMALMAP))) {
- MTFace* tf = RE_vlakren_get_tface(shi->obr, shi->vlr, i, NULL, 0);
- int j1 = shi->i1, j2 = shi->i2, j3 = shi->i3;
-
- vlr_set_uv_indices(shi->vlr, &j1, &j2, &j3);
-
- /* compute ortho basis around normal */
- if (!compat_bump->nunvdone) {
- /* render normal is negated */
- compat_bump->nn[0] = -shi->vn[0];
- compat_bump->nn[1] = -shi->vn[1];
- compat_bump->nn[2] = -shi->vn[2];
- ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn);
- compat_bump->nunvdone = true;
- }
-
- if (tf) {
- const float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3];
- const float an[3] = {fabsf(compat_bump->nn[0]), fabsf(compat_bump->nn[1]), fabsf(compat_bump->nn[2])};
- const int a1 = (an[0] > an[1] && an[0] > an[2]) ? 1 : 0;
- const int a2 = (an[2] > an[0] && an[2] > an[1]) ? 1 : 2;
- const float dp1_a1 = shi->v1->co[a1] - shi->v3->co[a1];
- const float dp1_a2 = shi->v1->co[a2] - shi->v3->co[a2];
- const float dp2_a1 = shi->v2->co[a1] - shi->v3->co[a1];
- const float dp2_a2 = shi->v2->co[a2] - shi->v3->co[a2];
- const float du1 = uv1[0] - uv3[0], du2 = uv2[0] - uv3[0];
- const float dv1 = uv1[1] - uv3[1], dv2 = uv2[1] - uv3[1];
- const float dpdu_a1 = dv2*dp1_a1 - dv1*dp2_a1;
- const float dpdu_a2 = dv2*dp1_a2 - dv1*dp2_a2;
- const float dpdv_a1 = du1*dp2_a1 - du2*dp1_a1;
- const float dpdv_a2 = du1*dp2_a2 - du2*dp1_a2;
- float d = dpdu_a1*dpdv_a2 - dpdv_a1*dpdu_a2;
- float uvd = du1*dv2 - dv1*du2;
-
- if (uvd == 0.f) uvd = 1e-5f;
- if (d == 0.f) d = 1e-5f;
- d = uvd / d;
-
- compat_bump->dudnu = (dpdv_a2*compat_bump->nu[a1] - dpdv_a1*compat_bump->nu[a2])*d;
- compat_bump->dvdnu = (dpdu_a1*compat_bump->nu[a2] - dpdu_a2*compat_bump->nu[a1])*d;
- compat_bump->dudnv = (dpdv_a2*compat_bump->nv[a1] - dpdv_a1*compat_bump->nv[a2])*d;
- compat_bump->dvdnv = (dpdu_a1*compat_bump->nv[a2] - dpdu_a2*compat_bump->nv[a1])*d;
- }
- }
- }
-}
-
-static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres,
- float Tnor, const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3],
- struct ImagePool *pool, const bool skip_load_image)
-{
- TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */
- float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv;
- const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
- const float bf = -0.04f*Tnor*mtex->norfac;
- int rgbnor;
- /* disable internal bump eval */
- float *nvec = texres->nor;
- texres->nor = NULL;
- /* du & dv estimates, constant value defaults */
- du = dv = 0.01f;
-
- /* compute ortho basis around normal */
- if (!compat_bump->nunvdone) {
- /* render normal is negated */
- negate_v3_v3(compat_bump->nn, shi->vn);
- ortho_basis_v3v3_v3(compat_bump->nu, compat_bump->nv, compat_bump->nn);
- compat_bump->nunvdone = true;
- }
-
- /* two methods, either constant based on main image resolution,
- * (which also works without osa, though of course not always good (or even very bad) results),
- * or based on tex derivative max values (osa only). Not sure which is best... */
-
- if (!shi->osatex && (tex->type == TEX_IMAGE) && tex->ima) {
- /* in case we have no proper derivatives, fall back to
- * computing du/dv it based on image size */
- ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
- if (ibuf) {
- du = 1.f/(float)ibuf->x;
- dv = 1.f/(float)ibuf->y;
- }
- BKE_image_pool_release_ibuf(tex->ima, ibuf, pool);
- }
- else if (shi->osatex) {
- /* we have derivatives, can compute proper du/dv */
- if (tex->type == TEX_IMAGE) { /* 2d image, use u & v max. of dx/dy 2d vecs */
- const float adx[2] = {fabsf(dx[0]), fabsf(dx[1])};
- const float ady[2] = {fabsf(dy[0]), fabsf(dy[1])};
- du = MAX2(adx[0], ady[0]);
- dv = MAX2(adx[1], ady[1]);
- }
- else { /* 3d procedural, estimate from all dx/dy elems */
- const float adx[3] = {fabsf(dx[0]), fabsf(dx[1]), fabsf(dx[2])};
- const float ady[3] = {fabsf(dy[0]), fabsf(dy[1]), fabsf(dy[2])};
- du = max_fff(adx[0], adx[1], adx[2]);
- dv = max_fff(ady[0], ady[1], ady[2]);
- }
- }
-
- /* center, main return value */
- texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
- rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool, skip_load_image);
- cd = fromrgb ? (texres->tr + texres->tg + texres->tb) / 3.0f : texres->tin;
-
- if (mtex->texco == TEXCO_UV) {
- /* for the uv case, use the same value for both du/dv,
- * since individually scaling the normal derivatives makes them useless... */
- du = min_ff(du, dv);
- idu = (du < 1e-5f) ? bf : (bf/du);
-
- /* +u val */
- tco[0] = co[0] + compat_bump->dudnu*du;
- tco[1] = co[1] + compat_bump->dvdnu*du;
- tco[2] = 0.f;
- texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
- multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image);
- ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
-
- /* +v val */
- tco[0] = co[0] + compat_bump->dudnv*du;
- tco[1] = co[1] + compat_bump->dvdnv*du;
- tco[2] = 0.f;
- texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
- multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image);
- vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
- }
- else {
- float tu[3], tv[3];
-
- copy_v3_v3(tu, compat_bump->nu);
- copy_v3_v3(tv, compat_bump->nv);
-
- idu = (du < 1e-5f) ? bf : (bf/du);
- idv = (dv < 1e-5f) ? bf : (bf/dv);
-
- if ((mtex->texco == TEXCO_ORCO) && shi->obr && shi->obr->ob) {
- mul_mat3_m4_v3(shi->obr->ob->imat_ren, tu);
- mul_mat3_m4_v3(shi->obr->ob->imat_ren, tv);
- normalize_v3(tu);
- normalize_v3(tv);
- }
- else if (mtex->texco == TEXCO_GLOB) {
- mul_mat3_m4_v3(R.viewinv, tu);
- mul_mat3_m4_v3(R.viewinv, tv);
- }
- else if (mtex->texco == TEXCO_OBJECT && mtex->object) {
- mul_mat3_m4_v3(mtex->object->imat_ren, tu);
- mul_mat3_m4_v3(mtex->object->imat_ren, tv);
- normalize_v3(tu);
- normalize_v3(tv);
- }
-
- /* +u val */
- tco[0] = co[0] + tu[0]*du;
- tco[1] = co[1] + tu[1]*du;
- tco[2] = co[2] + tu[2]*du;
- texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
- multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image);
- ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
-
- /* +v val */
- tco[0] = co[0] + tv[0]*dv;
- tco[1] = co[1] + tv[1]*dv;
- tco[2] = co[2] + tv[2]*dv;
- texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
- multitex_mtex(shi, mtex, texv, dxt, dyt, &ttexr, pool, skip_load_image);
- vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb) / 3.0f : ttexr.tin));
- }
-
- /* bumped normal */
- compat_bump->nu[0] += ud*compat_bump->nn[0];
- compat_bump->nu[1] += ud*compat_bump->nn[1];
- compat_bump->nu[2] += ud*compat_bump->nn[2];
- compat_bump->nv[0] += vd*compat_bump->nn[0];
- compat_bump->nv[1] += vd*compat_bump->nn[1];
- compat_bump->nv[2] += vd*compat_bump->nn[2];
- cross_v3_v3v3(nvec, compat_bump->nu, compat_bump->nv);
-
- nvec[0] = -nvec[0];
- nvec[1] = -nvec[1];
- nvec[2] = -nvec[2];
- texres->nor = nvec;
-
- rgbnor |= TEX_NOR;
- return rgbnor;
-}
-
-/* Improved bump code from later in 2.5 development cycle */
-
-typedef struct NTapBump {
- int init_done;
- int iPrevBumpSpace; /* 0: uninitialized, 1: objectspace, 2: texturespace, 4: viewspace */
- /* bumpmapping */
- float vNorg[3]; /* backup copy of shi->vn */
- float vNacc[3]; /* original surface normal minus the surface gradient of every bump map which is encountered */
- float vR1[3], vR2[3]; /* cross products (sigma_y, original_normal), (original_normal, sigma_x) */
- float sgn_det; /* sign of the determinant of the matrix {sigma_x, sigma_y, original_normal} */
- float fPrevMagnitude; /* copy of previous magnitude, used for multiple bumps in different spaces */
-} NTapBump;
-
-static void ntap_bump_init(NTapBump *ntap_bump)
-{
- memset(ntap_bump, 0, sizeof(*ntap_bump));
-}
-
-static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres,
- float Tnor, const float co[3], const float dx[3], const float dy[3],
- float texvec[3], float dxt[3], float dyt[3], struct ImagePool *pool,
- const bool skip_load_image)
-{
- TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */
-
- const int fromrgb = ((tex->type == TEX_IMAGE) || ((tex->flag & TEX_COLORBAND)!=0));
-
- /* The negate on Hscale is done because the
- * normal in the renderer points inward which corresponds
- * to inverting the bump map. The normals are generated
- * this way in calc_vertexnormals(). Should this ever change
- * this negate must be removed. */
- float Hscale = -Tnor*mtex->norfac;
-
- int dimx=512, dimy=512;
- const int imag_tspace_dimension_x = 1024; /* only used for texture space variant */
- float aspect = 1.0f;
-
- /* 2 channels for 2D texture and 3 for 3D textures. */
- const int nr_channels = (mtex->texco == TEXCO_UV)? 2 : 3;
- int c, rgbnor, iBumpSpace;
- float dHdx, dHdy;
- int found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP);
-
- /* disable internal bump eval in sampler, save pointer */
- float *nvec = texres->nor;
- texres->nor = NULL;
-
- if (found_deriv_map==0) {
- if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
- if (tex->ima)
- Hscale *= 13.0f; /* appears to be a sensible default value */
- }
- else
- Hscale *= 0.1f; /* factor 0.1 proved to look like the previous bump code */
- }
-
- if ( !ntap_bump->init_done ) {
- copy_v3_v3(ntap_bump->vNacc, shi->vn);
- copy_v3_v3(ntap_bump->vNorg, shi->vn);
- ntap_bump->fPrevMagnitude = 1.0f;
- ntap_bump->iPrevBumpSpace = 0;
-
- ntap_bump->init_done = true;
- }
-
- /* resolve image dimensions */
- if (found_deriv_map || (mtex->texflag&MTEX_BUMP_TEXTURESPACE)!=0) {
- ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
- if (ibuf) {
- dimx = ibuf->x;
- dimy = ibuf->y;
- aspect = ((float) dimy) / dimx;
- }
- BKE_image_pool_release_ibuf(tex->ima, ibuf, pool);
- }
-
- if (found_deriv_map) {
- float dBdu, dBdv, auto_bump = 1.0f;
- float s = 1; /* negate this if flipped texture coordinate */
- texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
- rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, texres, pool, skip_load_image);
-
- if (shi->obr->ob->derivedFinal) {
- auto_bump = shi->obr->ob->derivedFinal->auto_bump_scale;
- }
-
- {
- float fVirtDim = sqrtf(fabsf((float) (dimx*dimy)*mtex->size[0]*mtex->size[1]));
- auto_bump /= MAX2(fVirtDim, FLT_EPSILON);
- }
-
- /* this variant using a derivative map is described here
- * http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html */
- dBdu = auto_bump*Hscale*dimx*(2*texres->tr-1);
- dBdv = auto_bump*Hscale*dimy*(2*texres->tg-1);
-
- dHdx = dBdu*dxt[0] + s * dBdv*dxt[1];
- dHdy = dBdu*dyt[0] + s * dBdv*dyt[1];
- }
- else if (!(mtex->texflag & MTEX_5TAP_BUMP)) {
- /* compute height derivatives with respect to output image pixel coordinates x and y */
- float STll[3], STlr[3], STul[3];
- float Hll, Hlr, Hul;
-
- texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
-
- for (c=0; c<nr_channels; c++) {
- /* dx contains the derivatives (du/dx, dv/dx)
- * dy contains the derivatives (du/dy, dv/dy) */
- STll[c] = texvec[c];
- STlr[c] = texvec[c]+dxt[c];
- STul[c] = texvec[c]+dyt[c];
- }
-
- /* clear unused derivatives */
- for (c=nr_channels; c<3; c++) {
- STll[c] = 0.0f;
- STlr[c] = 0.0f;
- STul[c] = 0.0f;
- }
-
- /* use texres for the center sample, set rgbnor */
- rgbnor = multitex_mtex(shi, mtex, STll, dxt, dyt, texres, pool, skip_load_image);
- Hll = (fromrgb) ? IMB_colormanagement_get_luminance(&texres->tr) : texres->tin;
-
- /* use ttexr for the other 2 taps */
- multitex_mtex(shi, mtex, STlr, dxt, dyt, &ttexr, pool, skip_load_image);
- Hlr = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin;
-
- multitex_mtex(shi, mtex, STul, dxt, dyt, &ttexr, pool, skip_load_image);
- Hul = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin;
-
- dHdx = Hscale*(Hlr - Hll);
- dHdy = Hscale*(Hul - Hll);
- }
- else {
- /* same as above, but doing 5 taps, increasing quality at cost of speed */
- float STc[3], STl[3], STr[3], STd[3], STu[3];
- float /* Hc, */ /* UNUSED */ Hl, Hr, Hd, Hu;
-
- texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
-
- for (c=0; c<nr_channels; c++) {
- STc[c] = texvec[c];
- STl[c] = texvec[c] - 0.5f*dxt[c];
- STr[c] = texvec[c] + 0.5f*dxt[c];
- STd[c] = texvec[c] - 0.5f*dyt[c];
- STu[c] = texvec[c] + 0.5f*dyt[c];
- }
-
- /* clear unused derivatives */
- for (c=nr_channels; c<3; c++) {
- STc[c] = 0.0f;
- STl[c] = 0.0f;
- STr[c] = 0.0f;
- STd[c] = 0.0f;
- STu[c] = 0.0f;
- }
-
- /* use texres for the center sample, set rgbnor */
- rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres, pool, skip_load_image);
- /* Hc = (fromrgb) ? IMB_colormanagement_get_luminance(&texres->tr) : texres->tin; */ /* UNUSED */
-
- /* use ttexr for the other taps */
- multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr, pool, skip_load_image);
- Hl = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin;
- multitex_mtex(shi, mtex, STr, dxt, dyt, &ttexr, pool, skip_load_image);
- Hr = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin;
- multitex_mtex(shi, mtex, STd, dxt, dyt, &ttexr, pool, skip_load_image);
- Hd = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin;
- multitex_mtex(shi, mtex, STu, dxt, dyt, &ttexr, pool, skip_load_image);
- Hu = (fromrgb) ? IMB_colormanagement_get_luminance(&ttexr.tr) : ttexr.tin;
-
- dHdx = Hscale*(Hr - Hl);
- dHdy = Hscale*(Hu - Hd);
- }
-
- /* restore pointer */
- texres->nor = nvec;
-
- /* replaced newbump with code based on listing 1 and 2 of
- * [Mik10] Mikkelsen M. S.: Bump Mapping Unparameterized Surfaces on the GPU.
- * -> http://jbit.net/~sparky/sfgrad_bump/mm_sfgrad_bump.pdf */
-
- if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE )
- iBumpSpace = 1;
- else if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE )
- iBumpSpace = 2;
- else
- iBumpSpace = 4; /* ViewSpace */
-
- if ( ntap_bump->iPrevBumpSpace != iBumpSpace ) {
-
- /* initialize normal perturbation vectors */
- int xyz;
- float fDet, abs_fDet, fMagnitude;
- /* object2view and inverted matrix */
- float obj2view[3][3], view2obj[3][3], tmp[4][4];
- /* local copies of derivatives and normal */
- float dPdx[3], dPdy[3], vN[3];
- copy_v3_v3(dPdx, shi->dxco);
- copy_v3_v3(dPdy, shi->dyco);
- copy_v3_v3(vN, ntap_bump->vNorg);
-
- if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) {
- /* TODO: these calculations happen for every pixel!
- * -> move to shi->obi */
- mul_m4_m4m4(tmp, R.viewmat, shi->obr->ob->obmat);
- copy_m3_m4(obj2view, tmp); /* use only upper left 3x3 matrix */
- invert_m3_m3(view2obj, obj2view);
-
- /* generate the surface derivatives in object space */
- mul_m3_v3(view2obj, dPdx);
- mul_m3_v3(view2obj, dPdy);
- /* generate the unit normal in object space */
- mul_transposed_m3_v3(obj2view, vN);
- normalize_v3(vN);
- }
-
- cross_v3_v3v3(ntap_bump->vR1, dPdy, vN);
- cross_v3_v3v3(ntap_bump->vR2, vN, dPdx);
- fDet = dot_v3v3(dPdx, ntap_bump->vR1);
- ntap_bump->sgn_det = (fDet < 0)? -1.0f: 1.0f;
- abs_fDet = ntap_bump->sgn_det * fDet;
-
- if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
- if (tex->ima) {
- /* crazy hack solution that gives results similar to normal mapping - part 1 */
- normalize_v3(ntap_bump->vR1);
- normalize_v3(ntap_bump->vR2);
- abs_fDet = 1.0f;
- }
- }
-
- fMagnitude = abs_fDet;
- if ( mtex->texflag & MTEX_BUMP_OBJECTSPACE ) {
- /* pre do transform of texres->nor by the inverse transposed of obj2view */
- mul_transposed_m3_v3(view2obj, vN);
- mul_transposed_m3_v3(view2obj, ntap_bump->vR1);
- mul_transposed_m3_v3(view2obj, ntap_bump->vR2);
-
- fMagnitude *= len_v3(vN);
- }
-
- if (ntap_bump->fPrevMagnitude > 0.0f)
- for (xyz=0; xyz<3; xyz++)
- ntap_bump->vNacc[xyz] *= fMagnitude / ntap_bump->fPrevMagnitude;
-
- ntap_bump->fPrevMagnitude = fMagnitude;
- ntap_bump->iPrevBumpSpace = iBumpSpace;
- }
-
- if ( mtex->texflag & MTEX_BUMP_TEXTURESPACE ) {
- if (tex->ima) {
- /* crazy hack solution that gives results similar to normal mapping - part 2 */
- float vec[2];
- const float imag_tspace_dimension_y = aspect*imag_tspace_dimension_x;
-
- vec[0] = imag_tspace_dimension_x*dxt[0];
- vec[1] = imag_tspace_dimension_y*dxt[1];
- dHdx *= 1.0f/len_v2(vec);
- vec[0] = imag_tspace_dimension_x*dyt[0];
- vec[1] = imag_tspace_dimension_y*dyt[1];
- dHdy *= 1.0f/len_v2(vec);
- }
- }
-
- /* subtract the surface gradient from vNacc */
- for (c=0; c<3; c++) {
- float vSurfGrad_compi = ntap_bump->sgn_det * (dHdx * ntap_bump->vR1[c] + dHdy * ntap_bump->vR2[c]);
- ntap_bump->vNacc[c] -= vSurfGrad_compi;
- texres->nor[c] = ntap_bump->vNacc[c]; /* copy */
- }
-
- rgbnor |= TEX_NOR;
- return rgbnor;
-}
-
-void do_material_tex(ShadeInput *shi, Render *re)
-{
- const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0;
- CompatibleBump compat_bump;
- NTapBump ntap_bump;
- MTex *mtex;
- Tex *tex;
- TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
- float *co = NULL, *dx = NULL, *dy = NULL;
- float fact, facm, factt, facmm, stencilTin=1.0;
- float texvec[3], dxt[3], dyt[3], tempvec[3], norvec[3], warpvec[3]={0.0f, 0.0f, 0.0f}, Tnor=1.0;
- int tex_nr, rgbnor= 0;
- bool warp_done = false, use_compat_bump = false, use_ntap_bump = false;
- bool found_nmapping = false, found_deriv_map = false;
- bool iFirstTimeNMap = true;
-
- compatible_bump_init(&compat_bump);
- ntap_bump_init(&ntap_bump);
-
- if (re->r.scemode & R_NO_TEX) return;
- /* here: test flag if there's a tex (todo) */
-
- for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
-
- /* separate tex switching */
- if (shi->mat->septex & (1<<tex_nr)) continue;
-
- if (shi->mat->mtex[tex_nr]) {
- mtex= shi->mat->mtex[tex_nr];
-
- tex= mtex->tex;
- if (tex == NULL) continue;
-
- found_deriv_map = (tex->type==TEX_IMAGE) && (tex->imaflag & TEX_DERIVATIVEMAP);
- use_compat_bump= (mtex->texflag & MTEX_COMPAT_BUMP) != 0;
- use_ntap_bump = ((mtex->texflag & (MTEX_3TAP_BUMP|MTEX_5TAP_BUMP|MTEX_BICUBIC_BUMP))!=0 || found_deriv_map!=0) ? true : false;
-
- /* XXX texture node trees don't work for this yet */
- if (tex->nodetree && tex->use_nodes) {
- use_compat_bump = false;
- use_ntap_bump = false;
- }
-
- /* case displacement mapping */
- if (shi->osatex == 0 && use_ntap_bump) {
- use_ntap_bump = false;
- use_compat_bump = true;
- }
-
- /* case ocean */
- if (tex->type == TEX_OCEAN) {
- use_ntap_bump = false;
- use_compat_bump = false;
- }
-
- /* which coords */
- if (mtex->texco==TEXCO_ORCO) {
- if (mtex->texflag & MTEX_DUPLI_MAPTO) {
- co= shi->duplilo; dx= dxt; dy= dyt;
- dxt[0]= dxt[1]= dxt[2]= 0.0f;
- dyt[0]= dyt[1]= dyt[2]= 0.0f;
- }
- else {
- co= shi->lo; dx= shi->dxlo; dy= shi->dylo;
- }
- }
- else if (mtex->texco==TEXCO_OBJECT) {
- Object *ob= mtex->object;
- if (ob) {
- co= tempvec;
- dx= dxt;
- dy= dyt;
- copy_v3_v3(tempvec, shi->co);
- if (mtex->texflag & MTEX_OB_DUPLI_ORIG)
- if (shi->obi && shi->obi->duplitexmat)
- mul_m4_v3(shi->obi->duplitexmat, tempvec);
- mul_m4_v3(ob->imat_ren, tempvec);
- if (shi->osatex) {
- copy_v3_v3(dxt, shi->dxco);
- copy_v3_v3(dyt, shi->dyco);
- mul_mat3_m4_v3(ob->imat_ren, dxt);
- mul_mat3_m4_v3(ob->imat_ren, dyt);
- }
- }
- else {
- /* if object doesn't exist, do not use orcos (not initialized) */
- co= shi->co;
- dx= shi->dxco; dy= shi->dyco;
- }
- }
- else if (mtex->texco==TEXCO_REFL) {
- calc_R_ref(shi);
- co= shi->ref; dx= shi->dxref; dy= shi->dyref;
- }
- else if (mtex->texco==TEXCO_NORM) {
- co= shi->orn; dx= shi->dxno; dy= shi->dyno;
- }
- else if (mtex->texco==TEXCO_TANGENT) {
- co= shi->tang; dx= shi->dxno; dy= shi->dyno;
- }
- else if (mtex->texco==TEXCO_GLOB) {
- co= shi->gl; dx= shi->dxgl; dy= shi->dygl;
- }
- else if (mtex->texco==TEXCO_UV) {
- if (mtex->texflag & MTEX_DUPLI_MAPTO) {
- co= shi->dupliuv; dx= dxt; dy= dyt;
- dxt[0]= dxt[1]= dxt[2]= 0.0f;
- dyt[0]= dyt[1]= dyt[2]= 0.0f;
- }
- else {
- ShadeInputUV *suv= &shi->uv[shi->actuv];
- int i = shi->actuv;
-
- if (mtex->uvname[0] != 0) {
- for (i = 0; i < shi->totuv; i++) {
- if (STREQ(shi->uv[i].name, mtex->uvname)) {
- suv= &shi->uv[i];
- break;
- }
- }
- }
-
- co= suv->uv;
- dx= suv->dxuv;
- dy= suv->dyuv;
-
- compatible_bump_uv_derivs(&compat_bump, shi, mtex, i);
- }
- }
- else if (mtex->texco==TEXCO_WINDOW) {
- co= shi->winco; dx= shi->dxwin; dy= shi->dywin;
- }
- else if (mtex->texco==TEXCO_STRAND) {
- co= tempvec; dx= dxt; dy= dyt;
- co[0]= shi->strandco;
- co[1]= co[2]= 0.0f;
- dx[0]= shi->dxstrand;
- dx[1]= dx[2]= 0.0f;
- dy[0]= shi->dystrand;
- dy[1]= dy[2]= 0.0f;
- }
- else if (mtex->texco==TEXCO_STRESS) {
- co= tempvec; dx= dxt; dy= dyt;
- co[0]= shi->stress;
- co[1]= co[2]= 0.0f;
- dx[0]= 0.0f;
- dx[1]= dx[2]= 0.0f;
- dy[0]= 0.0f;
- dy[1]= dy[2]= 0.0f;
- }
- else {
- continue; /* can happen when texco defines disappear and it renders old files */
- }
-
- /* the pointer defines if bumping happens */
- if (mtex->mapto & (MAP_NORM|MAP_WARP)) {
- texres.nor= norvec;
- norvec[0]= norvec[1]= norvec[2]= 0.0;
- }
- else texres.nor= NULL;
-
- if (warp_done) {
- add_v3_v3v3(tempvec, co, warpvec);
- co= tempvec;
- }
-
- /* XXX texture node trees don't work for this yet */
- if (texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) {
- if (use_compat_bump) {
- rgbnor = compatible_bump_compute(&compat_bump, shi, mtex, tex,
- &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt,
- re->pool, skip_load_image);
- }
- else if (use_ntap_bump) {
- rgbnor = ntap_bump_compute(&ntap_bump, shi, mtex, tex,
- &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt,
- re->pool, skip_load_image);
- }
- else {
- texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
- rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool, skip_load_image);
- }
- }
- else {
- texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
- rgbnor = multitex_mtex(shi, mtex, texvec, dxt, dyt, &texres, re->pool, skip_load_image);
- }
-
- /* texture output */
-
- if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
- texres.tin = IMB_colormanagement_get_luminance(&texres.tr);
- rgbnor -= TEX_RGB;
- }
- if (mtex->texflag & MTEX_NEGATIVE) {
- if (rgbnor & TEX_RGB) {
- texres.tr= 1.0f-texres.tr;
- texres.tg= 1.0f-texres.tg;
- texres.tb= 1.0f-texres.tb;
- }
- texres.tin= 1.0f-texres.tin;
- }
- if (mtex->texflag & MTEX_STENCIL) {
- if (rgbnor & TEX_RGB) {
- fact= texres.ta;
- texres.ta*= stencilTin;
- stencilTin*= fact;
- }
- else {
- fact= texres.tin;
- texres.tin*= stencilTin;
- stencilTin*= fact;
- }
- }
- else {
- Tnor*= stencilTin;
- }
-
- if (texres.nor) {
- if ((rgbnor & TEX_NOR)==0) {
- /* make our own normal */
- if (rgbnor & TEX_RGB) {
- copy_v3_v3(texres.nor, &texres.tr);
- }
- else {
- float co_nor= 0.5f * cosf(texres.tin - 0.5f);
- float si = 0.5f * sinf(texres.tin - 0.5f);
- float f1, f2;
-
- f1= shi->vn[0];
- f2= shi->vn[1];
- texres.nor[0]= f1*co_nor+f2*si;
- f1= shi->vn[1];
- f2= shi->vn[2];
- texres.nor[1]= f1*co_nor+f2*si;
- texres.nor[2]= f2*co_nor-f1*si;
- }
- }
- /* warping, local space */
- if (mtex->mapto & MAP_WARP) {
- float *warpnor= texres.nor, warpnor_[3];
-
- if (use_ntap_bump) {
- copy_v3_v3(warpnor_, texres.nor);
- warpnor= warpnor_;
- normalize_v3(warpnor_);
- }
- warpvec[0]= mtex->warpfac*warpnor[0];
- warpvec[1]= mtex->warpfac*warpnor[1];
- warpvec[2]= mtex->warpfac*warpnor[2];
- warp_done = true;
- }
-#if 0
- if (mtex->texflag & MTEX_VIEWSPACE) {
- /* rotate to global coords */
- if (mtex->texco==TEXCO_ORCO || mtex->texco==TEXCO_UV) {
- if (shi->vlr && shi->obr && shi->obr->ob) {
- float len= normalize_v3(texres.nor);
- /* can be optimized... (ton) */
- mul_mat3_m4_v3(shi->obr->ob->obmat, texres.nor);
- mul_mat3_m4_v3(re->viewmat, texres.nor);
- normalize_v3_length(texres.nor, len);
- }
- }
- }
-#endif
- }
-
- /* mapping */
- if (mtex->mapto & (MAP_COL | MAP_COLSPEC | MAP_COLMIR)) {
- float tcol[3];
-
- /* stencil maps on the texture control slider, not texture intensity value */
- copy_v3_v3(tcol, &texres.tr);
-
- if ((rgbnor & TEX_RGB) == 0) {
- copy_v3_v3(tcol, &mtex->r);
- }
- else if (mtex->mapto & MAP_ALPHA) {
- texres.tin = stencilTin;
- }
- else {
- texres.tin = texres.ta;
- }
-
- /* inverse gamma correction */
- if (tex->type==TEX_IMAGE) {
- Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, re->pool);
-
- /* don't linearize float buffers, assumed to be linear */
- if (ibuf != NULL &&
- ibuf->rect_float == NULL &&
- (rgbnor & TEX_RGB) &&
- R.scene_color_manage)
- {
- IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace);
- }
-
- BKE_image_pool_release_ibuf(ima, ibuf, re->pool);
- }
-
- if (mtex->mapto & MAP_COL) {
- float colfac= mtex->colfac*stencilTin;
- texture_rgb_blend(&shi->r, tcol, &shi->r, texres.tin, colfac, mtex->blendtype);
- }
- if (mtex->mapto & MAP_COLSPEC) {
- float colspecfac= mtex->colspecfac*stencilTin;
- texture_rgb_blend(&shi->specr, tcol, &shi->specr, texres.tin, colspecfac, mtex->blendtype);
- }
- if (mtex->mapto & MAP_COLMIR) {
- float mirrfac= mtex->mirrfac*stencilTin;
-
- /* exception for envmap only */
- if (tex->type==TEX_ENVMAP && mtex->blendtype==MTEX_BLEND) {
- fact= texres.tin*mirrfac;
- facm= 1.0f- fact;
- shi->refcol[0]= fact + facm*shi->refcol[0];
- shi->refcol[1]= fact*tcol[0] + facm*shi->refcol[1];
- shi->refcol[2]= fact*tcol[1] + facm*shi->refcol[2];
- shi->refcol[3]= fact*tcol[2] + facm*shi->refcol[3];
- }
- else {
- texture_rgb_blend(&shi->mirr, tcol, &shi->mirr, texres.tin, mirrfac, mtex->blendtype);
- }
- }
- }
- if ( (mtex->mapto & MAP_NORM) ) {
- if (texres.nor) {
- float norfac= mtex->norfac;
-
- /* we need to code blending modes for normals too once.. now 1 exception hardcoded */
-
- if ((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP)) {
-
- found_nmapping = 1;
-
- /* qdn: for normalmaps, to invert the normalmap vector,
- * it is better to negate x & y instead of subtracting the vector as was done before */
- if (norfac < 0.0f) {
- texres.nor[0] = -texres.nor[0];
- texres.nor[1] = -texres.nor[1];
- }
- fact = Tnor*fabsf(norfac);
- if (fact>1.f) fact = 1.f;
- facm = 1.f-fact;
- if (mtex->normapspace == MTEX_NSPACE_TANGENT) {
- /* qdn: tangent space */
- float B[3], tv[3];
- const float *no = iFirstTimeNMap ? shi->nmapnorm : shi->vn;
- iFirstTimeNMap = false;
- cross_v3_v3v3(B, no, shi->nmaptang); /* bitangent */
- mul_v3_fl(B, shi->nmaptang[3]);
- /* transform norvec from tangent space to object surface in camera space */
- tv[0] = texres.nor[0]*shi->nmaptang[0] + texres.nor[1]*B[0] + texres.nor[2]*no[0];
- tv[1] = texres.nor[0]*shi->nmaptang[1] + texres.nor[1]*B[1] + texres.nor[2]*no[1];
- tv[2] = texres.nor[0]*shi->nmaptang[2] + texres.nor[1]*B[2] + texres.nor[2]*no[2];
- shi->vn[0]= facm*no[0] + fact*tv[0];
- shi->vn[1]= facm*no[1] + fact*tv[1];
- shi->vn[2]= facm*no[2] + fact*tv[2];
- }
- else {
- float nor[3];
-
- copy_v3_v3(nor, texres.nor);
-
- if (mtex->normapspace == MTEX_NSPACE_CAMERA) {
- /* pass */
- }
- else if (mtex->normapspace == MTEX_NSPACE_WORLD) {
- mul_mat3_m4_v3(re->viewmat, nor);
- }
- else if (mtex->normapspace == MTEX_NSPACE_OBJECT) {
- if (shi->obr && shi->obr->ob)
- mul_mat3_m4_v3(shi->obr->ob->obmat, nor);
- mul_mat3_m4_v3(re->viewmat, nor);
- }
-
- normalize_v3(nor);
-
- /* qdn: worldspace */
- shi->vn[0]= facm*shi->vn[0] + fact*nor[0];
- shi->vn[1]= facm*shi->vn[1] + fact*nor[1];
- shi->vn[2]= facm*shi->vn[2] + fact*nor[2];
- }
- }
- else {
- /* XXX texture node trees don't work for this yet */
- if (use_compat_bump || use_ntap_bump) {
- shi->vn[0] = texres.nor[0];
- shi->vn[1] = texres.nor[1];
- shi->vn[2] = texres.nor[2];
- }
- else {
- float nor[3], dot;
-
- if (shi->mat->mode & MA_TANGENT_V) {
- shi->tang[0]+= Tnor*norfac*texres.nor[0];
- shi->tang[1]+= Tnor*norfac*texres.nor[1];
- shi->tang[2]+= Tnor*norfac*texres.nor[2];
- }
-
- /* prevent bump to become negative normal */
- nor[0]= Tnor*norfac*texres.nor[0];
- nor[1]= Tnor*norfac*texres.nor[1];
- nor[2]= Tnor*norfac*texres.nor[2];
-
- dot= 0.5f + 0.5f * dot_v3v3(nor, shi->vn);
-
- shi->vn[0]+= dot*nor[0];
- shi->vn[1]+= dot*nor[1];
- shi->vn[2]+= dot*nor[2];
- }
- }
- normalize_v3(shi->vn);
-
- /* this makes sure the bump is passed on to the next texture */
- shi->orn[0]= -shi->vn[0];
- shi->orn[1]= -shi->vn[1];
- shi->orn[2]= -shi->vn[2];
- }
- }
-
- if ( mtex->mapto & MAP_DISPLACE ) {
- /* Now that most textures offer both Nor and Intensity, allow */
- /* both to work, and let user select with slider. */
- if (texres.nor) {
- float norfac= mtex->norfac;
-
- shi->displace[0]+= 0.2f*Tnor*norfac*texres.nor[0];
- shi->displace[1]+= 0.2f*Tnor*norfac*texres.nor[1];
- shi->displace[2]+= 0.2f*Tnor*norfac*texres.nor[2];
- }
-
- if (rgbnor & TEX_RGB) {
- texres.tin = IMB_colormanagement_get_luminance(&texres.tr);
- }
-
- factt= (0.5f-texres.tin)*mtex->dispfac*stencilTin; facmm= 1.0f-factt;
-
- if (mtex->blendtype==MTEX_BLEND) {
- shi->displace[0]= factt*shi->vn[0] + facmm*shi->displace[0];
- shi->displace[1]= factt*shi->vn[1] + facmm*shi->displace[1];
- shi->displace[2]= factt*shi->vn[2] + facmm*shi->displace[2];
- }
- else if (mtex->blendtype==MTEX_MUL) {
- shi->displace[0]*= factt*shi->vn[0];
- shi->displace[1]*= factt*shi->vn[1];
- shi->displace[2]*= factt*shi->vn[2];
- }
- else { /* add or sub */
- if (mtex->blendtype==MTEX_SUB) factt= -factt;
- shi->displace[0]+= factt*shi->vn[0];
- shi->displace[1]+= factt*shi->vn[1];
- shi->displace[2]+= factt*shi->vn[2];
- }
- }
-
- if (mtex->mapto & MAP_VARS) {
- /* stencil maps on the texture control slider, not texture intensity value */
-
- if (rgbnor & TEX_RGB) {
- if (texres.talpha) texres.tin = texres.ta;
- else texres.tin = IMB_colormanagement_get_luminance(&texres.tr);
- }
-
- if (mtex->mapto & MAP_REF) {
- float difffac= mtex->difffac*stencilTin;
-
- shi->refl= texture_value_blend(mtex->def_var, shi->refl, texres.tin, difffac, mtex->blendtype);
- if (shi->refl<0.0f) shi->refl= 0.0f;
- }
- if (mtex->mapto & MAP_SPEC) {
- float specfac= mtex->specfac*stencilTin;
-
- shi->spec= texture_value_blend(mtex->def_var, shi->spec, texres.tin, specfac, mtex->blendtype);
- if (shi->spec<0.0f) shi->spec= 0.0f;
- }
- if (mtex->mapto & MAP_EMIT) {
- float emitfac= mtex->emitfac*stencilTin;
-
- shi->emit= texture_value_blend(mtex->def_var, shi->emit, texres.tin, emitfac, mtex->blendtype);
- if (shi->emit<0.0f) shi->emit= 0.0f;
- }
- if (mtex->mapto & MAP_ALPHA) {
- float alphafac= mtex->alphafac*stencilTin;
-
- shi->alpha= texture_value_blend(mtex->def_var, shi->alpha, texres.tin, alphafac, mtex->blendtype);
- if (shi->alpha<0.0f) shi->alpha= 0.0f;
- else if (shi->alpha>1.0f) shi->alpha= 1.0f;
- }
- if (mtex->mapto & MAP_HAR) {
- float har; /* have to map to 0-1 */
- float hardfac= mtex->hardfac*stencilTin;
-
- har= ((float)shi->har)/128.0f;
- har= 128.0f*texture_value_blend(mtex->def_var, har, texres.tin, hardfac, mtex->blendtype);
-
- if (har<1.0f) shi->har= 1;
- else if (har>511) shi->har= 511;
- else shi->har= (int)har;
- }
- if (mtex->mapto & MAP_RAYMIRR) {
- float raymirrfac= mtex->raymirrfac*stencilTin;
-
- shi->ray_mirror= texture_value_blend(mtex->def_var, shi->ray_mirror, texres.tin, raymirrfac, mtex->blendtype);
- if (shi->ray_mirror<0.0f) shi->ray_mirror= 0.0f;
- else if (shi->ray_mirror>1.0f) shi->ray_mirror= 1.0f;
- }
- if (mtex->mapto & MAP_TRANSLU) {
- float translfac= mtex->translfac*stencilTin;
-
- shi->translucency= texture_value_blend(mtex->def_var, shi->translucency, texres.tin, translfac, mtex->blendtype);
- if (shi->translucency<0.0f) shi->translucency= 0.0f;
- else if (shi->translucency>1.0f) shi->translucency= 1.0f;
- }
- if (mtex->mapto & MAP_AMB) {
- float ambfac= mtex->ambfac*stencilTin;
-
- shi->amb= texture_value_blend(mtex->def_var, shi->amb, texres.tin, ambfac, mtex->blendtype);
- if (shi->amb<0.0f) shi->amb= 0.0f;
- else if (shi->amb>1.0f) shi->amb= 1.0f;
-
- shi->ambr= shi->amb*re->wrld.ambr;
- shi->ambg= shi->amb*re->wrld.ambg;
- shi->ambb= shi->amb*re->wrld.ambb;
- }
- }
- }
- }
- if ((use_compat_bump || use_ntap_bump || found_nmapping) && (shi->mat->mode & MA_TANGENT_V) != 0) {
- const float fnegdot = -dot_v3v3(shi->vn, shi->tang);
- /* apply Gram-Schmidt projection */
- madd_v3_v3fl(shi->tang, shi->vn, fnegdot);
- normalize_v3(shi->tang);
- }
-}
-
-
-void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_r[3], float *val, Render *re)
-{
- const bool skip_load_image = (re->r.scemode & R_NO_IMAGE_LOAD) != 0;
- const bool texnode_preview = (re->r.scemode & R_TEXNODE_PREVIEW) != 0;
- MTex *mtex;
- Tex *tex;
- TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
- int tex_nr, rgbnor= 0;
- float co[3], texvec[3];
- float fact, stencilTin=1.0;
-
- if (re->r.scemode & R_NO_TEX) return;
- /* here: test flag if there's a tex (todo) */
-
- for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
- /* separate tex switching */
- if (shi->mat->septex & (1<<tex_nr)) continue;
-
- if (shi->mat->mtex[tex_nr]) {
- mtex= shi->mat->mtex[tex_nr];
- tex= mtex->tex;
- if (tex == NULL) continue;
-
- /* only process if this texture is mapped
- * to one that we're interested in */
- if (!(mtex->mapto & mapto_flag)) continue;
-
- /* which coords */
- if (mtex->texco==TEXCO_OBJECT) {
- Object *ob= mtex->object;
- if (ob) {
- copy_v3_v3(co, xyz);
- if (mtex->texflag & MTEX_OB_DUPLI_ORIG) {
- if (shi->obi && shi->obi->duplitexmat)
- mul_m4_v3(shi->obi->duplitexmat, co);
- }
- mul_m4_v3(ob->imat_ren, co);
-
- if (mtex->texflag & MTEX_MAPTO_BOUNDS && ob->bb) {
- /* use bb vec[0] as min and bb vec[6] as max */
- co[0] = (co[0] - ob->bb->vec[0][0]) / (ob->bb->vec[6][0]-ob->bb->vec[0][0]) * 2.0f - 1.0f;
- co[1] = (co[1] - ob->bb->vec[0][1]) / (ob->bb->vec[6][1]-ob->bb->vec[0][1]) * 2.0f - 1.0f;
- co[2] = (co[2] - ob->bb->vec[0][2]) / (ob->bb->vec[6][2]-ob->bb->vec[0][2]) * 2.0f - 1.0f;
- }
- }
- }
- /* not really orco, but 'local' */
- else if (mtex->texco==TEXCO_ORCO) {
-
- if (mtex->texflag & MTEX_DUPLI_MAPTO) {
- copy_v3_v3(co, shi->duplilo);
- }
- else {
- Object *ob= shi->obi->ob;
- copy_v3_v3(co, xyz);
- mul_m4_v3(ob->imat_ren, co);
-
- if (mtex->texflag & MTEX_MAPTO_BOUNDS && ob->bb) {
- /* use bb vec[0] as min and bb vec[6] as max */
- co[0] = (co[0] - ob->bb->vec[0][0]) / (ob->bb->vec[6][0]-ob->bb->vec[0][0]) * 2.0f - 1.0f;
- co[1] = (co[1] - ob->bb->vec[0][1]) / (ob->bb->vec[6][1]-ob->bb->vec[0][1]) * 2.0f - 1.0f;
- co[2] = (co[2] - ob->bb->vec[0][2]) / (ob->bb->vec[6][2]-ob->bb->vec[0][2]) * 2.0f - 1.0f;
- }
- }
- }
- else if (mtex->texco==TEXCO_GLOB) {
- copy_v3_v3(co, xyz);
- mul_m4_v3(re->viewinv, co);
- }
- else {
- continue; /* can happen when texco defines disappear and it renders old files */
- }
-
- texres.nor= NULL;
-
- if (tex->type == TEX_IMAGE) {
- continue; /* not supported yet */
- //do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
- }
- else {
- /* placement */
- if (mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
- else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
-
- if (mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
- else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
-
- if (mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
- else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
- }
-
- rgbnor = multitex(tex,
- texvec,
- NULL, NULL,
- 0,
- &texres,
- shi->thread,
- mtex->which_output,
- re->pool,
- skip_load_image,
- texnode_preview,
- true); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */
-
- /* texture output */
-
- if ((rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
- texres.tin = IMB_colormanagement_get_luminance(&texres.tr);
- rgbnor -= TEX_RGB;
- }
- if (mtex->texflag & MTEX_NEGATIVE) {
- if (rgbnor & TEX_RGB) {
- texres.tr= 1.0f-texres.tr;
- texres.tg= 1.0f-texres.tg;
- texres.tb= 1.0f-texres.tb;
- }
- texres.tin= 1.0f-texres.tin;
- }
- if (mtex->texflag & MTEX_STENCIL) {
- if (rgbnor & TEX_RGB) {
- fact= texres.ta;
- texres.ta*= stencilTin;
- stencilTin*= fact;
- }
- else {
- fact= texres.tin;
- texres.tin*= stencilTin;
- stencilTin*= fact;
- }
- }
-
-
- if ((mapto_flag & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL)) && (mtex->mapto & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL))) {
- float tcol[3];
-
- /* stencil maps on the texture control slider, not texture intensity value */
-
- if ((rgbnor & TEX_RGB) == 0) {
- copy_v3_v3(tcol, &mtex->r);
- }
- else if (mtex->mapto & MAP_DENSITY) {
- copy_v3_v3(tcol, &texres.tr);
- if (texres.talpha) {
- texres.tin = stencilTin;
- }
- }
- else {
- copy_v3_v3(tcol, &texres.tr);
- if (texres.talpha) {
- texres.tin= texres.ta;
- }
- }
-
- /* used for emit */
- if ((mapto_flag & MAP_EMISSION_COL) && (mtex->mapto & MAP_EMISSION_COL)) {
- float colemitfac= mtex->colemitfac*stencilTin;
- texture_rgb_blend(col_r, tcol, col_r, texres.tin, colemitfac, mtex->blendtype);
- }
-
- if ((mapto_flag & MAP_REFLECTION_COL) && (mtex->mapto & MAP_REFLECTION_COL)) {
- float colreflfac= mtex->colreflfac*stencilTin;
- texture_rgb_blend(col_r, tcol, col_r, texres.tin, colreflfac, mtex->blendtype);
- }
-
- if ((mapto_flag & MAP_TRANSMISSION_COL) && (mtex->mapto & MAP_TRANSMISSION_COL)) {
- float coltransfac= mtex->coltransfac*stencilTin;
- texture_rgb_blend(col_r, tcol, col_r, texres.tin, coltransfac, mtex->blendtype);
- }
- }
-
- if ((mapto_flag & MAP_VARS) && (mtex->mapto & MAP_VARS)) {
- /* stencil maps on the texture control slider, not texture intensity value */
-
- /* convert RGB to intensity if intensity info isn't provided */
- if (rgbnor & TEX_RGB) {
- if (texres.talpha) texres.tin = texres.ta;
- else texres.tin = IMB_colormanagement_get_luminance(&texres.tr);
- }
-
- if ((mapto_flag & MAP_EMISSION) && (mtex->mapto & MAP_EMISSION)) {
- float emitfac= mtex->emitfac*stencilTin;
-
- *val = texture_value_blend(mtex->def_var, *val, texres.tin, emitfac, mtex->blendtype);
- if (*val<0.0f) *val= 0.0f;
- }
- if ((mapto_flag & MAP_DENSITY) && (mtex->mapto & MAP_DENSITY)) {
- float densfac= mtex->densfac*stencilTin;
-
- *val = texture_value_blend(mtex->def_var, *val, texres.tin, densfac, mtex->blendtype);
- CLAMP(*val, 0.0f, 1.0f);
- }
- if ((mapto_flag & MAP_SCATTERING) && (mtex->mapto & MAP_SCATTERING)) {
- float scatterfac= mtex->scatterfac*stencilTin;
-
- *val = texture_value_blend(mtex->def_var, *val, texres.tin, scatterfac, mtex->blendtype);
- CLAMP(*val, 0.0f, 1.0f);
- }
- if ((mapto_flag & MAP_REFLECTION) && (mtex->mapto & MAP_REFLECTION)) {
- float reflfac= mtex->reflfac*stencilTin;
-
- *val = texture_value_blend(mtex->def_var, *val, texres.tin, reflfac, mtex->blendtype);
- CLAMP(*val, 0.0f, 1.0f);
- }
- }
- }
- }
-}
-
-
-/* ------------------------------------------------------------------------- */
-
-void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4])
-{
- const bool skip_load_image = har->skip_load_image;
- const bool texnode_preview = har->texnode_preview;
- MTex *mtex;
- TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
- float texvec[3], dxt[3], dyt[3], fact, facm, dx;
- int rgb, osatex;
-
- if (R.r.scemode & R_NO_TEX) return;
-
- mtex= har->mat->mtex[0];
- if (har->mat->septex & (1<<0)) return;
- if (mtex->tex==NULL) return;
-
- /* no normal mapping */
- texres.nor= NULL;
-
- texvec[0]= xn/har->rad;
- texvec[1]= yn/har->rad;
- texvec[2]= 0.0;
-
- osatex= (har->mat->texco & TEXCO_OSA);
-
- /* placement */
- if (mtex->projx) texvec[0]= mtex->size[0]*(texvec[mtex->projx-1]+mtex->ofs[0]);
- else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
-
- if (mtex->projy) texvec[1]= mtex->size[1]*(texvec[mtex->projy-1]+mtex->ofs[1]);
- else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
-
- if (mtex->projz) texvec[2]= mtex->size[2]*(texvec[mtex->projz-1]+mtex->ofs[2]);
- else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
-
- if (osatex) {
-
- dx= 1.0f/har->rad;
-
- if (mtex->projx) {
- dxt[0]= mtex->size[0]*dx;
- dyt[0]= mtex->size[0]*dx;
- }
- else dxt[0]= dyt[0]= 0.0;
-
- if (mtex->projy) {
- dxt[1]= mtex->size[1]*dx;
- dyt[1]= mtex->size[1]*dx;
- }
- else dxt[1]= dyt[1]= 0.0;
-
- if (mtex->projz) {
- dxt[2]= 0.0;
- dyt[2]= 0.0;
- }
- else dxt[2]= dyt[2]= 0.0;
-
- }
-
- if (mtex->tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
-
- rgb = multitex(mtex->tex,
- texvec,
- dxt, dyt,
- osatex,
- &texres,
- 0,
- mtex->which_output,
- har->pool,
- skip_load_image,
- texnode_preview,
- true);
-
- /* texture output */
- if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
- texres.tin = IMB_colormanagement_get_luminance(&texres.tr);
- rgb= 0;
- }
- if (mtex->texflag & MTEX_NEGATIVE) {
- if (rgb) {
- texres.tr= 1.0f-texres.tr;
- texres.tg= 1.0f-texres.tg;
- texres.tb= 1.0f-texres.tb;
- }
- else texres.tin= 1.0f-texres.tin;
- }
-
- /* mapping */
- if (mtex->mapto & MAP_COL) {
-
- if (rgb==0) {
- texres.tr= mtex->r;
- texres.tg= mtex->g;
- texres.tb= mtex->b;
- }
- else if (mtex->mapto & MAP_ALPHA) {
- texres.tin= 1.0;
- }
- else texres.tin= texres.ta;
-
- /* inverse gamma correction */
- if (mtex->tex->type==TEX_IMAGE) {
- Image *ima = mtex->tex->ima;
- ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &mtex->tex->iuser, har->pool);
-
- /* don't linearize float buffers, assumed to be linear */
- if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
- IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace);
-
- BKE_image_pool_release_ibuf(ima, ibuf, har->pool);
- }
-
- fact= texres.tin*mtex->colfac;
- facm= 1.0f-fact;
-
- if (mtex->blendtype==MTEX_MUL) {
- facm= 1.0f-mtex->colfac;
- }
-
- if (mtex->blendtype==MTEX_SUB) fact= -fact;
-
- if (mtex->blendtype==MTEX_BLEND) {
- col_r[0]= (fact*texres.tr + facm*har->r);
- col_r[1]= (fact*texres.tg + facm*har->g);
- col_r[2]= (fact*texres.tb + facm*har->b);
- }
- else if (mtex->blendtype==MTEX_MUL) {
- col_r[0]= (facm+fact*texres.tr)*har->r;
- col_r[1]= (facm+fact*texres.tg)*har->g;
- col_r[2]= (facm+fact*texres.tb)*har->b;
- }
- else {
- col_r[0]= (fact*texres.tr + har->r);
- col_r[1]= (fact*texres.tg + har->g);
- col_r[2]= (fact*texres.tb + har->b);
-
- CLAMP(col_r[0], 0.0f, 1.0f);
- CLAMP(col_r[1], 0.0f, 1.0f);
- CLAMP(col_r[2], 0.0f, 1.0f);
- }
- }
- if (mtex->mapto & MAP_ALPHA) {
- if (rgb) {
- if (texres.talpha) {
- texres.tin = texres.ta;
- }
- else {
- texres.tin = IMB_colormanagement_get_luminance(&texres.tr);
- }
- }
-
- col_r[3]*= texres.tin;
- }
-}
-
-/* ------------------------------------------------------------------------- */
-
-/* hor and zen are RGB vectors, blend is 1 float, should all be initialized */
-void do_sky_tex(
- const float rco[3], const float view[3], const float lo[3], const float dxyview[2],
- float hor[3], float zen[3], float *blend, int skyflag, short thread)
-{
- const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0;
- const bool texnode_preview = (R.r.scemode & R_TEXNODE_PREVIEW) != 0;
- MTex *mtex;
- Tex *tex;
- TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
- float fact, stencilTin=1.0;
- float tempvec[3], texvec[3], dxt[3], dyt[3];
- int tex_nr, rgb= 0;
-
- if (R.r.scemode & R_NO_TEX) return;
- /* todo: add flag to test if there's a tex */
- texres.nor= NULL;
-
- for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
- if (R.wrld.mtex[tex_nr]) {
- const float *co;
-
- mtex= R.wrld.mtex[tex_nr];
-
- tex= mtex->tex;
- if (tex == NULL) continue;
- /* if (mtex->mapto==0) continue; */
-
- /* which coords */
- co= lo;
-
- /* dxt dyt just from 1 value */
- if (dxyview) {
- dxt[0]= dxt[1]= dxt[2]= dxyview[0];
- dyt[0]= dyt[1]= dyt[2]= dxyview[1];
- }
- else {
- dxt[0]= dxt[1]= dxt[2]= 0.0;
- dyt[0]= dyt[1]= dyt[2]= 0.0;
- }
-
- /* Grab the mapping settings for this texture */
- switch (mtex->texco) {
- case TEXCO_ANGMAP:
- /* only works with texture being "real" */
- /* use saacos(), fixes bug [#22398], float precision caused lo[2] to be slightly less than -1.0 */
- if (lo[0] || lo[1]) { /* check for zero case [#24807] */
- fact= (1.0f/(float)M_PI)*saacos(lo[2])/(sqrtf(lo[0]*lo[0] + lo[1]*lo[1]));
- tempvec[0]= lo[0]*fact;
- tempvec[1]= lo[1]*fact;
- tempvec[2]= 0.0;
- }
- else {
- /* this value has no angle, the vector is directly along the view.
- * avoid divide by zero and use a dummy value. */
- tempvec[0]= 1.0f;
- tempvec[1]= 0.0;
- tempvec[2]= 0.0;
- }
- co= tempvec;
- break;
-
- case TEXCO_H_SPHEREMAP:
- case TEXCO_H_TUBEMAP:
- if (skyflag & WO_ZENUP) {
- if (mtex->texco==TEXCO_H_TUBEMAP) map_to_tube( tempvec, tempvec+1, lo[0], lo[2], lo[1]);
- else map_to_sphere(tempvec, tempvec+1, lo[0], lo[2], lo[1]);
- /* tube/spheremap maps for outside view, not inside */
- tempvec[0]= 1.0f-tempvec[0];
- /* only top half */
- tempvec[1]= 2.0f*tempvec[1]-1.0f;
- tempvec[2]= 0.0;
- /* and correction for do_2d_mapping */
- tempvec[0]= 2.0f*tempvec[0]-1.0f;
- tempvec[1]= 2.0f*tempvec[1]-1.0f;
- co= tempvec;
- }
- else {
- /* potentially dangerous... check with multitex! */
- continue;
- }
- break;
- case TEXCO_EQUIRECTMAP:
- tempvec[0]= -atan2f(lo[2], lo[0]) / (float)M_PI;
- tempvec[1]= atan2f(lo[1], hypot(lo[0], lo[2])) / (float)M_PI_2;
- tempvec[2]= 0.0f;
- co= tempvec;
- break;
- case TEXCO_OBJECT:
- if (mtex->object) {
- copy_v3_v3(tempvec, lo);
- mul_m4_v3(mtex->object->imat_ren, tempvec);
- co= tempvec;
- }
- break;
-
- case TEXCO_GLOB:
- if (rco) {
- copy_v3_v3(tempvec, rco);
- mul_m4_v3(R.viewinv, tempvec);
- co= tempvec;
- }
- else
- co= lo;
-
-// copy_v3_v3(shi->dxgl, shi->dxco);
-// mul_m3_v3(R.imat, shi->dxco);
-// copy_v3_v3(shi->dygl, shi->dyco);
-// mul_m3_v3(R.imat, shi->dyco);
- break;
- case TEXCO_VIEW:
- co = view;
- break;
- }
-
- /* placement */
- if (mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
- else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
-
- if (mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
- else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
-
- if (mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
- else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
-
- /* texture */
- if (tex->type==TEX_IMAGE) do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
-
- rgb = multitex(mtex->tex,
- texvec,
- dxt, dyt,
- R.osa,
- &texres,
- thread,
- mtex->which_output,
- R.pool,
- skip_load_image,
- texnode_preview,
- true);
-
- /* texture output */
- if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
- texres.tin = IMB_colormanagement_get_luminance(&texres.tr);
- rgb= 0;
- }
- if (mtex->texflag & MTEX_NEGATIVE) {
- if (rgb) {
- texres.tr= 1.0f-texres.tr;
- texres.tg= 1.0f-texres.tg;
- texres.tb= 1.0f-texres.tb;
- }
- else texres.tin= 1.0f-texres.tin;
- }
- if (mtex->texflag & MTEX_STENCIL) {
- if (rgb) {
- fact= texres.ta;
- texres.ta*= stencilTin;
- stencilTin*= fact;
- }
- else {
- fact= texres.tin;
- texres.tin*= stencilTin;
- stencilTin*= fact;
- }
- }
- else {
- if (rgb) texres.ta *= stencilTin;
- else texres.tin*= stencilTin;
- }
-
- /* color mapping */
- if (mtex->mapto & (WOMAP_HORIZ+WOMAP_ZENUP+WOMAP_ZENDOWN)) {
- float tcol[3];
-
- if (rgb==0) {
- texres.tr= mtex->r;
- texres.tg= mtex->g;
- texres.tb= mtex->b;
- }
- else texres.tin= texres.ta;
-
- tcol[0]= texres.tr; tcol[1]= texres.tg; tcol[2]= texres.tb;
-
- /* inverse gamma correction */
- if (tex->type==TEX_IMAGE) {
- Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, R.pool);
-
- /* don't linearize float buffers, assumed to be linear */
- if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
- IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace);
-
- BKE_image_pool_release_ibuf(ima, ibuf, R.pool);
- }
-
- if (mtex->mapto & WOMAP_HORIZ) {
- texture_rgb_blend(hor, tcol, hor, texres.tin, mtex->colfac, mtex->blendtype);
- }
- if (mtex->mapto & (WOMAP_ZENUP+WOMAP_ZENDOWN)) {
- float zenfac = 0.0f;
-
- if (R.wrld.skytype & WO_SKYREAL) {
- if ((skyflag & WO_ZENUP)) {
- if (mtex->mapto & WOMAP_ZENUP) zenfac= mtex->zenupfac;
- }
- else if (mtex->mapto & WOMAP_ZENDOWN) zenfac= mtex->zendownfac;
- }
- else {
- if (mtex->mapto & WOMAP_ZENUP) zenfac= mtex->zenupfac;
- else if (mtex->mapto & WOMAP_ZENDOWN) zenfac= mtex->zendownfac;
- }
-
- if (zenfac != 0.0f)
- texture_rgb_blend(zen, tcol, zen, texres.tin, zenfac, mtex->blendtype);
- }
- }
- if (mtex->mapto & WOMAP_BLEND) {
- if (rgb) texres.tin = IMB_colormanagement_get_luminance(&texres.tr);
-
- *blend= texture_value_blend(mtex->def_var, *blend, texres.tin, mtex->blendfac, mtex->blendtype);
- }
- }
- }
-}
-
-/* ------------------------------------------------------------------------- */
-/* col_r supposed to be initialized with la->r,g,b */
-
-void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r[3], int effect)
-{
- const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0;
- const bool texnode_preview = (R.r.scemode & R_TEXNODE_PREVIEW) != 0;
- Object *ob;
- MTex *mtex;
- Tex *tex;
- TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
- float *co = NULL, *dx = NULL, *dy = NULL, fact, stencilTin=1.0;
- float texvec[3], dxt[3], dyt[3], tempvec[3];
- int i, tex_nr, rgb= 0;
-
- if (R.r.scemode & R_NO_TEX) return;
- tex_nr= 0;
-
- for (; tex_nr<MAX_MTEX; tex_nr++) {
-
- if (la->mtex[tex_nr]) {
- mtex= la->mtex[tex_nr];
-
- tex= mtex->tex;
- if (tex==NULL) continue;
- texres.nor= NULL;
-
- /* which coords */
- if (mtex->texco==TEXCO_OBJECT) {
- ob= mtex->object;
- if (ob) {
- co= tempvec;
- dx= dxt;
- dy= dyt;
- copy_v3_v3(tempvec, shi->co);
- mul_m4_v3(ob->imat_ren, tempvec);
- if (shi->osatex) {
- copy_v3_v3(dxt, shi->dxco);
- copy_v3_v3(dyt, shi->dyco);
- mul_mat3_m4_v3(ob->imat_ren, dxt);
- mul_mat3_m4_v3(ob->imat_ren, dyt);
- }
- }
- else {
- co= shi->co;
- dx= shi->dxco; dy= shi->dyco;
- }
- }
- else if (mtex->texco==TEXCO_GLOB) {
- co= shi->gl; dx= shi->dxco; dy= shi->dyco;
- copy_v3_v3(shi->gl, shi->co);
- mul_m4_v3(R.viewinv, shi->gl);
- }
- else if (mtex->texco==TEXCO_VIEW) {
-
- copy_v3_v3(tempvec, lavec);
- mul_m3_v3(la->imat, tempvec);
-
- if (la->type==LA_SPOT) {
- tempvec[0]*= la->spottexfac;
- tempvec[1]*= la->spottexfac;
- /* project from 3d to 2d */
- tempvec[0] /= -tempvec[2];
- tempvec[1] /= -tempvec[2];
- }
- co= tempvec;
-
- dx= dxt; dy= dyt;
- if (shi->osatex) {
- copy_v3_v3(dxt, shi->dxlv);
- copy_v3_v3(dyt, shi->dylv);
- /* need some matrix conversion here? la->imat is a [3][3] matrix!!! **/
- mul_m3_v3(la->imat, dxt);
- mul_m3_v3(la->imat, dyt);
-
- mul_v3_fl(dxt, la->spottexfac);
- mul_v3_fl(dyt, la->spottexfac);
- }
- }
-
-
- /* placement */
- if (mtex->projx && co) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
- else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
-
- if (mtex->projy && co) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
- else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
-
- if (mtex->projz && co) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
- else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
-
- if (shi->osatex) {
- if (!dx) {
- for (i=0;i<2;i++) {
- dxt[i] = dyt[i] = 0.0;
- }
- }
- else {
- if (mtex->projx) {
- dxt[0]= mtex->size[0]*dx[mtex->projx-1];
- dyt[0]= mtex->size[0]*dy[mtex->projx-1];
- }
- else {
- dxt[0]= 0.0;
- dyt[0]= 0.0;
- }
- if (mtex->projy) {
- dxt[1]= mtex->size[1]*dx[mtex->projy-1];
- dyt[1]= mtex->size[1]*dy[mtex->projy-1];
- }
- else {
- dxt[1]= 0.0;
- dyt[1]= 0.0;
- }
- if (mtex->projz) {
- dxt[2]= mtex->size[2]*dx[mtex->projz-1];
- dyt[2]= mtex->size[2]*dy[mtex->projz-1];
- }
- else {
- dxt[2]= 0.0;
- dyt[2]= 0.0;
- }
- }
- }
-
- /* texture */
- if (tex->type==TEX_IMAGE) {
- do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
- }
-
- rgb = multitex(tex,
- texvec,
- dxt, dyt,
- shi->osatex,
- &texres,
- shi->thread,
- mtex->which_output,
- R.pool,
- skip_load_image,
- texnode_preview,
- true);
-
- /* texture output */
- if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
- texres.tin = IMB_colormanagement_get_luminance(&texres.tr);
- rgb= 0;
- }
- if (mtex->texflag & MTEX_NEGATIVE) {
- if (rgb) {
- texres.tr= 1.0f-texres.tr;
- texres.tg= 1.0f-texres.tg;
- texres.tb= 1.0f-texres.tb;
- }
- else texres.tin= 1.0f-texres.tin;
- }
- if (mtex->texflag & MTEX_STENCIL) {
- if (rgb) {
- fact= texres.ta;
- texres.ta*= stencilTin;
- stencilTin*= fact;
- }
- else {
- fact= texres.tin;
- texres.tin*= stencilTin;
- stencilTin*= fact;
- }
- }
- else {
- if (rgb) texres.ta*= stencilTin;
- else texres.tin*= stencilTin;
- }
-
- /* mapping */
- if (((mtex->mapto & LAMAP_COL) && (effect & LA_TEXTURE))||((mtex->mapto & LAMAP_SHAD) && (effect & LA_SHAD_TEX))) {
- float col[3];
-
- if (rgb==0) {
- texres.tr= mtex->r;
- texres.tg= mtex->g;
- texres.tb= mtex->b;
- }
- else if (mtex->mapto & MAP_ALPHA) {
- texres.tin= stencilTin;
- }
- else texres.tin= texres.ta;
-
- /* inverse gamma correction */
- if (tex->type==TEX_IMAGE) {
- Image *ima = tex->ima;
- ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, R.pool);
-
- /* don't linearize float buffers, assumed to be linear */
- if (ibuf && !(ibuf->rect_float) && R.scene_color_manage)
- IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace);
-
- BKE_image_pool_release_ibuf(ima, ibuf, R.pool);
- }
-
- /* lamp colors were premultiplied with this */
- col[0]= texres.tr*la->energy;
- col[1]= texres.tg*la->energy;
- col[2]= texres.tb*la->energy;
-
- if (effect & LA_SHAD_TEX)
- texture_rgb_blend(col_r, col, col_r, texres.tin, mtex->shadowfac, mtex->blendtype);
- else
- texture_rgb_blend(col_r, col, col_r, texres.tin, mtex->colfac, mtex->blendtype);
- }
- }
- }
-}
-
/* ------------------------------------------------------------------------- */
int externtex(const MTex *mtex,
@@ -3626,7 +1476,7 @@ int externtex(const MTex *mtex,
/* texture */
if (tex->type==TEX_IMAGE) {
- do_2d_mapping(mtex, texvec, NULL, NULL, dxt, dyt);
+ do_2d_mapping(mtex, texvec, NULL, dxt, dyt);
}
rgb = multitex(tex,
@@ -3658,327 +1508,3 @@ int externtex(const MTex *mtex,
return (rgb != 0);
}
-
-/* ------------------------------------------------------------------------- */
-
-void render_realtime_texture(ShadeInput *shi, Image *ima)
-{
- const bool skip_load_image = (R.r.scemode & R_NO_IMAGE_LOAD) != 0;
- TexResult texr;
- static Tex imatex[BLENDER_MAX_THREADS]; /* threadsafe */
- static int firsttime= 1;
- Tex *tex;
- float texvec[3], dx[2], dy[2];
- ShadeInputUV *suv= &shi->uv[shi->actuv];
- int a;
-
- if (R.r.scemode & R_NO_TEX) return;
-
- if (firsttime) {
- BLI_thread_lock(LOCK_IMAGE);
- if (firsttime) {
- const int num_threads = BLI_system_thread_count();
- for (a = 0; a < num_threads; a++) {
- memset(&imatex[a], 0, sizeof(Tex));
- BKE_texture_default(&imatex[a]);
- imatex[a].type= TEX_IMAGE;
- }
-
- firsttime= 0;
- }
- BLI_thread_unlock(LOCK_IMAGE);
- }
-
- tex= &imatex[shi->thread];
- tex->iuser.ok= ima->ok;
- tex->ima = ima;
-
- texvec[0]= 0.5f+0.5f*suv->uv[0];
- texvec[1]= 0.5f+0.5f*suv->uv[1];
- texvec[2] = 0.0f; /* initalize it because imagewrap looks at it. */
- if (shi->osatex) {
- dx[0]= 0.5f*suv->dxuv[0];
- dx[1]= 0.5f*suv->dxuv[1];
- dy[0]= 0.5f*suv->dyuv[0];
- dy[1]= 0.5f*suv->dyuv[1];
- }
-
- texr.nor= NULL;
-
- if (shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr, R.pool, skip_load_image);
- else imagewrap(tex, ima, NULL, texvec, &texr, R.pool, skip_load_image);
-
- shi->vcol[0]*= texr.tr;
- shi->vcol[1]*= texr.tg;
- shi->vcol[2]*= texr.tb;
- shi->vcol[3]*= texr.ta;
-}
-
-/* A modified part of shadeinput.c -> shade_input_set_uv()
- * Used for sampling UV mapped texture color */
-static void textured_face_generate_uv(
- const float normal[3], const float hit[3],
- const float v1[3], const float v2[3], const float v3[3],
- float r_uv[2])
-{
-
- float detsh, t00, t10, t01, t11;
- int axis1, axis2;
-
- /* find most stable axis to project */
- axis_dominant_v3(&axis1, &axis2, normal);
-
- /* compute u,v and derivatives */
- t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];
- t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];
-
- detsh= 1.0f/(t00*t11-t10*t01);
- t00*= detsh; t01*=detsh;
- t10*=detsh; t11*=detsh;
-
- r_uv[0] = (hit[axis1] - v3[axis1]) * t11 - (hit[axis2] - v3[axis2]) * t10;
- r_uv[1] = (hit[axis2] - v3[axis2]) * t00 - (hit[axis1] - v3[axis1]) * t01;
-
- /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */
- CLAMP(r_uv[0], -2.0f, 1.0f);
- CLAMP(r_uv[1], -2.0f, 1.0f);
-}
-
-/* Generate an updated copy of material to use for color sampling. */
-Material *RE_sample_material_init(Depsgraph *depsgraph, Material *orig_mat, Scene *scene)
-{
- Tex *tex = NULL;
- Material *mat;
- int tex_nr;
-
- if (!orig_mat) return NULL;
-
- /* copy material */
- mat = BKE_material_localize(orig_mat);
-
- /* update material anims */
- BKE_animsys_evaluate_animdata(scene, &mat->id, mat->adt, BKE_scene_frame_get(scene), ADT_RECALC_ANIM);
-
- /* strip material copy from unsupported flags */
- for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
-
- if (mat->mtex[tex_nr]) {
- MTex *mtex = mat->mtex[tex_nr];
-
- /* just in case make all non-used mtexes empty*/
- Tex *cur_tex = mtex->tex;
- mtex->tex = NULL;
-
- if (mat->septex & (1<<tex_nr) || !cur_tex) continue;
-
- /* only keep compatible texflags */
- mtex->texflag = mtex->texflag & (MTEX_RGBTOINT | MTEX_STENCIL | MTEX_NEGATIVE | MTEX_ALPHAMIX);
-
- /* depending of material type, strip non-compatible mapping modes */
- if (mat->material_type == MA_TYPE_SURFACE) {
- if (!ELEM(mtex->texco, TEXCO_ORCO, TEXCO_OBJECT, TEXCO_GLOB, TEXCO_UV)) {
- /* ignore this texture */
- mtex->texco = 0;
- continue;
- }
- /* strip all mapto flags except color and alpha */
- mtex->mapto = (mtex->mapto & MAP_COL) | (mtex->mapto & MAP_ALPHA);
- }
- else if (mat->material_type == MA_TYPE_VOLUME) {
- if (!ELEM(mtex->texco, TEXCO_OBJECT, TEXCO_ORCO, TEXCO_GLOB)) {
- /* ignore */
- mtex->texco = 0;
- continue;
- }
- /* strip all mapto flags except color and alpha */
- mtex->mapto = mtex->mapto & (MAP_TRANSMISSION_COL | MAP_REFLECTION_COL | MAP_DENSITY);
- }
-
- /* if mapped to an object, calculate inverse matrices */
- if (mtex->texco==TEXCO_OBJECT) {
- Object *ob= mtex->object;
- if (ob) {
- invert_m4_m4(ob->imat, ob->obmat);
- copy_m4_m4(ob->imat_ren, ob->imat);
- }
- }
-
- /* copy texture */
- tex= mtex->tex = BKE_texture_localize(cur_tex);
-
- /* update texture anims */
- BKE_animsys_evaluate_animdata(scene, &tex->id, tex->adt, BKE_scene_frame_get(scene), ADT_RECALC_ANIM);
-
- /* update texture cache if required */
- if (tex->type==TEX_VOXELDATA) {
- cache_voxeldata(tex, (int)scene->r.cfra);
- }
- if (tex->type==TEX_POINTDENSITY) {
- /* set dummy values for render and do cache */
- Render dummy_re = {NULL};
- dummy_re.scene = scene;
- unit_m4(dummy_re.viewinv);
- unit_m4(dummy_re.viewmat);
- unit_m4(dummy_re.winmat);
- dummy_re.winx = dummy_re.winy = 128;
- cache_pointdensity(depsgraph, &dummy_re, tex->pd);
- }
-
- /* update image sequences and movies */
- if (tex->ima && BKE_image_is_animated(tex->ima)) {
- BKE_image_user_check_frame_calc(&tex->iuser, (int)scene->r.cfra, 0);
- }
- }
- }
- return mat;
-}
-
-/* free all duplicate data allocated by RE_sample_material_init() */
-void RE_sample_material_free(Material *mat)
-{
- int tex_nr;
-
- /* free textures */
- for (tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
- if (mat->septex & (1<<tex_nr)) continue;
- if (mat->mtex[tex_nr]) {
- MTex *mtex= mat->mtex[tex_nr];
-
- if (mtex->tex) {
- /* don't update user counts as we are freeing a duplicate */
- BKE_texture_free(mtex->tex);
- MEM_freeN(mtex->tex);
- mtex->tex = NULL;
- }
- }
- }
-
- /* don't update user counts as we are freeing a duplicate */
- BKE_material_free(mat);
- MEM_freeN(mat);
-}
-
-/*
- * Get material diffuse color and alpha (including linked textures) in given coordinates
- *
- * color,alpha : input/output color values
- * volume_co : sample coordinate in global space. used by volumetric materials
- * surface_co : sample surface coordinate in global space. used by "surface" materials
- * tri_index : surface tri index
- * orcoDm : orco state derived mesh
- */
-void RE_sample_material_color(
- Material *mat, float color[3], float *alpha, const float volume_co[3], const float surface_co[3],
- int tri_index, DerivedMesh *orcoDm, Object *ob)
-{
- int v1, v2, v3;
- MVert *mvert;
- MLoop *mloop;
- const MLoopTri *mlooptri;
- float normal[3];
- ShadeInput shi = {NULL};
- Render re = {NULL};
-
- /* Get face data */
- mvert = orcoDm->getVertArray(orcoDm);
- mloop = orcoDm->getLoopArray(orcoDm);
- mlooptri = orcoDm->getLoopTriArray(orcoDm);
-
- if (!mvert || !mlooptri || !mat) {
- return;
- }
-
- v1 = mloop[mlooptri[tri_index].tri[0]].v;
- v2 = mloop[mlooptri[tri_index].tri[1]].v;
- v3 = mloop[mlooptri[tri_index].tri[2]].v;
- normal_tri_v3(normal, mvert[v1].co, mvert[v2].co, mvert[v3].co);
-
- /* generate shadeinput with data required */
- shi.mat = mat;
-
- /* fill shadeinput data depending on material type */
- if (mat->material_type == MA_TYPE_SURFACE) {
- /* global coordinates */
- copy_v3_v3(shi.gl, surface_co);
- /* object space coordinates */
- copy_v3_v3(shi.co, surface_co);
- mul_m4_v3(ob->imat, shi.co);
- /* orco coordinates */
- {
- float uv[2];
- float l;
- /* Get generated UV */
- textured_face_generate_uv(normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co, uv);
- l= 1.0f+uv[0]+uv[1];
-
- /* calculate generated coordinate */
- shi.lo[0]= l*mvert[v3].co[0]-uv[0]*mvert[v1].co[0]-uv[1]*mvert[v2].co[0];
- shi.lo[1]= l*mvert[v3].co[1]-uv[0]*mvert[v1].co[1]-uv[1]*mvert[v2].co[1];
- shi.lo[2]= l*mvert[v3].co[2]-uv[0]*mvert[v1].co[2]-uv[1]*mvert[v2].co[2];
- }
- /* uv coordinates */
- {
- const int layers = CustomData_number_of_layers(&orcoDm->loopData, CD_MLOOPUV);
- const int layer_index = CustomData_get_layer_index(&orcoDm->loopData, CD_MLOOPUV);
- int i;
-
- /* for every uv map set coords and name */
- for (i=0; i<layers; i++) {
- if (layer_index >= 0) {
- const float *uv1, *uv2, *uv3;
- const CustomData *data = &orcoDm->loopData;
- const MLoopUV *mloopuv = data->layers[layer_index + i].data;
- float uv[2];
- float l;
-
- /* point layer name from actual layer data */
- shi.uv[i].name = data->layers[i].name;
- /* Get generated coordinates to calculate UV from */
- textured_face_generate_uv(normal, shi.co, mvert[v1].co, mvert[v2].co, mvert[v3].co, uv);
- /* Get UV mapping coordinate */
- l= 1.0f+uv[0]+uv[1];
-
- uv1 = mloopuv[mlooptri[tri_index].tri[0]].uv;
- uv2 = mloopuv[mlooptri[tri_index].tri[1]].uv;
- uv3 = mloopuv[mlooptri[tri_index].tri[2]].uv;
-
- shi.uv[i].uv[0]= -1.0f + 2.0f*(l*uv3[0]-uv[0]*uv1[0]-uv[1]*uv2[0]);
- shi.uv[i].uv[1]= -1.0f + 2.0f*(l*uv3[1]-uv[0]*uv1[1]-uv[1]*uv2[1]);
- shi.uv[i].uv[2]= 0.0f; /* texture.c assumes there are 3 coords */
- }
- }
- /* active uv map */
- shi.actuv = CustomData_get_active_layer_index(&orcoDm->loopData, CD_MLOOPUV) - layer_index;
- shi.totuv = layers;
- }
-
- /* apply initial values from material */
- shi.r = mat->r;
- shi.g = mat->g;
- shi.b = mat->b;
- shi.alpha = mat->alpha;
-
- /* do texture */
- do_material_tex(&shi, &re);
-
- /* apply result */
- color[0] = shi.r;
- color[1] = shi.g;
- color[2] = shi.b;
- *alpha = shi.alpha;
- }
- else if (mat->material_type == MA_TYPE_VOLUME) {
- ObjectInstanceRen obi = {NULL};
- obi.ob = ob;
- shi.obi = &obi;
- unit_m4(re.viewinv);
- copy_v3_v3(color, mat->vol.reflection_col);
- *alpha = mat->vol.density;
-
- /* do texture */
- do_volume_tex(&shi, volume_co, (MAP_TRANSMISSION_COL | MAP_REFLECTION_COL | MAP_DENSITY),
- color, alpha, &re);
- }
-}
-
-/* eof */