diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-08-24 02:42:45 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2021-08-24 02:43:57 +0300 |
commit | bffa1681577e3c850c4fbab5799612febf32a245 (patch) | |
tree | 87fca54b03015913cd7c8396fcc7a8ebbb18fa97 /intern/cycles | |
parent | eec1ea0ccf2a47cbfa67e2cde250e44533c0d573 (diff) |
Fix T90854: Cycles, normal map fails with applied transformations
Prior to rBb8ecdbcd964a normals were stored both in
DeviceScene.tri_vnormal and the float3 attributes buffer. However, the
normals in `DeviceScene.tri_vnormal` might have be transformed to world
space if the object's transformation was applied, while the data in the
float3 attributes buffer were not. This caused shading issues in cases
where the objects did have transformation applied, as the math expects
the normals to be in object space.
To fix this, convert the normals to object space if necessary before
applying the normal map.
Reviewed By: brecht
Maniphest Tasks: T90854
Differential Revision: https://developer.blender.org/D12294
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/kernel/geom/geom_triangle.h | 11 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_tex_coord.h | 2 |
2 files changed, 10 insertions, 3 deletions
diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h index 1e7fbd9c7fb..ff7909ca425 100644 --- a/intern/cycles/kernel/geom/geom_triangle.h +++ b/intern/cycles/kernel/geom/geom_triangle.h @@ -107,8 +107,8 @@ triangle_smooth_normal(KernelGlobals *kg, float3 Ng, int prim, float u, float v) return is_zero(N) ? Ng : N; } -ccl_device_inline float3 -triangle_smooth_normal_unnormalized(KernelGlobals *kg, float3 Ng, int prim, float u, float v) +ccl_device_inline float3 triangle_smooth_normal_unnormalized( + KernelGlobals *kg, ShaderData *sd, float3 Ng, int prim, float u, float v) { /* load triangle vertices */ const uint4 tri_vindex = kernel_tex_fetch(__tri_vindex, prim); @@ -116,6 +116,13 @@ triangle_smooth_normal_unnormalized(KernelGlobals *kg, float3 Ng, int prim, floa float3 n1 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.y)); float3 n2 = float4_to_float3(kernel_tex_fetch(__tri_vnormal, tri_vindex.z)); + /* ensure that the normals are in object space */ + if (sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED) { + object_inverse_normal_transform(kg, sd, &n0); + object_inverse_normal_transform(kg, sd, &n1); + object_inverse_normal_transform(kg, sd, &n2); + } + float3 N = (1.0f - u - v) * n2 + u * n0 + v * n1; return is_zero(N) ? Ng : N; diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index fec6a2cc27f..46600551cc4 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -289,7 +289,7 @@ ccl_device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *st float3 normal; if (sd->shader & SHADER_SMOOTH_NORMAL) { - normal = triangle_smooth_normal_unnormalized(kg, sd->Ng, sd->prim, sd->u, sd->v); + normal = triangle_smooth_normal_unnormalized(kg, sd, sd->Ng, sd->prim, sd->u, sd->v); } else { normal = sd->Ng; |