diff options
author | Mikhail Matrosov <ktdfly> | 2021-10-06 11:16:56 +0300 |
---|---|---|
committer | William Leeson <william@blender.org> | 2021-10-06 11:25:09 +0300 |
commit | ca0450feeffdb07eea11c17aa617bfd7b9a04913 (patch) | |
tree | 12794100153cbf61184d6dc6de102634227c6703 /intern | |
parent | 85267ec1ae9edba1167b2f6248fbf7307ee73544 (diff) |
Fix T91064: Cycles low poly meshes having black edges when shade smoothed
Fixes:{T91064}
Caused by {rBcd118c5581f482afc8554ff88b5b6f3b552b1682}
- Applies `ensure_valid_reflection()` to the normal input on all BSDFs for CPU and GPU.
- This doesn't affect hair.
- Removes `ensure_valid_reflection()` from the output of Bump Map and Normal Map nodes for CPU/GPU as it is not needed.
- The fix doesn't touch OSL.
Reviewed By: brecht, leesonw
Maniphest Tasks: T91064
Differential Revision: https://developer.blender.org/D12403
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/kernel/closure/bsdf_principled_diffuse.h | 25 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_closure.h | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_tex_coord.h | 2 |
3 files changed, 19 insertions, 14 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h index a72af519482..55fe364db70 100644 --- a/intern/cycles/kernel/closure/bsdf_principled_diffuse.h +++ b/intern/cycles/kernel/closure/bsdf_principled_diffuse.h @@ -35,21 +35,25 @@ static_assert(sizeof(ShaderClosure) >= sizeof(PrincipledDiffuseBsdf), "PrincipledDiffuseBsdf is too large!"); ccl_device float3 calculate_principled_diffuse_brdf( - const PrincipledDiffuseBsdf *bsdf, float3 N, float3 V, float3 L, float3 H, float *pdf) + const PrincipledDiffuseBsdf *bsdf, float3 N, float3 V, float3 L, float *pdf) { float NdotL = dot(N, L); - float NdotV = dot(N, V); - if (NdotL <= 0 || NdotV <= 0) { - *pdf = 0.0f; + if (NdotL <= 0) { return make_float3(0.0f, 0.0f, 0.0f); } - float LdotH = dot(L, H); + float NdotV = dot(N, V); + + /* H = normalize(L + V); // Bissector of an angle between L and V + * LH2 = 2 * dot(L, H)^2 = 2cos(x)^2 = cos(2x) + 1 = dot(L, V) + 1, + * half-angle x between L and V is at most 90 deg + */ + float LH2 = dot(L, V) + 1; float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV); - const float Fd90 = 0.5f + 2.0f * LdotH * LdotH * bsdf->roughness; - float Fd = (1.0f * (1.0f - FL) + Fd90 * FL) * (1.0f * (1.0f - FV) + Fd90 * FV); + const float Fd90 = 0.5f + LH2 * bsdf->roughness; + float Fd = (1.0f - FL + Fd90 * FL) * (1.0f - FV + Fd90 * FV); float value = M_1_PI_F * NdotL * Fd; @@ -72,11 +76,10 @@ ccl_device float3 bsdf_principled_diffuse_eval_reflect(const ShaderClosure *sc, float3 N = bsdf->N; float3 V = I; // outgoing float3 L = omega_in; // incoming - float3 H = normalize(L + V); if (dot(N, omega_in) > 0.0f) { *pdf = fmaxf(dot(N, omega_in), 0.0f) * M_1_PI_F; - return calculate_principled_diffuse_brdf(bsdf, N, V, L, H, pdf); + return calculate_principled_diffuse_brdf(bsdf, N, V, L, pdf); } else { *pdf = 0.0f; @@ -112,9 +115,7 @@ ccl_device int bsdf_principled_diffuse_sample(const ShaderClosure *sc, sample_cos_hemisphere(N, randu, randv, omega_in, pdf); if (dot(Ng, *omega_in) > 0) { - float3 H = normalize(I + *omega_in); - - *eval = calculate_principled_diffuse_brdf(bsdf, N, I, *omega_in, H, pdf); + *eval = calculate_principled_diffuse_brdf(bsdf, N, I, *omega_in, pdf); #ifdef __RAY_DIFFERENTIALS__ // TODO: find a better approximation for the diffuse bounce diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index e2f6dde4ace..3e0cbe3a483 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -85,6 +85,9 @@ ccl_device_noinline int svm_node_closure_bsdf( } float3 N = stack_valid(data_node.x) ? stack_load_float3(stack, data_node.x) : sd->N; + if (!(sd->type & PRIMITIVE_ALL_CURVE)) { + N = ensure_valid_reflection(sd->Ng, sd->I, N); + } float param1 = (stack_valid(param1_offset)) ? stack_load_float(stack, param1_offset) : __uint_as_float(node.z); @@ -166,6 +169,9 @@ ccl_device_noinline int svm_node_closure_bsdf( float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ? stack_load_float3(stack, data_cn_ssr.x) : sd->N; + if (!(sd->type & PRIMITIVE_ALL_CURVE)) { + clearcoat_normal = ensure_valid_reflection(sd->Ng, sd->I, clearcoat_normal); + } float3 subsurface_radius = stack_valid(data_cn_ssr.y) ? stack_load_float3(stack, data_cn_ssr.y) : make_float3(1.0f, 1.0f, 1.0f); diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index a35253080da..8869001015b 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -347,8 +347,6 @@ ccl_device_noinline void svm_node_normal_map(const KernelGlobals *kg, N = safe_normalize(sd->N + (N - sd->N) * strength); } - N = ensure_valid_reflection(sd->Ng, sd->I, N); - if (is_zero(N)) { N = sd->N; } |