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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-01-15 20:35:05 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-01-15 20:35:05 +0400
commit6adfd91657e07e5b749fb3a7aaeeeec88fb15d04 (patch)
tree32232a0280a212d0438cb3219079a61e89632a16 /intern/cycles/kernel
parent51f36ac80ab3dbb9a34cacdcb0eda5371793b16f (diff)
Fix #33830: cycles normal mapping was not quite correct, was not correctly
respecting the assumption that normal and tangent are interpolated without normalization.
Diffstat (limited to 'intern/cycles/kernel')
-rw-r--r--intern/cycles/kernel/shaders/node_normal_map.osl20
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h17
2 files changed, 24 insertions, 13 deletions
diff --git a/intern/cycles/kernel/shaders/node_normal_map.osl b/intern/cycles/kernel/shaders/node_normal_map.osl
index dc25eb8539f..21382fab06f 100644
--- a/intern/cycles/kernel/shaders/node_normal_map.osl
+++ b/intern/cycles/kernel/shaders/node_normal_map.osl
@@ -31,15 +31,23 @@ shader node_normal_map(
if (space == "Tangent") {
vector tangent;
+ vector ninterp;
float tangent_sign;
- getattribute(attr_name, tangent);
- getattribute(attr_sign_name, tangent_sign);
+ // get _unnormalized_ interpolated normal and tangent
+ if(!getattribute(attr_name, tangent) ||
+ !getattribute(attr_sign_name, tangent_sign) ||
+ !getattribute("geom:N", ninterp)) {
+ Normal = normal(0, 0, 0);
+ }
+ else {
+ // apply normal map
+ vector B = tangent_sign * cross(ninterp, tangent);
+ Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * ninterp);
- tangent = transform("object", "world", tangent);
-
- vector B = tangent_sign * cross(NormalIn, tangent);
- Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * NormalIn);
+ // transform to world space
+ Normal = normalize(transform("object", "world", Normal));
+ }
}
else if (space == "Object")
Normal = normalize(transform("object", "world", vector(mcolor)));
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index 7a1af43b625..d793169261d 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -248,24 +248,27 @@ __device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stac
}
/* first try to get tangent attribute */
- AttributeElement attr_elem, attr_sign_elem;
+ AttributeElement attr_elem, attr_sign_elem, attr_normal_elem;
int attr_offset = find_attribute(kg, sd, node.z, &attr_elem);
int attr_sign_offset = find_attribute(kg, sd, node.w, &attr_sign_elem);
+ int attr_normal_offset = find_attribute(kg, sd, ATTR_STD_VERTEX_NORMAL, &attr_normal_elem);
- if(attr_offset == ATTR_STD_NOT_FOUND || attr_sign_offset == ATTR_STD_NOT_FOUND) {
+ if(attr_offset == ATTR_STD_NOT_FOUND || attr_sign_offset == ATTR_STD_NOT_FOUND || attr_normal_offset == ATTR_STD_NOT_FOUND) {
stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
return;
}
- /* ensure orthogonal and normalized (interpolation breaks it) */
+ /* get _unnormalized_ interpolated normal and tangent */
float3 tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL);
float sign = primitive_attribute_float(kg, sd, attr_sign_elem, attr_sign_offset, NULL, NULL);
+ float3 normal = primitive_attribute_float3(kg, sd, attr_normal_elem, attr_normal_offset, NULL, NULL);
- object_normal_transform(kg, sd, &tangent);
- tangent = cross(sd->N, normalize(cross(tangent, sd->N)));;
+ /* apply normal map */
+ float3 B = sign * cross(normal, tangent);
+ N = normalize(color.x * tangent + color.y * B + color.z * normal);
- float3 B = sign * cross(sd->N, tangent);
- N = normalize(color.x * tangent + color.y * B + color.z * sd->N);
+ /* transform to world space */
+ object_normal_transform(kg, sd, &N);
}
else {
/* object, world space */