Cycles/EEVEE: Change specular tint in Principled BSDF from float to color #112192
|
@ -738,6 +738,7 @@ ccl_device void bsdf_microfacet_setup_fresnel_generalized_schlick(
|
|||
ccl_private FresnelGeneralizedSchlick *fresnel,
|
||||
const bool preserve_energy)
|
||||
{
|
||||
fresnel->f0 = saturate(fresnel->f0);
|
||||
bsdf->fresnel_type = MicrofacetFresnel::GENERALIZED_SCHLICK;
|
||||
bsdf->fresnel = fresnel;
|
||||
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
|
||||
|
|
|
@ -15,7 +15,7 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
|
|||
float SubsurfaceAnisotropy = 0.0,
|
||||
float Metallic = 0.0,
|
||||
float Specular = 0.5,
|
||||
float SpecularTint = 0.0,
|
||||
color SpecularTint = color(1.0),
|
||||
float Roughness = 0.5,
|
||||
float Anisotropic = 0.0,
|
||||
float AnisotropicRotation = 0.0,
|
||||
|
@ -67,14 +67,9 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
|
|||
BSDF = mix(BSDF, BaseColor * SubsurfBSDF, Subsurface);
|
||||
}
|
||||
|
||||
color f0 = color(F0_from_ior(IOR));
|
||||
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);
|
||||
color f0 = F0_from_ior(IOR) * SpecularTint * 2.0 * Specular;
|
||||
color f90 = color(1.0);
|
||||
|
||||
BSDF = layer(
|
||||
generalized_schlick_bsdf(
|
||||
|
@ -84,12 +79,14 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
|
|||
|
||||
closure color TransmissionBSDF = 0;
|
||||
if (Metallic < 1.0 && Transmission > 0.0) {
|
||||
color reflectTint = mix(color(1.0), BaseColor, SpecularTint);
|
||||
float eta = max(IOR, 1e-5);
|
||||
eta = backfacing() ? 1.0 / eta : eta;
|
||||
|
||||
TransmissionBSDF = dielectric_bsdf(
|
||||
Normal, vector(0.0), reflectTint, sqrt(BaseColor), r2, r2, eta, distribution);
|
||||
color f0 = F0_from_ior(eta) * SpecularTint;
|
||||
color f90 = color(1.0);
|
||||
|
||||
TransmissionBSDF = generalized_schlick_bsdf(
|
||||
Normal, vector(0.0), color(1.0), sqrt(BaseColor), r2, r2, f0, f90, -eta, distribution),
|
||||
BSDF = mix(BSDF, TransmissionBSDF, clamp(Transmission, 0.0, 1.0));
|
||||
}
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
float subsurface = param2;
|
||||
float specular = stack_load_float(stack, specular_offset);
|
||||
float roughness = stack_load_float(stack, roughness_offset);
|
||||
float specular_tint = stack_load_float(stack, specular_tint_offset);
|
||||
Spectrum specular_tint = rgb_to_spectrum(stack_load_float3(stack, specular_tint_offset));
|
||||
float anisotropic = stack_load_float(stack, anisotropic_offset);
|
||||
float sheen = stack_load_float(stack, sheen_offset);
|
||||
float3 sheen_tint = stack_load_float3(stack, sheen_tint_offset);
|
||||
|
@ -287,9 +287,9 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
if (glass_caustics && transmission > CLOSURE_WEIGHT_CUTOFF) {
|
||||
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
|
||||
sd, sizeof(MicrofacetBsdf), transmission * weight);
|
||||
ccl_private FresnelDielectricTint *fresnel =
|
||||
(bsdf != NULL) ? (ccl_private FresnelDielectricTint *)closure_alloc_extra(
|
||||
sd, sizeof(FresnelDielectricTint)) :
|
||||
ccl_private FresnelGeneralizedSchlick *fresnel =
|
||||
(bsdf != NULL) ? (ccl_private FresnelGeneralizedSchlick *)closure_alloc_extra(
|
||||
sd, sizeof(FresnelGeneralizedSchlick)) :
|
||||
NULL;
|
||||
|
||||
if (bsdf && fresnel) {
|
||||
|
@ -299,14 +299,16 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
bsdf->alpha_x = bsdf->alpha_y = sqr(roughness);
|
||||
bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / eta : eta;
|
||||
|
||||
fresnel->reflection_tint = mix(
|
||||
one_spectrum(), rgb_to_spectrum(base_color), specular_tint);
|
||||
fresnel->f0 = F0_from_ior(eta) * specular_tint;
|
||||
fresnel->f90 = one_spectrum();
|
||||
fresnel->exponent = -eta;
|
||||
fresnel->reflection_tint = one_spectrum();
|
||||
fresnel->transmission_tint = sqrt(rgb_to_spectrum(base_color));
|
||||
|
||||
/* setup bsdf */
|
||||
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
|
||||
const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
|
||||
bsdf_microfacet_setup_fresnel_dielectric_tint(kg, bsdf, sd, fresnel, is_multiggx);
|
||||
bsdf_microfacet_setup_fresnel_generalized_schlick(kg, bsdf, sd, fresnel, is_multiggx);
|
||||
|
||||
/* Attenuate other components */
|
||||
weight *= (1.0f - transmission);
|
||||
|
@ -329,11 +331,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
bsdf->alpha_x = alpha_x;
|
||||
bsdf->alpha_y = alpha_y;
|
||||
|
||||
float m_cdlum = linear_rgb_to_gray(kg, base_color);
|
||||
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) * 2.0f * specular * specular_tint;
|
||||
fresnel->f90 = one_spectrum();
|
||||
fresnel->exponent = -eta;
|
||||
fresnel->reflection_tint = one_spectrum();
|
||||
|
|
|
@ -2707,7 +2707,7 @@ NODE_DEFINE(PrincipledBsdfNode)
|
|||
SOCKET_IN_FLOAT(subsurface_anisotropy, "Subsurface Anisotropy", 0.0f);
|
||||
SOCKET_IN_FLOAT(specular, "Specular", 0.0f);
|
||||
SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
|
||||
SOCKET_IN_FLOAT(specular_tint, "Specular Tint", 0.0f);
|
||||
SOCKET_IN_COLOR(specular_tint, "Specular Tint", one_float3());
|
||||
SOCKET_IN_FLOAT(anisotropic, "Anisotropic", 0.0f);
|
||||
SOCKET_IN_FLOAT(sheen, "Sheen", 0.0f);
|
||||
SOCKET_IN_FLOAT(sheen_roughness, "Sheen Roughness", 0.5f);
|
||||
|
|
|
@ -527,7 +527,7 @@ class PrincipledBsdfNode : public BsdfBaseNode {
|
|||
NODE_SOCKET_API(float, subsurface)
|
||||
NODE_SOCKET_API(float, specular)
|
||||
NODE_SOCKET_API(float, roughness)
|
||||
NODE_SOCKET_API(float, specular_tint)
|
||||
NODE_SOCKET_API(float3, specular_tint)
|
||||
NODE_SOCKET_API(float, anisotropic)
|
||||
NODE_SOCKET_API(float, sheen)
|
||||
NODE_SOCKET_API(float, sheen_roughness)
|
||||
|
|
|
@ -791,6 +791,65 @@ static void version_principled_bsdf_coat(bNodeTree *ntree)
|
|||
ntree, SH_NODE_BSDF_PRINCIPLED, "Clearcoat Normal", "Coat Normal");
|
||||
}
|
||||
|
||||
/* Convert specular tint in Principled BSDF. */
|
||||
static void version_principled_bsdf_specular_tint(bNodeTree *ntree)
|
||||
{
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
if (node->type != SH_NODE_BSDF_PRINCIPLED) {
|
||||
continue;
|
||||
}
|
||||
bNodeSocket *specular_tint_sock = nodeFindSocket(node, SOCK_IN, "Specular Tint");
|
||||
if (specular_tint_sock->type == SOCK_RGBA) {
|
||||
/* Node is already updated. */
|
||||
continue;
|
||||
}
|
||||
|
||||
bNodeSocket *base_color_sock = nodeFindSocket(node, SOCK_IN, "Base Color");
|
||||
float specular_tint_old = *version_cycles_node_socket_float_value(specular_tint_sock);
|
||||
float *base_color = version_cycles_node_socket_rgba_value(base_color_sock);
|
||||
|
||||
/* Change socket type to Color. */
|
||||
nodeModifySocketTypeStatic(ntree, node, specular_tint_sock, SOCK_RGBA, 0);
|
||||
|
||||
static float one[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
/* If any of the two inputs is dynamic, we add a Mix node. */
|
||||
if (base_color_sock->link || specular_tint_sock->link) {
|
||||
bNode *mix = nodeAddStaticNode(nullptr, ntree, SH_NODE_MIX);
|
||||
static_cast<NodeShaderMix *>(mix->storage)->data_type = SOCK_RGBA;
|
||||
mix->locx = node->locx - 170;
|
||||
mix->locy = node->locy - 120;
|
||||
|
||||
bNodeSocket *a_in = nodeFindSocket(mix, SOCK_IN, "A_Color");
|
||||
bNodeSocket *b_in = nodeFindSocket(mix, SOCK_IN, "B_Color");
|
||||
bNodeSocket *fac_in = nodeFindSocket(mix, SOCK_IN, "Factor_Float");
|
||||
bNodeSocket *result_out = nodeFindSocket(mix, SOCK_OUT, "Result_Color");
|
||||
|
||||
copy_v4_v4(version_cycles_node_socket_rgba_value(a_in), one);
|
||||
copy_v4_v4(version_cycles_node_socket_rgba_value(b_in), base_color);
|
||||
*version_cycles_node_socket_float_value(fac_in) = specular_tint_old;
|
||||
|
||||
if (base_color_sock->link) {
|
||||
nodeAddLink(
|
||||
ntree, base_color_sock->link->fromnode, base_color_sock->link->fromsock, mix, b_in);
|
||||
}
|
||||
if (specular_tint_sock->link) {
|
||||
nodeAddLink(ntree,
|
||||
specular_tint_sock->link->fromnode,
|
||||
specular_tint_sock->link->fromsock,
|
||||
mix,
|
||||
fac_in);
|
||||
nodeRemLink(ntree, specular_tint_sock->link);
|
||||
}
|
||||
nodeAddLink(ntree, mix, result_out, node, specular_tint_sock);
|
||||
}
|
||||
|
||||
float *specular_tint = version_cycles_node_socket_rgba_value(specular_tint_sock);
|
||||
/* Mix the fixed values. */
|
||||
interp_v4_v4v4(specular_tint, one, base_color, specular_tint_old);
|
||||
}
|
||||
}
|
||||
|
||||
static void version_copy_socket(bNodeTreeInterfaceSocket &dst,
|
||||
const bNodeTreeInterfaceSocket &src,
|
||||
char *identifier)
|
||||
|
@ -1366,5 +1425,13 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
|
||||
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
|
||||
if (ntree->type == NTREE_SHADER) {
|
||||
/* Convert specular tint on the Principled BSDF. */
|
||||
version_principled_bsdf_specular_tint(ntree);
|
||||
}
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,7 +93,15 @@ float ambient_occlusion_eval(vec3 normal,
|
|||
vec3 safe_normalize(vec3 N);
|
||||
float fast_sqrt(float a);
|
||||
vec3 cameraVec(vec3 P);
|
||||
vec2 bsdf_lut(float a, float b, float c, float d);
|
||||
void bsdf_lut(vec3 F0,
|
||||
vec3 F90,
|
||||
vec3 transmission_tint,
|
||||
float cos_theta,
|
||||
float roughness,
|
||||
float ior,
|
||||
float do_multiscatter,
|
||||
out vec3 reflectance,
|
||||
out vec3 transmittance);
|
||||
vec2 brdf_lut(float a, float b);
|
||||
vec3 F_brdf_multi_scatter(vec3 a, vec3 b, vec2 c);
|
||||
vec3 F_brdf_single_scatter(vec3 a, vec3 b, vec2 c);
|
||||
|
|
|
@ -101,24 +101,35 @@ vec3 lut_coords_bsdf(float cos_theta, float roughness, float ior)
|
|||
return coords;
|
||||
}
|
||||
|
||||
/* Computes the reflectance and transmittance based on the BSDF LUT. */
|
||||
vec2 bsdf_lut(float cos_theta, float roughness, float ior, float do_multiscatter)
|
||||
/* Computes the reflectance and transmittance based on the tint (`f0`, `f90`, `transmission_tint`)
|
||||
* and the BSDF LUT. */
|
||||
void bsdf_lut(vec3 F0,
|
||||
vec3 F90,
|
||||
vec3 transmission_tint,
|
||||
float cos_theta,
|
||||
float roughness,
|
||||
float ior,
|
||||
float do_multiscatter,
|
||||
out vec3 reflectance,
|
||||
out vec3 transmittance)
|
||||
{
|
||||
if (ior == 1.0) {
|
||||
return vec2(0.0, 1.0);
|
||||
reflectance = vec3(0.0);
|
||||
transmittance = transmission_tint;
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 split_sum;
|
||||
float transmission_factor;
|
||||
float F0 = F0_from_ior(ior);
|
||||
float F90 = 1.0;
|
||||
|
||||
if (ior >= 1.0) {
|
||||
if (ior > 1.0) {
|
||||
split_sum = brdf_lut(cos_theta, roughness);
|
||||
transmission_factor = sample_3D_texture(utilTex, lut_coords_btdf(cos_theta, roughness, ior)).a;
|
||||
/* 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`. */
|
||||
F90 = saturate(2.33 / 0.33 * (ior - 1.0) / (ior + 1.0));
|
||||
if (all(equal(F90, vec3(1.0)))) {
|
||||
F90 = vec3(saturate(2.33 / 0.33 * (ior - 1.0) / (ior + 1.0)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
vec3 bsdf = sample_3D_texture(utilTex, lut_coords_bsdf(cos_theta, roughness, ior)).rgb;
|
||||
|
@ -126,20 +137,34 @@ vec2 bsdf_lut(float cos_theta, float roughness, float ior, float do_multiscatter
|
|||
transmission_factor = bsdf.b;
|
||||
}
|
||||
|
||||
float reflectance = F_brdf_single_scatter(vec3(F0), vec3(F90), split_sum).r;
|
||||
float transmittance = (1.0 - F0) * transmission_factor;
|
||||
reflectance = F_brdf_single_scatter(F0, F90, split_sum);
|
||||
transmittance = (vec3(1.0) - F0) * transmission_factor * transmission_tint;
|
||||
|
||||
if (do_multiscatter != 0.0) {
|
||||
float Ess = F0 * split_sum.x + split_sum.y + (1.0 - F0) * transmission_factor;
|
||||
/* TODO: maybe add saturation for higher roughness similar as in `F_brdf_multi_scatter()`.
|
||||
* However, it is not necessarily desirable that the users see a different color than they
|
||||
* picked. */
|
||||
float scale = 1.0 / Ess;
|
||||
float real_F0 = F0_from_ior(ior);
|
||||
float Ess = real_F0 * split_sum.x + split_sum.y + (1.0 - real_F0) * transmission_factor;
|
||||
float Ems = 1.0 - Ess;
|
||||
/* Assume that the transmissive tint makes up most of the overall color if it's not zero. */
|
||||
vec3 Favg = all(equal(transmission_tint, vec3(0.0))) ? F0 + (F90 - F0) / 21.0 :
|
||||
transmission_tint;
|
||||
|
||||
vec3 scale = 1.0 / (1.0 - Ems * Favg);
|
||||
reflectance *= scale;
|
||||
transmittance *= scale;
|
||||
}
|
||||
|
||||
return vec2(reflectance, transmittance);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Computes the reflectance and transmittance based on the BSDF LUT. */
|
||||
vec2 bsdf_lut(float cos_theta, float roughness, float ior, float do_multiscatter)
|
||||
{
|
||||
float F0 = F0_from_ior(ior);
|
||||
vec3 color = vec3(1.0);
|
||||
vec3 reflectance, transmittance;
|
||||
bsdf_lut(
|
||||
F0, color, color, cos_theta, roughness, ior, do_multiscatter, reflectance, transmittance);
|
||||
return vec2(reflectance.r, transmittance.r);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -43,6 +43,21 @@ vec2 bsdf_lut(float a, float b, float c, float d)
|
|||
return vec2(0.0);
|
||||
}
|
||||
|
||||
void bsdf_lut(vec3 F0,
|
||||
vec3 F90,
|
||||
vec3 transmission_tint,
|
||||
float cos_theta,
|
||||
float roughness,
|
||||
float ior,
|
||||
float do_multiscatter,
|
||||
out vec3 reflectance,
|
||||
out vec3 transmittance)
|
||||
{
|
||||
reflectance = vec3(0.0);
|
||||
transmittance = vec3(0.0);
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 brdf_lut(float a, float b)
|
||||
{
|
||||
return vec2(0.0);
|
||||
|
|
|
@ -320,26 +320,37 @@ vec3 lut_coords_btdf(float cos_theta, float roughness, float ior)
|
|||
return vec3(sqrt((ior - 1.0) / (ior + 1.0)), sqrt(1.0 - cos_theta), roughness);
|
||||
}
|
||||
|
||||
/* Computes the reflectance and transmittance based on the BSDF LUT. */
|
||||
vec2 bsdf_lut(float cos_theta, float roughness, float ior, float do_multiscatter)
|
||||
/* Computes the reflectance and transmittance based on the tint (`f0`, `f90`, `transmission_tint`)
|
||||
* and the BSDF LUT. */
|
||||
void bsdf_lut(vec3 F0,
|
||||
vec3 F90,
|
||||
vec3 transmission_tint,
|
||||
float cos_theta,
|
||||
float roughness,
|
||||
float ior,
|
||||
float do_multiscatter,
|
||||
out vec3 reflectance,
|
||||
out vec3 transmittance)
|
||||
{
|
||||
#ifdef EEVEE_UTILITY_TX
|
||||
if (ior == 1.0) {
|
||||
return vec2(0.0, 1.0);
|
||||
reflectance = vec3(0.0);
|
||||
transmittance = transmission_tint;
|
||||
return;
|
||||
}
|
||||
|
||||
vec2 split_sum;
|
||||
float transmission_factor;
|
||||
float F0 = F0_from_ior(ior);
|
||||
float F90 = 1.0;
|
||||
|
||||
if (ior >= 1.0) {
|
||||
if (ior > 1.0) {
|
||||
split_sum = brdf_lut(cos_theta, roughness);
|
||||
vec3 coords = lut_coords_btdf(cos_theta, roughness, ior);
|
||||
transmission_factor = utility_tx_sample_bsdf_lut(utility_tx, coords.xy, coords.z).a;
|
||||
/* 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`. */
|
||||
F90 = saturate(2.33 / 0.33 * (ior - 1.0) / (ior + 1.0));
|
||||
if (all(equal(F90, vec3(1.0)))) {
|
||||
F90 = vec3(saturate(2.33 / 0.33 * (ior - 1.0) / (ior + 1.0)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
vec3 coords = lut_coords_bsdf(cos_theta, roughness, ior);
|
||||
|
@ -348,23 +359,37 @@ vec2 bsdf_lut(float cos_theta, float roughness, float ior, float do_multiscatter
|
|||
transmission_factor = bsdf.b;
|
||||
}
|
||||
|
||||
float reflectance = F_brdf_single_scatter(vec3(F0), vec3(F90), split_sum).r;
|
||||
float transmittance = (1.0 - F0) * transmission_factor;
|
||||
reflectance = F_brdf_single_scatter(F0, F90, split_sum);
|
||||
transmittance = (vec3(1.0) - F0) * transmission_factor * transmission_tint;
|
||||
|
||||
if (do_multiscatter != 0.0) {
|
||||
float Ess = F0 * split_sum.x + split_sum.y + (1.0 - F0) * transmission_factor;
|
||||
/* TODO: maybe add saturation for higher roughness similar as in `F_brdf_multi_scatter()`.
|
||||
* However, it is not necessarily desirable that the users see a different color than they
|
||||
* picked. */
|
||||
float scale = 1.0 / Ess;
|
||||
float real_F0 = F0_from_ior(ior);
|
||||
float Ess = real_F0 * split_sum.x + split_sum.y + (1.0 - real_F0) * transmission_factor;
|
||||
float Ems = 1.0 - Ess;
|
||||
/* Assume that the transmissive tint makes up most of the overall color if it's not zero. */
|
||||
vec3 Favg = all(equal(transmission_tint, vec3(0.0))) ? F0 + (F90 - F0) / 21.0 :
|
||||
transmission_tint;
|
||||
|
||||
vec3 scale = 1.0 / (1.0 - Ems * Favg);
|
||||
reflectance *= scale;
|
||||
transmittance *= scale;
|
||||
}
|
||||
|
||||
return vec2(reflectance, transmittance);
|
||||
#else
|
||||
return vec2(0.0);
|
||||
reflectance = vec3(0.0);
|
||||
transmittance = vec3(0.0);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/* Computes the reflectance and transmittance based on the BSDF LUT. */
|
||||
vec2 bsdf_lut(float cos_theta, float roughness, float ior, float do_multiscatter)
|
||||
{
|
||||
float F0 = F0_from_ior(ior);
|
||||
vec3 color = vec3(1.0);
|
||||
vec3 reflectance, transmittance;
|
||||
bsdf_lut(
|
||||
F0, color, color, cos_theta, roughness, ior, do_multiscatter, reflectance, transmittance);
|
||||
return vec2(reflectance.r, transmittance.r);
|
||||
}
|
||||
|
||||
#ifdef EEVEE_MATERIAL_STUBS
|
||||
|
|
|
@ -32,7 +32,7 @@ void node_bsdf_principled(vec4 base_color,
|
|||
float subsurface_ior,
|
||||
float subsurface_anisotropy,
|
||||
float specular,
|
||||
float specular_tint,
|
||||
vec4 specular_tint,
|
||||
float anisotropic,
|
||||
float anisotropic_rotation,
|
||||
vec3 T,
|
||||
|
@ -109,10 +109,11 @@ void node_bsdf_principled(vec4 base_color,
|
|||
ClosureReflection reflection_data;
|
||||
reflection_data.N = N;
|
||||
reflection_data.roughness = roughness;
|
||||
vec2 split_sum = brdf_lut(NV, roughness);
|
||||
|
||||
if (true) {
|
||||
vec3 f0 = base_color.rgb;
|
||||
vec3 f90 = vec3(1.0);
|
||||
vec2 split_sum = brdf_lut(NV, roughness);
|
||||
vec3 metallic_brdf = (do_multiscatter != 0.0) ? F_brdf_multi_scatter(f0, f90, split_sum) :
|
||||
F_brdf_single_scatter(f0, f90, split_sum);
|
||||
reflection_data.color = weight * metallic * metallic_brdf;
|
||||
|
@ -122,15 +123,18 @@ void node_bsdf_principled(vec4 base_color,
|
|||
|
||||
/* Transmission component */
|
||||
ClosureRefraction refraction_data;
|
||||
/* TODO: change `specular_tint` to rgb. */
|
||||
vec3 reflection_tint = mix(vec3(1.0), base_color.rgb, specular_tint);
|
||||
vec3 reflection_tint = specular_tint.rgb;
|
||||
if (true) {
|
||||
vec2 bsdf = bsdf_lut(NV, roughness, ior, do_multiscatter);
|
||||
vec3 F0 = vec3(F0_from_ior(ior)) * reflection_tint;
|
||||
vec3 F90 = vec3(1.0);
|
||||
vec3 reflectance, transmittance;
|
||||
bsdf_lut(
|
||||
F0, F90, base_color.rgb, NV, roughness, ior, do_multiscatter, reflectance, transmittance);
|
||||
|
||||
reflection_data.color += weight * transmission * bsdf.x * reflection_tint;
|
||||
reflection_data.color += weight * transmission * reflectance;
|
||||
|
||||
refraction_data.weight = weight * transmission * bsdf.y;
|
||||
refraction_data.color = base_color.rgb * coat_tint.rgb;
|
||||
refraction_data.weight = weight * transmission;
|
||||
refraction_data.color = transmittance * coat_tint.rgb;
|
||||
refraction_data.N = N;
|
||||
refraction_data.roughness = roughness;
|
||||
refraction_data.ior = ior;
|
||||
|
@ -140,17 +144,15 @@ void node_bsdf_principled(vec4 base_color,
|
|||
|
||||
/* Specular component */
|
||||
if (true) {
|
||||
vec3 f0 = vec3(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;
|
||||
vec3 F0 = vec3(F0_from_ior(ior)) * 2.0 * specular * reflection_tint;
|
||||
F0 = clamp(F0, vec3(0.0), vec3(1.0));
|
||||
vec3 F90 = vec3(1.0);
|
||||
vec3 reflectance, unused;
|
||||
bsdf_lut(F0, F90, vec3(0.0), NV, roughness, ior, do_multiscatter, reflectance, unused);
|
||||
|
||||
vec3 specular_brdf = (do_multiscatter != 0.0) ? F_brdf_multi_scatter(f0, f90, split_sum) :
|
||||
F_brdf_single_scatter(f0, f90, split_sum);
|
||||
reflection_data.color += weight * specular_brdf;
|
||||
reflection_data.color += weight * reflectance;
|
||||
/* Attenuate lower layers */
|
||||
weight *= (1.0 - max_v3(specular_brdf));
|
||||
weight *= (1.0 - max_v3(reflectance));
|
||||
}
|
||||
|
||||
/* Diffuse component */
|
||||
|
|
|
@ -110,11 +110,10 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
#define SOCK_SPECULAR_ID 13
|
||||
spec.add_input<decl::Float>("Specular Tint")
|
||||
.default_value(0.0f)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
spec.add_input<decl::Color>("Specular Tint")
|
||||
.default_value({1.0f, 1.0f, 1.0f, 1.0f})
|
||||
.description(
|
||||
"Tint of the specular reflection at normal incidence. Affects dielectric materials");
|
||||
#define SOCK_SPECULAR_TINT_ID 14
|
||||
spec.add_input<decl::Float>("Anisotropic")
|
||||
.default_value(0.0f)
|
||||
|
|
Loading…
Reference in New Issue