diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-01-15 20:35:05 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2013-01-15 20:35:05 +0400 |
commit | 6adfd91657e07e5b749fb3a7aaeeeec88fb15d04 (patch) | |
tree | 32232a0280a212d0438cb3219079a61e89632a16 /intern/cycles/kernel/svm/svm_tex_coord.h | |
parent | 51f36ac80ab3dbb9a34cacdcb0eda5371793b16f (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/svm/svm_tex_coord.h')
-rw-r--r-- | intern/cycles/kernel/svm/svm_tex_coord.h | 17 |
1 files changed, 10 insertions, 7 deletions
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 */ |