diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-10-18 03:09:12 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2012-10-18 03:09:12 +0400 |
commit | 9d260eedeb83776416981e2f3a8af9bb5605e1d2 (patch) | |
tree | b0bff5e62f273ec1f7674027d70bdaf090a990fb /intern/cycles/kernel/svm/svm_geometry.h | |
parent | b2142d6533d740b00ac1578de67f4a8d8dc94121 (diff) |
Fix #32904: strange pattern on subdivided cube with anistropic shader. Now
tangents from generated coordinates are computed per pixel on the fly, avoids
bad interpolation of singularities.
Diffstat (limited to 'intern/cycles/kernel/svm/svm_geometry.h')
-rw-r--r-- | intern/cycles/kernel/svm/svm_geometry.h | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h index 30afd6322a7..e0f9e337652 100644 --- a/intern/cycles/kernel/svm/svm_geometry.h +++ b/intern/cycles/kernel/svm/svm_geometry.h @@ -20,6 +20,22 @@ CCL_NAMESPACE_BEGIN /* Geometry Node */ +__device_inline float3 svm_tangent_from_generated(float3 P) +{ + float length = len(P); + + if(length == 0.0f) + return make_float3(0.0f, 0.0f, 0.0f); + + float u = 0.0f; + if(!(P.x == 0.0f && P.y == 0.0f)) + u = (1.0f - atan2f(P.x, P.y))/(2.0f*M_PI_F); + + float v = 1.0f - acosf(clamp(P.z/length, -1.0f, 1.0f))/M_PI_F; + + return make_float3(u, v, 0.0f); +} + __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset) { float3 data; @@ -36,8 +52,17 @@ __device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); object_normal_transform(kg, sd, &data); } - else - data = normalize(sd->dPdu); + else { + attr_offset = find_attribute(kg, sd, ATTR_STD_GENERATED); + + if(attr_offset != ATTR_STD_NOT_FOUND) { + data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); + svm_tangent_from_generated(data); + object_normal_transform(kg, sd, &data); + } + else + data = normalize(sd->dPdu); + } } else data = normalize(sd->dPdu); |