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:
-rw-r--r--release/ui/buttons_data_mesh.py8
-rw-r--r--source/blender/blenkernel/intern/material.c1
-rw-r--r--source/blender/blenkernel/intern/texture.c4
-rw-r--r--source/blender/blenlib/intern/arithb.c24
-rw-r--r--source/blender/blenloader/intern/readfile.c15
-rw-r--r--source/blender/makesdna/DNA_texture_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_material.c30
-rw-r--r--source/blender/render/intern/source/convertblender.c1
-rw-r--r--source/blender/render/intern/source/shadeinput.c10
-rw-r--r--source/blender/render/intern/source/texture.c395
10 files changed, 367 insertions, 122 deletions
diff --git a/release/ui/buttons_data_mesh.py b/release/ui/buttons_data_mesh.py
index d4bf9698a89..757745d039e 100644
--- a/release/ui/buttons_data_mesh.py
+++ b/release/ui/buttons_data_mesh.py
@@ -49,6 +49,14 @@ class DATA_PT_normals(DataButtonsPanel):
sub.itemR(mesh, "vertex_normal_flip")
sub.itemR(mesh, "double_sided")
+ row = layout.row(align=True)
+ if context.edit_object:
+ row.itemO("MESH_OT_faces_shade_smooth")
+ row.itemO("MESH_OT_faces_shade_flat")
+ else:
+ row.itemO("OBJECT_OT_shade_smooth")
+ row.itemO("OBJECT_OT_shade_flat")
+
class DATA_PT_vertex_groups(DataButtonsPanel):
__idname__ = "DATA_PT_vertex_groups"
__label__ = "Vertex Groups"
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 088b1b6e0c2..bee63f497ca 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -671,6 +671,7 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
ma->mapto |= mtex->mapto;
if(r_mode & R_OSA) {
if ELEM3(mtex->tex->type, TEX_IMAGE, TEX_PLUGIN, TEX_ENVMAP) ma->texco |= TEXCO_OSA;
+ else if(mtex->texflag & MTEX_NEW_BUMP) ma->texco |= TEXCO_OSA; // NEWBUMP: need texture derivatives for procedurals as well
}
if(ma->texco & (TEXCO_ORCO|TEXCO_REFL|TEXCO_NORM|TEXCO_STRAND|TEXCO_STRESS)) needuv= 1;
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index db864dc9f1e..1c7dab15d5c 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -534,7 +534,7 @@ void default_mtex(MTex *mtex)
mtex->size[1]= 1.0;
mtex->size[2]= 1.0;
mtex->tex= 0;
- mtex->texflag= 0;
+ mtex->texflag= MTEX_NEW_BUMP;
mtex->colormodel= 0;
mtex->r= 1.0;
mtex->g= 0.0;
@@ -543,7 +543,7 @@ void default_mtex(MTex *mtex)
mtex->def_var= 1.0;
mtex->blendtype= MTEX_BLEND;
mtex->colfac= 1.0;
- mtex->norfac= 0.5;
+ mtex->norfac= 1.0;
mtex->varfac= 1.0;
mtex->dispfac=0.2;
mtex->normapspace= MTEX_NSPACE_TANGENT;
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index 03be10dd0b1..f7313c8b37a 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -2197,25 +2197,23 @@ void VecNegf(float *v1)
void VecOrthoBasisf(float *v, float *v1, float *v2)
{
- float f = (float)sqrt(v[0]*v[0] + v[1]*v[1]);
+ const float f = (float)sqrt(v[0]*v[0] + v[1]*v[1]);
if (f < 1e-35f) {
// degenerate case
- v1[0] = 0.0f; v1[1] = 1.0f; v1[2] = 0.0f;
- if (v[2] > 0.0f) {
- v2[0] = 1.0f; v2[1] = v2[2] = 0.0f;
- }
- else {
- v2[0] = -1.0f; v2[1] = v2[2] = 0.0f;
- }
+ v1[0] = (v[2] < 0.0f) ? -1.0f : 1.0f;
+ v1[1] = v1[2] = v2[0] = v2[2] = 0.0f;
+ v2[1] = 1.0f;
}
else {
- f = 1.0f/f;
- v1[0] = v[1]*f;
- v1[1] = -v[0]*f;
- v1[2] = 0.0f;
+ const float d= 1.0f/f;
- Crossf(v2, v, v1);
+ v1[0] = v[1]*d;
+ v1[1] = -v[0]*d;
+ v1[2] = 0.0f;
+ v2[0] = -v[2]*v1[1];
+ v2[1] = v[2]*v1[0];
+ v2[2] = v[0]*v1[1] - v[1]*v1[0];
}
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 6da444bc88e..bbe85c5f378 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -9276,7 +9276,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
Tex *tex;
Scene *sce;
ToolSettings *ts;
- int i;
+ int i, a;
for(ob = main->object.first; ob; ob = ob->id.next) {
@@ -9351,15 +9351,26 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
/* texture filter */
- for(tex = main->tex.first; tex; tex = tex->id.next)
+ for(tex = main->tex.first; tex; tex = tex->id.next) {
if(tex->afmax == 0)
tex->afmax= 8;
+ }
for(ma = main->mat.first; ma; ma = ma->id.next) {
if(ma->mode & MA_HALO) {
ma->material_type= MA_TYPE_HALO;
ma->mode &= ~MA_HALO;
}
+
+ /* set new bump for unused slots */
+ for(a=0; a<MAX_MTEX; a++) {
+ if(ma->mtex[a]) {
+ if(!ma->mtex[a]->tex)
+ ma->mtex[a]->texflag |= MTEX_NEW_BUMP;
+ else if(((Tex*)newlibadr(fd, ma->id.lib, ma->mtex[a]->tex))->type == 0)
+ ma->mtex[a]->texflag |= MTEX_NEW_BUMP;
+ }
+ }
}
for(sce = main->scene.first; sce; sce = sce->id.next) {
diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h
index e1dd21a8ccb..0760825670d 100644
--- a/source/blender/makesdna/DNA_texture_types.h
+++ b/source/blender/makesdna/DNA_texture_types.h
@@ -373,6 +373,7 @@ typedef struct TexMapping {
#define MTEX_VIEWSPACE 16
#define MTEX_DUPLI_MAPTO 32
#define MTEX_OB_DUPLI_ORIG 64
+#define MTEX_NEW_BUMP 128
/* blendtype */
#define MTEX_BLEND 0
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 6686d43d075..fd54dd959b2 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -231,99 +231,122 @@ static void rna_def_material_mtex(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "texco");
RNA_def_property_enum_items(prop, prop_texture_coordinates_items);
RNA_def_property_ui_text(prop, "Texture Coordinates", "");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "object", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "object");
RNA_def_property_struct_type(prop, "Object");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Object", "Object to use for mapping with Object texture coordinates.");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "uvname");
RNA_def_property_ui_text(prop, "UV Layer", "UV layer to use for mapping with UV texture coordinates.");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "from_dupli", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_DUPLI_MAPTO);
RNA_def_property_ui_text(prop, "From Dupli", "Dupli's instanced from verts, faces or particles, inherit texture coordinate from their parent.");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "from_original", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_OB_DUPLI_ORIG);
RNA_def_property_ui_text(prop, "From Original", "Dupli's derive their object coordinates from the original objects transformation.");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_colordiff", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_COL);
RNA_def_property_ui_text(prop, "Diffuse Color", "Causes the texture to affect basic color of the material");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_normal", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_NORM);
RNA_def_property_ui_text(prop, "Normal", "Causes the texture to affect the rendered normal");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_colorspec", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_COLSPEC);
RNA_def_property_ui_text(prop, "Specular Color", "Causes the texture to affect the specularity color");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_mirror", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_COLMIR);
RNA_def_property_ui_text(prop, "Mirror", "Causes the texture to affect the mirror color");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_diffuse", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_REF);
RNA_def_property_ui_text(prop, "Diffuse", "Causes the texture to affect the value of the materials diffuse reflectivity");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_specular", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_SPEC);
RNA_def_property_ui_text(prop, "Specular", "Causes the texture to affect the value of specular reflectivity");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_ambient", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_AMB);
RNA_def_property_ui_text(prop, "Ambient", "Causes the texture to affect the value of ambient");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_hardness", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_HAR);
RNA_def_property_ui_text(prop, "Hardness", "Causes the texture to affect the hardness value");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_raymir", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_RAYMIRR);
RNA_def_property_ui_text(prop, "Ray-Mirror", "Causes the texture to affect the ray-mirror value");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_ALPHA);
RNA_def_property_ui_text(prop, "Alpha", "Causes the texture to affect the alpha value");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_emit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_EMIT);
RNA_def_property_ui_text(prop, "Emit", "Causes the texture to affect the emit value");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_translucency", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_TRANSLU);
RNA_def_property_ui_text(prop, "Translucency", "Causes the texture to affect the translucency value");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_displacement", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_DISPLACE);
RNA_def_property_ui_text(prop, "Displacement", "Let the texture displace the surface");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "map_warp", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mapto", MAP_WARP);
RNA_def_property_ui_text(prop, "Warp", "Let the texture warp texture coordinates of next channels");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "x_mapping", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "projx");
RNA_def_property_enum_items(prop, prop_x_mapping_items);
RNA_def_property_ui_text(prop, "X Mapping", "");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "y_mapping", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "projy");
RNA_def_property_enum_items(prop, prop_y_mapping_items);
RNA_def_property_ui_text(prop, "Y Mapping", "");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "z_mapping", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "projz");
RNA_def_property_enum_items(prop, prop_z_mapping_items);
RNA_def_property_ui_text(prop, "Z Mapping", "");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_mapping_items);
RNA_def_property_ui_text(prop, "Mapping", "");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
/* XXX: pmapto, pmaptoneg */
@@ -331,6 +354,7 @@ static void rna_def_material_mtex(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "normapspace");
RNA_def_property_enum_items(prop, prop_normal_map_space_items);
RNA_def_property_ui_text(prop, "Normal Map Space", "");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
/* XXX: MTex.which_output */
@@ -340,11 +364,13 @@ static void rna_def_material_mtex(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "dispfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Displacement Factor", "Amount texture displaces the surface.");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "warp_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "warpfac");
RNA_def_property_ui_range(prop, 0, 1, 10, 3);
RNA_def_property_ui_text(prop, "Warp Factor", "Amount texture affects texture coordinates of next channels.");
+ RNA_def_property_update(prop, NC_TEXTURE, NULL);
prop= RNA_def_property(srna, "colorspec_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "colfac");
@@ -417,10 +443,10 @@ static void rna_def_material_mtex(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Enabled", "Enable this material texture slot.");
RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
- /*prop= RNA_def_property(srna, "new_bump", PROP_BOOLEAN, PROP_NONE);
+ prop= RNA_def_property(srna, "new_bump", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_NEW_BUMP);
RNA_def_property_ui_text(prop, "New Bump", "Use new, corrected bump mapping code (backwards compatibility option).");
- RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);*/
+ RNA_def_property_update(prop, NC_MATERIAL|ND_SHADING, NULL);
}
static void rna_def_material_colors(StructRNA *srna)
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index da77d578efc..5853b51a6b1 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -2243,6 +2243,7 @@ static void displace_render_face(Render *re, ObjectRen *obr, VlakRen *vlr, float
/* memset above means we dont need this */
/*shi.osatex= 0;*/ /* signal not to use dx[] and dy[] texture AA vectors */
+ shi.obr= obr;
shi.vlr= vlr; /* current render face */
shi.mat= vlr->mat; /* current input material */
shi.thread= 0;
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index 931595eae60..6b1d11be6f3 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -210,7 +210,6 @@ void shade_input_do_shade(ShadeInput *shi, ShadeResult *shr)
/* add mist and premul color */
if(shr->alpha!=1.0f || alpha!=1.0f) {
float fac= alpha*(shr->alpha);
-
shr->combined[3]= fac;
shr->combined[0]*= fac;
shr->combined[1]*= fac;
@@ -1016,9 +1015,12 @@ void shade_input_set_shade_texco(ShadeInput *shi)
MTC_Mat4MulVecfl(R.viewinv, shi->gl);
if(shi->osatex) {
VECCOPY(shi->dxgl, shi->dxco);
- MTC_Mat3MulVecfl(R.imat, shi->dxco);
+ // TXF: bug was here, but probably should be in convertblender.c, R.imat only valid if there is a world
+ //MTC_Mat3MulVecfl(R.imat, shi->dxco);
+ MTC_Mat4Mul3Vecfl(R.viewinv, shi->dxco);
VECCOPY(shi->dygl, shi->dyco);
- MTC_Mat3MulVecfl(R.imat, shi->dyco);
+ //MTC_Mat3MulVecfl(R.imat, shi->dyco);
+ MTC_Mat4Mul3Vecfl(R.viewinv, shi->dyco);
}
}
@@ -1121,6 +1123,8 @@ void shade_input_set_shade_texco(ShadeInput *shi)
if(tface && tface->tpage)
render_realtime_texture(shi, tface->tpage);
}
+
+
}
shi->dupliuv[0]= -1.0f + 2.0f*obi->dupliuv[0];
diff --git a/source/blender/render/intern/source/texture.c b/source/blender/render/intern/source/texture.c
index 9466bd45420..3f7ffc5b9bb 100644
--- a/source/blender/render/intern/source/texture.c
+++ b/source/blender/render/intern/source/texture.c
@@ -71,6 +71,8 @@
#include "shading.h"
#include "texture.h"
+#include "renderdatabase.h" /* needed for UV */
+
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
/* only to be used here in this file, it's for speed */
@@ -1499,6 +1501,94 @@ 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, float* co, float* dx, float* dy, float* texvec, float* dxt, float* dyt)
+{
+ // 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_DEFAULT)
+ 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_DEFAULT)
+ 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] = 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] = 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]= 0.f;
+ }
+ }
+}
void do_material_tex(ShadeInput *shi)
{
@@ -1509,10 +1599,12 @@ void do_material_tex(ShadeInput *shi)
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, warpdone=0;
+ float nu[3], nv[3], nn[3] = {0,0,0}, dudnu = 1.f, dudnv = 0.f, dvdnu = 0.f, dvdnv = 1.f; // bump mapping
+ int nunvdone= 0;
if (R.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 */
@@ -1582,7 +1674,7 @@ void do_material_tex(ShadeInput *shi)
}
else {
ShadeInputUV *suv= &shi->uv[shi->actuv];
- int i;
+ int i = shi->actuv;
if(mtex->uvname[0] != 0) {
for(i = 0; i < shi->totuv; i++) {
@@ -1596,6 +1688,47 @@ void do_material_tex(ShadeInput *shi)
co= suv->uv;
dx= suv->dxuv;
dy= suv->dyuv;
+
+ // 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..
+ if ((mtex->texflag & MTEX_NEW_BUMP) && shi->obr && shi->obr->ob) {
+ if(mtex->mapto & (MAP_NORM|MAP_DISPLACE|MAP_WARP)) {
+ 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);
+
+ if (tf) {
+ float *uv1 = tf->uv[j1], *uv2 = tf->uv[j2], *uv3 = tf->uv[j3];
+ const float an[3] = {fabsf(nn[0]), fabsf(nn[1]), fabsf(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;
+
+ dudnu = (dpdv_a2*nu[a1] - dpdv_a1*nu[a2])*d;
+ dvdnu = (dpdu_a1*nu[a2] - dpdu_a2*nu[a1])*d;
+ dudnv = (dpdv_a2*nv[a1] - dpdv_a1*nv[a2])*d;
+ dvdnv = (dpdu_a1*nv[a2] - dpdu_a2*nv[a1])*d;
+ }
+ }
+ }
}
}
else if(mtex->texco==TEXCO_WINDOW) {
@@ -1621,7 +1754,7 @@ void do_material_tex(ShadeInput *shi)
}
else continue; // can happen when texco defines disappear and it renders old files
- /* de pointer defines if bumping happens */
+ /* the pointer defines if bumping happens */
if(mtex->mapto & (MAP_NORM|MAP_DISPLACE|MAP_WARP)) {
texres.nor= norvec;
norvec[0]= norvec[1]= norvec[2]= 0.0;
@@ -1632,94 +1765,149 @@ void do_material_tex(ShadeInput *shi)
VECADD(tempvec, co, warpvec);
co= tempvec;
}
-
- if(tex->type==TEX_IMAGE) {
-
- /* new: first swap coords, then map, then trans/scale */
- /* placement */
- if(mtex->projx) texvec[0]= co[mtex->projx-1];
- else texvec[0]= 0.0;
- if(mtex->projy) texvec[1]= co[mtex->projy-1];
- else texvec[1]= 0.0;
- if(mtex->projz) texvec[2]= co[mtex->projz-1];
- else texvec[2]= 0.0;
+ if(mtex->texflag & MTEX_NEW_BUMP) {
+ // compute ortho basis around normal
+ if(!nunvdone) {
+ // render normal is negated
+ nn[0] = -shi->vn[0];
+ nn[1] = -shi->vn[1];
+ nn[2] = -shi->vn[2];
+ VecOrthoBasisf(nn, nu, nv);
+ nunvdone= 1;
+ }
- if(shi->osatex) {
-
- if(mtex->projx) {
- dxt[0]= dx[mtex->projx-1];
- dyt[0]= dy[mtex->projx-1];
- }
- else dxt[0]= dyt[0]= 0.0f;
-
- if(mtex->projy) {
- dxt[1]= dx[mtex->projy-1];
- dyt[1]= dy[mtex->projy-1];
+ if(texres.nor) {
+ 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->maptoneg & MAP_NORM) ? -mtex->norfac : mtex->norfac);
+ // disable internal bump eval
+ float* nvec = texres.nor;
+ texres.nor = NULL;
+ // du & dv estimates, constant value defaults
+ du = dv = 0.01f;
+
+ // 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_get_ibuf(tex->ima, &tex->iuser);
+ if (ibuf) {
+ du = 1.f/(float)ibuf->x;
+ dv = 1.f/(float)ibuf->y;
+ }
}
- else dxt[1]= dyt[1]= 0.0f;
- if(mtex->projz) {
- dxt[2]= dx[mtex->projz-1];
- dyt[2]= dy[mtex->projz-1];
+ 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 = MAX3(adx[0], adx[1], adx[2]);
+ dv = MAX3(ady[1], ady[1], ady[2]);
+ }
}
- else dxt[2]= dyt[2]= 0.0;
- }
-
- do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt);
- /* translate and scale */
- texvec[0]= mtex->size[0]*(texvec[0]-0.5) +mtex->ofs[0]+0.5;
- texvec[1]= mtex->size[1]*(texvec[1]-0.5) +mtex->ofs[1]+0.5;
- 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 */
- if(tex->flag & TEX_REPEAT_XMIR) {
- if(texvec[0]>1.0f) texvec[0] -= (int)(texvec[0]);
- else if(texvec[0]<0.0f) texvec[0]+= 1-(int)(texvec[0]);
- }
- if(tex->flag & TEX_REPEAT_YMIR) {
- if(texvec[1]>1.0f) texvec[1] -= (int)(texvec[1]);
- else if(texvec[1]<0.0f) texvec[1]+= 1-(int)(texvec[1]);
- }
-
- }
- 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]);
+ // center, main return value
+ texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
+ rgbnor = multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
+ cd = fromrgb ? (texres.tr + texres.tg + texres.tb)*0.33333333f : 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 = MIN2(du, dv);
+ idu = (du < 1e-6f) ? bf : (bf/du);
+
+ // +u val
+ tco[0] = co[0] + dudnu*du;
+ tco[1] = co[1] + dvdnu*du;
+ tco[2] = 0.f;
+ texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
+ multitex(tex, texv, dxt, dyt, shi->osatex, &ttexr, shi->thread, mtex->which_output);
+ ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
+
+ // +v val
+ tco[0] = co[0] + dudnv*du;
+ tco[1] = co[1] + dvdnv*du;
+ tco[2] = 0.f;
+ texco_mapping(shi, tex, mtex, tco, dx, dy, texv, dxt, dyt);
+ multitex(tex, texv, dxt, dyt, shi->osatex, &ttexr, shi->thread, mtex->which_output);
+ vd = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
+ }
+ else {
+ float tu[3] = {nu[0], nu[1], nu[2]}, tv[3] = {nv[0], nv[1], nv[2]};
- if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
- else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
+ idu = (du < 1e-6f) ? bf : (bf/du);
+ idv = (dv < 1e-6f) ? bf : (bf/dv);
- if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
- else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
+ if ((mtex->texco == TEXCO_ORCO) && shi->obr && shi->obr->ob) {
+ Mat4Mul3Vecfl(shi->obr->ob->imat, tu);
+ Mat4Mul3Vecfl(shi->obr->ob->imat, tv);
+ Normalize(tu);
+ Normalize(tv);
+ }
+ else if (mtex->texco == TEXCO_GLOB) {
+ Mat4Mul3Vecfl(R.viewinv, tu);
+ Mat4Mul3Vecfl(R.viewinv, tv);
+ }
+ else if (mtex->texco == TEXCO_OBJECT && mtex->object) {
+ Mat4Mul3Vecfl(mtex->object->imat, tu);
+ Mat4Mul3Vecfl(mtex->object->imat, tv);
+ Normalize(tu);
+ Normalize(tv);
+ }
- 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]= 0.0;
- if(mtex->projy) {
- dxt[1]= mtex->size[1]*dx[mtex->projy-1];
- dyt[1]= mtex->size[1]*dy[mtex->projy-1];
+ // +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(tex, texv, dxt, dyt, shi->osatex, &ttexr, shi->thread, mtex->which_output);
+ ud = idu*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : 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(tex, texv, dxt, dyt, shi->osatex, &ttexr, shi->thread, mtex->which_output);
+ vd = idv*(cd - (fromrgb ? (ttexr.tr + ttexr.tg + ttexr.tb)*0.33333333f : ttexr.tin));
}
- else dxt[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;
+
+ // bumped normal
+ nu[0] += ud*nn[0];
+ nu[1] += ud*nn[1];
+ nu[2] += ud*nn[2];
+ nv[0] += vd*nn[0];
+ nv[1] += vd*nn[1];
+ nv[2] += vd*nn[2];
+ Crossf(nvec, nu, nv);
+
+ nvec[0] = -nvec[0];
+ nvec[1] = -nvec[1];
+ nvec[2] = -nvec[2];
+ texres.nor = nvec;
+ rgbnor |= TEX_NOR;
+ }
+ else {
+ texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
+ rgbnor = multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
}
}
-
- rgbnor= multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
+ else {
+ texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt);
+ rgbnor = multitex(tex, texvec, dxt, dyt, shi->osatex, &texres, shi->thread, mtex->which_output);
+ }
/* texture output */
@@ -1785,7 +1973,7 @@ void do_material_tex(ShadeInput *shi)
if(mtex->texflag & MTEX_VIEWSPACE) {
// rotate to global coords
if(mtex->texco==TEXCO_ORCO || mtex->texco==TEXCO_UV) {
- if(shi->vlr && shi->obr->ob) {
+ if(shi->vlr && shi->obr && shi->obr->ob) {
float len= Normalize(texres.nor);
// can be optimized... (ton)
Mat4Mul3Vecfl(shi->obr->ob->obmat, texres.nor);
@@ -1897,25 +2085,32 @@ void do_material_tex(ShadeInput *shi)
}
}
else {
- float nor[3], dot;
-
- if(shi->mat->mode & MA_TANGENT_V) {
- shi->tang[0]+= Tnor*tex->norfac*texres.nor[0];
- shi->tang[1]+= Tnor*tex->norfac*texres.nor[1];
- shi->tang[2]+= Tnor*tex->norfac*texres.nor[2];
+ if (mtex->texflag & MTEX_NEW_BUMP) {
+ shi->vn[0] = texres.nor[0];
+ shi->vn[1] = texres.nor[1];
+ shi->vn[2] = texres.nor[2];
}
-
- /* prevent bump to become negative normal */
- nor[0]= Tnor*tex->norfac*texres.nor[0];
- nor[1]= Tnor*tex->norfac*texres.nor[1];
- nor[2]= Tnor*tex->norfac*texres.nor[2];
-
- dot= 0.5f + 0.5f*INPR(nor, shi->vn);
-
- shi->vn[0]+= dot*nor[0];
- shi->vn[1]+= dot*nor[1];
- shi->vn[2]+= dot*nor[2];
- }
+ else {
+ float nor[3], dot;
+
+ if(shi->mat->mode & MA_TANGENT_V) {
+ shi->tang[0]+= Tnor*tex->norfac*texres.nor[0];
+ shi->tang[1]+= Tnor*tex->norfac*texres.nor[1];
+ shi->tang[2]+= Tnor*tex->norfac*texres.nor[2];
+ }
+
+ /* prevent bump to become negative normal */
+ nor[0]= Tnor*tex->norfac*texres.nor[0];
+ nor[1]= Tnor*tex->norfac*texres.nor[1];
+ nor[2]= Tnor*tex->norfac*texres.nor[2];
+
+ dot= 0.5f + 0.5f*INPR(nor, shi->vn);
+
+ shi->vn[0]+= dot*nor[0];
+ shi->vn[1]+= dot*nor[1];
+ shi->vn[2]+= dot*nor[2];
+ }
+ }
Normalize(shi->vn);
/* this makes sure the bump is passed on to the next texture */
@@ -2628,7 +2823,7 @@ void render_realtime_texture(ShadeInput *shi, Image *ima)
texr.nor= NULL;
- if(shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr);
+ if(shi->osatex) imagewraposa(tex, ima, NULL, texvec, dx, dy, &texr);
else imagewrap(tex, ima, NULL, texvec, &texr);
shi->vcol[0]*= texr.tr;