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
This commit is contained in:
parent
85267ec1ae
commit
ca0450feef
Notes:
blender-bot
2023-02-13 23:17:13 +01:00
Referenced by issue #91064, Cycles Lower Poly Meshes Having Obvious Black Edges When Shade Smoothed
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue