Cycles/EEVEE: Change Specular input on Principled BSDF to affect IOR #112552
|
@ -42,3 +42,9 @@ float F0_from_ior(float eta)
|
|||
float f0 = (eta - 1.0) / (eta + 1.0);
|
||||
return f0 * f0;
|
||||
}
|
||||
|
||||
float ior_from_F0(float f0)
|
||||
{
|
||||
float sqrt_f0 = sqrt(clamp(f0, 0.0, 0.99));
|
||||
return (1.0 + sqrt_f0) / (1.0 - sqrt_f0);
|
||||
}
|
||||
|
|
|
@ -50,10 +50,15 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
|
|||
}
|
||||
|
||||
if (Metallic < 1.0 && Transmission < 1.0) {
|
||||
float eta = ior_from_F0(2.0 * Specular * F0_from_ior(IOR));
|
||||
if (IOR < 1.0) {
|
||||
eta = 1.0 / eta;
|
||||
}
|
||||
|
||||
BSDF = BaseColor * diffuse(Normal);
|
||||
if (Subsurface > 1e-5) {
|
||||
vector radius = SubsurfaceScale * SubsurfaceRadius;
|
||||
float subsurface_ior = (subsurface_method == "random_walk") ? SubsurfaceIOR : IOR;
|
||||
float subsurface_ior = (subsurface_method == "random_walk") ? SubsurfaceIOR : eta;
|
||||
closure color SubsurfBSDF = bssrdf(subsurface_method,
|
||||
Normal,
|
||||
SubsurfaceScale * SubsurfaceRadius,
|
||||
|
@ -67,18 +72,17 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
|
|||
BSDF = mix(BSDF, BaseColor * SubsurfBSDF, Subsurface);
|
||||
}
|
||||
|
||||
color f0 = color(F0_from_ior(IOR));
|
||||
color f0 = color(F0_from_ior(eta));
|
||||
color f90 = color(1.0);
|
||||
|
||||
/* Apply specular tint */
|
||||
float m_cdlum = luminance(BaseColor);
|
||||
color m_ctint = m_cdlum > 0.0 ? BaseColor / m_cdlum : color(1.0);
|
||||
color specTint = mix(color(1.0), m_ctint, SpecularTint);
|
||||
f0 *= (specTint * 2.0 * Specular);
|
||||
f0 *= mix(color(1.0), m_ctint, SpecularTint);
|
||||
|
||||
BSDF = layer(
|
||||
generalized_schlick_bsdf(
|
||||
Normal, T, color(1.0), color(0.0), alpha_x, alpha_y, f0, f90, -IOR, distribution),
|
||||
Normal, T, color(1.0), color(0.0), alpha_x, alpha_y, f0, f90, -eta, distribution),
|
||||
BSDF);
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
case CLOSURE_BSDF_PRINCIPLED_ID: {
|
||||
uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset,
|
||||
sheen_offset, sheen_tint_offset, sheen_roughness_offset, coat_offset,
|
||||
coat_roughness_offset, coat_ior_offset, eta_offset, transmission_offset,
|
||||
coat_roughness_offset, coat_ior_offset, ior_offset, transmission_offset,
|
||||
anisotropic_rotation_offset, coat_tint_offset, coat_normal_offset, dummy, alpha_offset,
|
||||
emission_strength_offset, emission_offset;
|
||||
uint4 data_node2 = read_node(kg, &offset);
|
||||
|
@ -90,7 +90,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
svm_unpack_node_uchar4(
|
||||
data_node.w, &sheen_offset, &sheen_tint_offset, &sheen_roughness_offset, &dummy);
|
||||
svm_unpack_node_uchar4(data_node2.x,
|
||||
&eta_offset,
|
||||
&ior_offset,
|
||||
&transmission_offset,
|
||||
&anisotropic_rotation_offset,
|
||||
&coat_normal_offset);
|
||||
|
@ -113,7 +113,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
float3 coat_tint = stack_load_float3(stack, coat_tint_offset);
|
||||
float transmission = saturatef(stack_load_float(stack, transmission_offset));
|
||||
float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
|
||||
float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
|
||||
float ior = fmaxf(stack_load_float(stack, ior_offset), 1e-5f);
|
||||
|
||||
ClosureType distribution = (ClosureType)data_node2.y;
|
||||
ClosureType subsurface_method = (ClosureType)data_node2.z;
|
||||
|
@ -297,7 +297,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
bsdf->T = zero_float3();
|
||||
|
||||
bsdf->alpha_x = bsdf->alpha_y = sqr(roughness);
|
||||
bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
|
||||
bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / ior : ior;
|
||||
|
||||
fresnel->reflection_tint = mix(
|
||||
one_spectrum(), rgb_to_spectrum(base_color), specular_tint);
|
||||
|
@ -313,6 +313,12 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
}
|
||||
}
|
||||
|
||||
/* Apply IOR adjustment for specular and subsurface components. */
|
||||
float eta = ior_from_F0(2.0f * specular * F0_from_ior(ior));
|
||||
if (ior < 1.0f) {
|
||||
eta = 1.0f / eta;
|
||||
}
|
||||
|
||||
/* Specular component */
|
||||
if (reflective_caustics) {
|
||||
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
|
||||
|
@ -333,7 +339,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
float3 m_ctint = m_cdlum > 0.0f ? base_color / m_cdlum : one_float3();
|
||||
float3 specTint = mix(one_spectrum(), rgb_to_spectrum(m_ctint), specular_tint);
|
||||
|
||||
fresnel->f0 = F0_from_ior(eta) * 2.0f * specular * specTint;
|
||||
fresnel->f0 = F0_from_ior(eta) * specTint;
|
||||
fresnel->f90 = one_spectrum();
|
||||
fresnel->exponent = -eta;
|
||||
fresnel->reflection_tint = one_spectrum();
|
||||
|
|
|
@ -140,11 +140,11 @@ void node_bsdf_principled(vec4 base_color,
|
|||
|
||||
/* Specular component */
|
||||
if (true) {
|
||||
vec3 f0 = vec3(F0_from_ior(ior));
|
||||
vec3 f0 = vec3(2.0 * specular * F0_from_ior(ior));
|
||||
/* Gradually increase `f90` from 0 to 1 when IOR is in the range of [1.0, 1.33], to avoid harsh
|
||||
* transition at `IOR == 1`. */
|
||||
vec3 f90 = sqrt(saturate(f0 / 0.02));
|
||||
f0 *= 2.0 * specular * reflection_tint;
|
||||
f0 *= reflection_tint;
|
||||
|
||||
vec3 specular_brdf = (do_multiscatter != 0.0) ? F_brdf_multi_scatter(f0, f90, split_sum) :
|
||||
F_brdf_single_scatter(f0, f90, split_sum);
|
||||
|
|
|
@ -108,7 +108,10 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
.default_value(0.5f)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
.subtype(PROP_FACTOR)
|
||||
.description(
|
||||
"Adjustment to the IOR to increase or decrease specular intensity "
|
||||
"(0.5 means no adjustment, 0 removes all reflections, 1 doubles them)");
|
||||
#define SOCK_SPECULAR_ID 13
|
||||
spec.add_input<decl::Float>("Specular Tint")
|
||||
.default_value(0.0f)
|
||||
|
|
Loading…
Reference in New Issue