Shader: Clamp invalid inputs of various BSDF nodes
Clamp some of the inputs of the Glossy BSDF, Glass BSDF, Sheen BSDF, and Subsurface Scattering nodes to improve consistency between render engines and to avoid unexpected results. * Clamp roughness to 0..1 * Clamp subsurface radius to 0..inf * Clamp colors to 0..inf Pull Request: https://projects.blender.org/blender/blender/pulls/120390
This commit is contained in:
committed by
Brecht Van Lommel
parent
e3894f0a07
commit
afa66fc628
@@ -12,12 +12,14 @@ shader node_glass_bsdf(color Color = 0.8,
|
||||
normal Normal = N,
|
||||
output closure color BSDF = 0)
|
||||
{
|
||||
float r2 = Roughness * Roughness;
|
||||
color base_color = max(Color, color(0.0));
|
||||
float r2 = clamp(Roughness, 0.0, 1.0);
|
||||
r2 = r2 * r2;
|
||||
float eta = max(IOR, 1e-5);
|
||||
eta = backfacing() ? 1.0 / eta : eta;
|
||||
color F0 = F0_from_ior(eta);
|
||||
color F90 = color(1.0);
|
||||
|
||||
BSDF = generalized_schlick_bsdf(
|
||||
Normal, vector(0.0), Color, Color, r2, r2, F0, F90, -eta, distribution);
|
||||
Normal, vector(0.0), base_color, base_color, r2, r2, F0, F90, -eta, distribution);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@ shader node_glossy_bsdf(color Color = 0.8,
|
||||
output closure color BSDF = 0)
|
||||
{
|
||||
/* compute roughness */
|
||||
float roughness = Roughness * Roughness;
|
||||
color base_color = max(Color, color(0.0));
|
||||
float roughness = clamp(Roughness, 0.0, 1.0);
|
||||
roughness = roughness * roughness;
|
||||
float roughness_u, roughness_v;
|
||||
float aniso = clamp(Anisotropy, -0.99, 0.99);
|
||||
|
||||
@@ -41,7 +43,8 @@ shader node_glossy_bsdf(color Color = 0.8,
|
||||
}
|
||||
|
||||
if (distribution == "Multiscatter GGX")
|
||||
BSDF = Color * microfacet_multi_ggx_aniso(Normal, T, roughness_u, roughness_v, Color);
|
||||
BSDF = base_color *
|
||||
microfacet_multi_ggx_aniso(Normal, T, roughness_u, roughness_v, base_color);
|
||||
else
|
||||
BSDF = Color * microfacet(distribution, Normal, T, roughness_u, roughness_v, 0.0, 0);
|
||||
BSDF = base_color * microfacet(distribution, Normal, T, roughness_u, roughness_v, 0.0, 0);
|
||||
}
|
||||
|
||||
@@ -11,10 +11,11 @@ shader node_sheen_bsdf(color Color = 0.8,
|
||||
normal Normal = N,
|
||||
output closure color BSDF = 0)
|
||||
{
|
||||
color base_color = max(Color, color(0.0));
|
||||
float roughness = clamp(Roughness, 0.0, 1.0);
|
||||
|
||||
if (distribution == "ashikhmin")
|
||||
BSDF = Color * ashikhmin_velvet(Normal, roughness);
|
||||
BSDF = base_color * ashikhmin_velvet(Normal, roughness);
|
||||
else if (distribution == "microfiber")
|
||||
BSDF = Color * sheen(Normal, roughness);
|
||||
BSDF = base_color * sheen(Normal, roughness);
|
||||
}
|
||||
|
||||
@@ -13,14 +13,15 @@ shader node_subsurface_scattering(color Color = 0.8,
|
||||
normal Normal = N,
|
||||
output closure color BSSRDF = 0)
|
||||
{
|
||||
BSSRDF = Color * bssrdf(method,
|
||||
Normal,
|
||||
Scale * Radius,
|
||||
Color,
|
||||
"ior",
|
||||
IOR,
|
||||
"anisotropy",
|
||||
Anisotropy,
|
||||
"roughness",
|
||||
1.0);
|
||||
color base_color = max(Color, color(0.0));
|
||||
BSSRDF = base_color * bssrdf(method,
|
||||
Normal,
|
||||
Scale * Radius,
|
||||
base_color,
|
||||
"ior",
|
||||
IOR,
|
||||
"anisotropy",
|
||||
Anisotropy,
|
||||
"roughness",
|
||||
1.0);
|
||||
}
|
||||
|
||||
@@ -470,7 +470,7 @@ ccl_device
|
||||
break;
|
||||
}
|
||||
|
||||
float roughness = sqr(param1);
|
||||
float roughness = sqr(saturatef(param1));
|
||||
|
||||
bsdf->N = maybe_ensure_valid_specular_reflection(sd, N);
|
||||
bsdf->ior = 1.0f;
|
||||
@@ -513,7 +513,8 @@ ccl_device
|
||||
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
|
||||
if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
|
||||
kernel_assert(stack_valid(data_node.z));
|
||||
const Spectrum color = rgb_to_spectrum(stack_load_float3(stack, data_node.z));
|
||||
const Spectrum color = max(rgb_to_spectrum(stack_load_float3(stack, data_node.z)),
|
||||
zero_spectrum());
|
||||
bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, color);
|
||||
}
|
||||
}
|
||||
@@ -580,12 +581,12 @@ ccl_device
|
||||
|
||||
float ior = fmaxf(param2, 1e-5f);
|
||||
bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / ior : ior;
|
||||
bsdf->alpha_x = bsdf->alpha_y = sqr(param1);
|
||||
bsdf->alpha_x = bsdf->alpha_y = sqr(saturatef(param1));
|
||||
|
||||
fresnel->f0 = make_float3(F0_from_ior(ior));
|
||||
fresnel->f90 = one_spectrum();
|
||||
fresnel->exponent = -ior;
|
||||
const float3 color = stack_load_float3(stack, data_node.y);
|
||||
const float3 color = max(stack_load_float3(stack, data_node.y), zero_float3());
|
||||
fresnel->reflection_tint = reflective_caustics ? rgb_to_spectrum(color) : zero_spectrum();
|
||||
fresnel->transmission_tint = refractive_caustics ? rgb_to_spectrum(color) :
|
||||
zero_spectrum();
|
||||
@@ -622,7 +623,7 @@ ccl_device
|
||||
|
||||
if (bsdf) {
|
||||
bsdf->N = N;
|
||||
bsdf->roughness = param1;
|
||||
bsdf->roughness = saturatef(param1);
|
||||
|
||||
sd->flag |= bsdf_sheen_setup(kg, sd, bsdf);
|
||||
}
|
||||
@@ -866,7 +867,8 @@ ccl_device
|
||||
ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
|
||||
|
||||
if (bssrdf) {
|
||||
bssrdf->radius = rgb_to_spectrum(stack_load_float3(stack, data_node.y) * param1);
|
||||
bssrdf->radius = max(rgb_to_spectrum(stack_load_float3(stack, data_node.y) * param1),
|
||||
zero_spectrum());
|
||||
bssrdf->albedo = closure_weight;
|
||||
bssrdf->N = maybe_ensure_valid_specular_reflection(sd, N);
|
||||
bssrdf->ior = param2;
|
||||
|
||||
@@ -15,6 +15,7 @@ void node_bsdf_glossy(vec4 color,
|
||||
color = max(color, vec4(0.0));
|
||||
roughness = saturate(roughness);
|
||||
N = safe_normalize(N);
|
||||
/* anisotropy = clamp(anisotropy, -0.99, 0.99) */
|
||||
|
||||
vec3 V = coordinate_incoming(g_data.P);
|
||||
float NV = dot(N, V);
|
||||
|
||||
@@ -13,8 +13,6 @@ void node_subsurface_scattering(vec4 color,
|
||||
out Closure result)
|
||||
{
|
||||
color = max(color, vec4(0.0));
|
||||
scale = max(scale, 0.0);
|
||||
radius = max(radius, vec3(0));
|
||||
ior = max(ior, 1e-5);
|
||||
N = safe_normalize(N);
|
||||
|
||||
@@ -22,7 +20,7 @@ void node_subsurface_scattering(vec4 color,
|
||||
sss_data.weight = weight;
|
||||
sss_data.color = color.rgb;
|
||||
sss_data.N = N;
|
||||
sss_data.sss_radius = radius * scale;
|
||||
sss_data.sss_radius = max(radius * scale, vec3(0.0));
|
||||
|
||||
#ifdef GPU_SHADER_EEVEE_LEGACY_DEFINES
|
||||
if (do_sss == 0.0) {
|
||||
|
||||
Reference in New Issue
Block a user