Cycles: Rework Principled BSDF Clearcoat #110993
|
@ -139,7 +139,7 @@ class UsdToCycles {
|
|||
{TfToken("diffuseColor"), ustring("base_color")},
|
||||
{TfToken("emissiveColor"), ustring("emission")},
|
||||
{TfToken("specularColor"), ustring("specular")},
|
||||
{TfToken("clearcoatRoughness"), ustring("clearcoat_roughness")},
|
||||
{TfToken("clearcoatRoughness"), ustring("coat_roughness")},
|
||||
{TfToken("opacity"), ustring("alpha")},
|
||||
// opacityThreshold
|
||||
// occlusion
|
||||
|
|
|
@ -153,7 +153,6 @@ ccl_device_inline int bsdf_sample(KernelGlobals kg,
|
|||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
|
||||
label = bsdf_microfacet_ggx_sample(
|
||||
|
@ -284,7 +283,6 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
|
|||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
|
||||
|
@ -385,7 +383,6 @@ ccl_device_inline int bsdf_label(const KernelGlobals kg,
|
|||
label = LABEL_TRANSMIT | LABEL_TRANSPARENT;
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
|
||||
|
@ -484,7 +481,6 @@ ccl_device_inline
|
|||
eval = bsdf_transparent_eval(sc, sd->wi, wo, pdf);
|
||||
break;
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
|
||||
eval = bsdf_microfacet_ggx_eval(sc, Ng, sd->wi, wo, pdf);
|
||||
|
@ -555,7 +551,6 @@ ccl_device void bsdf_blur(KernelGlobals kg, ccl_private ShaderClosure *sc, float
|
|||
#if defined(__SVM__) || defined(__OSL__)
|
||||
switch (sc->type) {
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID:
|
||||
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
|
||||
|
|
|
@ -377,17 +377,6 @@ ccl_device Spectrum bsdf_microfacet_estimate_albedo(KernelGlobals kg,
|
|||
return albedo;
|
||||
}
|
||||
|
||||
/* Generalized Trowbridge-Reitz for clearcoat. */
|
||||
ccl_device_forceinline float bsdf_clearcoat_D(float alpha2, float cos_NH)
|
||||
{
|
||||
if (alpha2 >= 1.0f) {
|
||||
return M_1_PI_F;
|
||||
}
|
||||
|
||||
const float t = 1.0f + (alpha2 - 1.0f) * cos_NH * cos_NH;
|
||||
return (alpha2 - 1.0f) / (M_PI_F * logf(alpha2) * t);
|
||||
}
|
||||
|
||||
/* Smith shadowing-masking term, here in the non-separable form.
|
||||
* For details, see:
|
||||
* Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs.
|
||||
|
@ -529,18 +518,7 @@ ccl_device Spectrum bsdf_microfacet_eval(ccl_private const ShaderClosure *sc,
|
|||
* harder to compute. */
|
||||
if (alpha_x == alpha_y || is_transmission) { /* Isotropic. */
|
||||
float alpha2 = alpha_x * alpha_y;
|
||||
|
||||
if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
|
||||
D = bsdf_clearcoat_D(alpha2, cos_NH);
|
||||
|
||||
/* The masking-shadowing term for clearcoat has a fixed alpha of 0.25
|
||||
* => alpha2 = 0.25 * 0.25 */
|
||||
alpha2 = 0.0625f;
|
||||
}
|
||||
else {
|
||||
D = bsdf_D<m_type>(alpha2, cos_NH);
|
||||
}
|
||||
|
||||
D = bsdf_D<m_type>(alpha2, cos_NH);
|
||||
lambdaI = bsdf_lambda<m_type>(alpha2, cos_NI);
|
||||
lambdaO = bsdf_lambda<m_type>(alpha2, cos_NO);
|
||||
}
|
||||
|
@ -687,17 +665,7 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
|
|||
const float cos_NH = dot(N, H);
|
||||
const float cos_NO = dot(N, *wo);
|
||||
|
||||
if (bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID) {
|
||||
D = bsdf_clearcoat_D(alpha2, cos_NH);
|
||||
|
||||
/* The masking-shadowing term for clearcoat has a fixed alpha of 0.25
|
||||
* => alpha2 = 0.25 * 0.25 */
|
||||
alpha2 = 0.0625f;
|
||||
}
|
||||
else {
|
||||
D = bsdf_D<m_type>(alpha2, cos_NH);
|
||||
}
|
||||
|
||||
D = bsdf_D<m_type>(alpha2, cos_NH);
|
||||
lambdaO = bsdf_lambda<m_type>(alpha2, cos_NO);
|
||||
lambdaI = bsdf_lambda<m_type>(alpha2, cos_NI);
|
||||
}
|
||||
|
@ -831,6 +799,14 @@ ccl_device void bsdf_microfacet_setup_fresnel_constant(KernelGlobals kg,
|
|||
microfacet_ggx_preserve_energy(kg, bsdf, sd, color);
|
||||
}
|
||||
|
||||
ccl_device void bsdf_microfacet_setup_fresnel_dielectric(KernelGlobals kg,
|
||||
ccl_private MicrofacetBsdf *bsdf,
|
||||
ccl_private const ShaderData *sd)
|
||||
{
|
||||
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC;
|
||||
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
|
||||
}
|
||||
|
||||
/* GGX microfacet with Smith shadow-masking from:
|
||||
*
|
||||
* Microfacet Models for Refraction through Rough Surfaces
|
||||
|
@ -856,21 +832,6 @@ ccl_device int bsdf_microfacet_ggx_setup(ccl_private MicrofacetBsdf *bsdf)
|
|||
return SD_BSDF | bsdf_microfacet_eval_flag(bsdf);
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_ggx_clearcoat_setup(KernelGlobals kg,
|
||||
ccl_private MicrofacetBsdf *bsdf,
|
||||
ccl_private const ShaderData *sd)
|
||||
{
|
||||
bsdf->alpha_x = saturatef(bsdf->alpha_x);
|
||||
bsdf->alpha_y = bsdf->alpha_x;
|
||||
|
||||
bsdf->fresnel_type = MicrofacetFresnel::DIELECTRIC;
|
||||
bsdf->energy_scale = 1.0f;
|
||||
bsdf->type = CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID;
|
||||
bsdf->sample_weight *= average(bsdf_microfacet_estimate_albedo(kg, sd, bsdf, true, true));
|
||||
|
||||
return SD_BSDF | bsdf_microfacet_eval_flag(bsdf);
|
||||
}
|
||||
|
||||
ccl_device int bsdf_microfacet_ggx_refraction_setup(ccl_private MicrofacetBsdf *bsdf)
|
||||
{
|
||||
bsdf->alpha_x = saturatef(bsdf->alpha_x);
|
||||
|
|
|
@ -420,10 +420,6 @@ ccl_device void osl_closure_microfacet_setup(KernelGlobals kg,
|
|||
else if (closure->distribution == make_string("ashikhmin_shirley", 11318482998918370922ull)) {
|
||||
sd->flag |= bsdf_ashikhmin_shirley_setup(bsdf);
|
||||
}
|
||||
/* Clearcoat */
|
||||
else if (closure->distribution == make_string("clearcoat", 3490136178980547276ull)) {
|
||||
sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(kg, bsdf, sd);
|
||||
}
|
||||
/* GGX (either single- or multi-scattering) */
|
||||
else {
|
||||
if (closure->refract == 1) {
|
||||
|
|
|
@ -140,7 +140,7 @@ ccl_device void flatten_closure_tree(KernelGlobals kg,
|
|||
if (stack_size == layer_stack_level) {
|
||||
/* We just finished processing the top layers of a Layer closure, so adjust the weight to
|
||||
* account for the layering. */
|
||||
weight *= saturatef(1.0f - reduce_max(layer_albedo / weight));
|
||||
weight *= saturatef(1.0f - reduce_max(safe_divide_color(layer_albedo, weight)));
|
||||
layer_stack_level = -1;
|
||||
if (is_zero(weight)) {
|
||||
/* If it's fully occluded, skip the base layer we just popped from the stack and grab
|
||||
|
|
|
@ -22,12 +22,14 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
|
|||
float Sheen = 0.0,
|
||||
float SheenRoughness = 0.5,
|
||||
color SheenTint = 0.5,
|
||||
float Clearcoat = 0.0,
|
||||
float ClearcoatRoughness = 0.03,
|
||||
float Coat = 0.0,
|
||||
float CoatRoughness = 0.03,
|
||||
float CoatIOR = 1.5,
|
||||
color CoatTint = color(1.0, 1.0, 1.0),
|
||||
float IOR = 1.45,
|
||||
float Transmission = 0.0,
|
||||
normal Normal = N,
|
||||
normal ClearcoatNormal = N,
|
||||
normal CoatNormal = N,
|
||||
normal Tangent = normalize(dPdu),
|
||||
output closure color BSDF = 0)
|
||||
{
|
||||
|
@ -97,10 +99,18 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
|
|||
BSDF = mix(BSDF, MetallicBSDF, clamp(Metallic, 0.0, 1.0));
|
||||
}
|
||||
|
||||
if (Clearcoat > 1e-5) {
|
||||
float clearcoat_r2 = ClearcoatRoughness * ClearcoatRoughness;
|
||||
closure color ClearcoatBSDF = microfacet("clearcoat", ClearcoatNormal, clearcoat_r2, 1.5, 0);
|
||||
BSDF = layer(0.25 * Clearcoat * ClearcoatBSDF, BSDF);
|
||||
if (Coat > 1e-5) {
|
||||
float coat_ior = max(CoatIOR, 1.0);
|
||||
if (CoatTint != color(1.0)) {
|
||||
float coat_neta = 1.0 / coat_ior;
|
||||
float cosNI = dot(I, CoatNormal);
|
||||
float cosNT = sqrt(1.0 - coat_neta * coat_neta * (1 - cosNI * cosNI));
|
||||
BSDF *= pow(CoatTint, Coat / cosNT);
|
||||
}
|
||||
float coat_r2 = CoatRoughness * CoatRoughness;
|
||||
closure color CoatBSDF = dielectric_bsdf(
|
||||
CoatNormal, vector(0.0), color(1.0), color(0.0), coat_r2, coat_r2, coat_ior, "ggx");
|
||||
LukasStockner marked this conversation as resolved
Outdated
|
||||
BSDF = layer(Coat * CoatBSDF, BSDF);
|
||||
}
|
||||
|
||||
if (Sheen > 1e-5) {
|
||||
|
|
|
@ -69,8 +69,9 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
switch (type) {
|
||||
case CLOSURE_BSDF_PRINCIPLED_ID: {
|
||||
uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset,
|
||||
sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset,
|
||||
eta_offset, transmission_offset, anisotropic_rotation_offset, pad1;
|
||||
sheen_offset, sheen_tint_offset, sheen_roughness_offset, coat_offset,
|
||||
coat_roughness_offset, coat_ior_offset, eta_offset, transmission_offset,
|
||||
anisotropic_rotation_offset, coat_tint_offset, dummy;
|
||||
uint4 data_node2 = read_node(kg, &offset);
|
||||
|
||||
float3 T = stack_load_float3(stack, data_node.y);
|
||||
|
@ -79,13 +80,12 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
&roughness_offset,
|
||||
&specular_tint_offset,
|
||||
&anisotropic_offset);
|
||||
svm_unpack_node_uchar4(data_node.w,
|
||||
&sheen_offset,
|
||||
&sheen_tint_offset,
|
||||
&clearcoat_offset,
|
||||
&clearcoat_roughness_offset);
|
||||
svm_unpack_node_uchar4(
|
||||
data_node2.x, &eta_offset, &transmission_offset, &anisotropic_rotation_offset, &pad1);
|
||||
data_node.w, &sheen_offset, &sheen_tint_offset, &sheen_roughness_offset, &dummy);
|
||||
svm_unpack_node_uchar4(
|
||||
data_node2.x, &eta_offset, &transmission_offset, &anisotropic_rotation_offset, &dummy);
|
||||
svm_unpack_node_uchar4(
|
||||
data_node2.w, &coat_offset, &coat_roughness_offset, &coat_ior_offset, &coat_tint_offset);
|
||||
|
||||
// get Disney principled parameters
|
||||
float metallic = saturatef(param1);
|
||||
|
@ -96,9 +96,11 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
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);
|
||||
float sheen_roughness = stack_load_float(stack, data_node2.w);
|
||||
float clearcoat = stack_load_float(stack, clearcoat_offset);
|
||||
float clearcoat_roughness = stack_load_float(stack, clearcoat_roughness_offset);
|
||||
float sheen_roughness = stack_load_float(stack, sheen_roughness_offset);
|
||||
float coat = stack_load_float(stack, coat_offset);
|
||||
float coat_roughness = stack_load_float(stack, coat_roughness_offset);
|
||||
float coat_ior = fmaxf(stack_load_float(stack, coat_ior_offset), 1.0f);
|
||||
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);
|
||||
|
@ -116,12 +118,11 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
__uint_as_float(data_base_color.z),
|
||||
__uint_as_float(data_base_color.w));
|
||||
|
||||
// get the additional clearcoat normal and subsurface scattering radius
|
||||
// get the additional coat normal and subsurface scattering radius
|
||||
uint4 data_cn_ssr = read_node(kg, &offset);
|
||||
float3 clearcoat_normal = stack_valid(data_cn_ssr.x) ?
|
||||
stack_load_float3(stack, data_cn_ssr.x) :
|
||||
sd->N;
|
||||
clearcoat_normal = maybe_ensure_valid_specular_reflection(sd, clearcoat_normal);
|
||||
float3 coat_normal = stack_valid(data_cn_ssr.x) ? stack_load_float3(stack, data_cn_ssr.x) :
|
||||
sd->N;
|
||||
coat_normal = maybe_ensure_valid_specular_reflection(sd, coat_normal);
|
||||
float3 subsurface_radius = stack_valid(data_cn_ssr.y) ?
|
||||
stack_load_float3(stack, data_cn_ssr.y) :
|
||||
one_float3();
|
||||
|
@ -175,31 +176,58 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
|
||||
/* Attenuate lower layers */
|
||||
Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
weight *= 1.0f - reduce_max(albedo / weight);
|
||||
weight *= 1.0f - reduce_max(safe_divide_color(albedo, weight));
|
||||
}
|
||||
}
|
||||
|
||||
/* Second layer: Clearcoat */
|
||||
if (reflective_caustics && clearcoat > CLOSURE_WEIGHT_CUTOFF) {
|
||||
/* Second layer: Coat */
|
||||
if (reflective_caustics && coat > CLOSURE_WEIGHT_CUTOFF) {
|
||||
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
|
||||
sd, sizeof(MicrofacetBsdf), 0.25f * clearcoat * weight);
|
||||
sd, sizeof(MicrofacetBsdf), coat * weight);
|
||||
|
||||
if (bsdf) {
|
||||
bsdf->N = clearcoat_normal;
|
||||
bsdf->N = coat_normal;
|
||||
bsdf->T = zero_float3();
|
||||
bsdf->ior = 1.5f;
|
||||
bsdf->ior = coat_ior;
|
||||
|
||||
bsdf->alpha_x = bsdf->alpha_y = sqr(clearcoat_roughness);
|
||||
bsdf->alpha_x = bsdf->alpha_y = sqr(coat_roughness);
|
||||
|
||||
/* setup bsdf */
|
||||
sd->flag |= bsdf_microfacet_ggx_clearcoat_setup(kg, bsdf, sd);
|
||||
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
|
||||
bsdf_microfacet_setup_fresnel_dielectric(kg, bsdf, sd);
|
||||
|
||||
/* Attenuate lower layers */
|
||||
Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
weight *= 1.0f - reduce_max(albedo / weight);
|
||||
weight *= 1.0f - reduce_max(safe_divide_color(albedo, weight));
|
||||
}
|
||||
}
|
||||
|
||||
Alaska marked this conversation as resolved
Outdated
Alaska
commented
Replacing For reference, the compilation issue is this:
Replacing `if (coat_tint != one_float3())` with `if (!isequal(coat_tint, one_float3()))` fixes compilation issues with the Metal backend.
For reference, the compilation issue is this:
```
error: value of type 'bool __attribute__((ext_vector_type(3)))' (vector of 3 'bool' values) is not contextually convertible to 'bool'
if (coat_tint != one_float3()) {
^~~~~~~~~~~~~~~~~~~~~~~~~
```
|
||||
if (coat > CLOSURE_WEIGHT_CUTOFF && !isequal(coat_tint, one_float3())) {
|
||||
/* Tint is normalized to perpendicular incidence.
|
||||
* Therefore, if we define the coat thickness as length 1, the length along the ray is
|
||||
* t = sqrt(1+tan^2(angle(N, I))) = sqrt(1+tan^2(acos(dotNI))) = 1 / dotNI.
|
||||
* From Beer's law, we have T = exp(-sigma_e * t).
|
||||
* Therefore, tint = exp(-sigma_e * 1) (per def.), so -sigma_e = log(tint).
|
||||
* From this, T = exp(log(tint) * t) = exp(log(tint)) ^ t = tint ^ t;
|
||||
*
|
||||
* Note that this is only an approximation - it assumes that the outgoing ray
|
||||
* follows the same angle, and that there aren't multiple internal bounces.
|
||||
* In particular, things that could be improved:
|
||||
* - For transmissive materials, there should not be an outgoing path at all if the path
|
||||
* is transmitted.
|
||||
* - For rough materials, we could blend towards a view-independent average path length
|
||||
* (e.g. 2 for diffuse reflection) for the outgoing direction.
|
||||
* However, there's also an argument to be made for keeping parameters independent of each
|
||||
* other for more intuitive control, in particular main roughness not affecting the coat.
|
||||
*/
|
||||
float cosNI = dot(sd->wi, coat_normal);
|
||||
/* Refract incoming direction into coat material.
|
||||
* TIR is no concern here since we're always coming from the outside. */
|
||||
float cosNT = sqrtf(1.0f - sqr(1.0f / coat_ior) * (1 - sqr(cosNI)));
|
||||
float optical_depth = 1.0f / cosNT;
|
||||
weight *= power(rgb_to_spectrum(coat_tint), coat * optical_depth);
|
||||
}
|
||||
|
||||
/* Metallic component */
|
||||
if (reflective_caustics && metallic > CLOSURE_WEIGHT_CUTOFF) {
|
||||
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
|
||||
|
@ -295,7 +323,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
|
||||
/* Attenuate lower layers */
|
||||
Spectrum albedo = bsdf_albedo(kg, sd, (ccl_private ShaderClosure *)bsdf, true, false);
|
||||
weight *= 1.0f - reduce_max(albedo / weight);
|
||||
weight *= 1.0f - reduce_max(safe_divide_color(albedo, weight));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -427,7 +427,6 @@ typedef enum ClosureType {
|
|||
|
||||
/* Glossy */
|
||||
CLOSURE_BSDF_MICROFACET_GGX_ID,
|
||||
CLOSURE_BSDF_MICROFACET_GGX_CLEARCOAT_ID,
|
||||
CLOSURE_BSDF_MICROFACET_BECKMANN_ID,
|
||||
CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID, /* virtual closure */
|
||||
CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID,
|
||||
|
|
|
@ -2674,8 +2674,10 @@ NODE_DEFINE(PrincipledBsdfNode)
|
|||
SOCKET_IN_FLOAT(sheen, "Sheen", 0.0f);
|
||||
SOCKET_IN_FLOAT(sheen_roughness, "Sheen Roughness", 0.5f);
|
||||
SOCKET_IN_COLOR(sheen_tint, "Sheen Tint", one_float3());
|
||||
SOCKET_IN_FLOAT(clearcoat, "Clearcoat", 0.0f);
|
||||
SOCKET_IN_FLOAT(clearcoat_roughness, "Clearcoat Roughness", 0.03f);
|
||||
SOCKET_IN_FLOAT(coat, "Coat", 0.0f);
|
||||
SOCKET_IN_FLOAT(coat_roughness, "Coat Roughness", 0.03f);
|
||||
SOCKET_IN_FLOAT(coat_ior, "Coat IOR", 1.5f);
|
||||
SOCKET_IN_COLOR(coat_tint, "Coat Tint", one_float3());
|
||||
SOCKET_IN_FLOAT(ior, "IOR", 0.0f);
|
||||
SOCKET_IN_FLOAT(transmission, "Transmission", 0.0f);
|
||||
SOCKET_IN_FLOAT(anisotropic_rotation, "Anisotropic Rotation", 0.0f);
|
||||
|
@ -2683,7 +2685,7 @@ NODE_DEFINE(PrincipledBsdfNode)
|
|||
SOCKET_IN_FLOAT(emission_strength, "Emission Strength", 1.0f);
|
||||
SOCKET_IN_FLOAT(alpha, "Alpha", 1.0f);
|
||||
SOCKET_IN_NORMAL(normal, "Normal", zero_float3(), SocketType::LINK_NORMAL);
|
||||
SOCKET_IN_NORMAL(clearcoat_normal, "Clearcoat Normal", zero_float3(), SocketType::LINK_NORMAL);
|
||||
SOCKET_IN_NORMAL(coat_normal, "Coat Normal", zero_float3(), SocketType::LINK_NORMAL);
|
||||
SOCKET_IN_NORMAL(tangent, "Tangent", zero_float3(), SocketType::LINK_TANGENT);
|
||||
SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
|
||||
|
||||
|
@ -2785,8 +2787,10 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler,
|
|||
ShaderInput *p_sheen,
|
||||
ShaderInput *p_sheen_roughness,
|
||||
ShaderInput *p_sheen_tint,
|
||||
ShaderInput *p_clearcoat,
|
||||
ShaderInput *p_clearcoat_roughness,
|
||||
ShaderInput *p_coat,
|
||||
ShaderInput *p_coat_roughness,
|
||||
ShaderInput *p_coat_ior,
|
||||
ShaderInput *p_coat_tint,
|
||||
ShaderInput *p_ior,
|
||||
ShaderInput *p_transmission,
|
||||
ShaderInput *p_anisotropic_rotation)
|
||||
|
@ -2794,7 +2798,7 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler,
|
|||
ShaderInput *base_color_in = input("Base Color");
|
||||
ShaderInput *subsurface_color_in = input("Subsurface Color");
|
||||
ShaderInput *normal_in = input("Normal");
|
||||
ShaderInput *clearcoat_normal_in = input("Clearcoat Normal");
|
||||
ShaderInput *coat_normal_in = input("Coat Normal");
|
||||
ShaderInput *tangent_in = input("Tangent");
|
||||
|
||||
float3 weight = one_float3();
|
||||
|
@ -2802,7 +2806,7 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler,
|
|||
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, weight);
|
||||
|
||||
int normal_offset = compiler.stack_assign_if_linked(normal_in);
|
||||
int clearcoat_normal_offset = compiler.stack_assign_if_linked(clearcoat_normal_in);
|
||||
int coat_normal_offset = compiler.stack_assign_if_linked(coat_normal_in);
|
||||
int tangent_offset = compiler.stack_assign_if_linked(tangent_in);
|
||||
int specular_offset = compiler.stack_assign(p_specular);
|
||||
int roughness_offset = compiler.stack_assign(p_roughness);
|
||||
|
@ -2811,8 +2815,10 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler,
|
|||
int sheen_offset = compiler.stack_assign(p_sheen);
|
||||
int sheen_roughness_offset = compiler.stack_assign(p_sheen_roughness);
|
||||
int sheen_tint_offset = compiler.stack_assign(p_sheen_tint);
|
||||
int clearcoat_offset = compiler.stack_assign(p_clearcoat);
|
||||
int clearcoat_roughness_offset = compiler.stack_assign(p_clearcoat_roughness);
|
||||
int coat_offset = compiler.stack_assign(p_coat);
|
||||
int coat_roughness_offset = compiler.stack_assign(p_coat_roughness);
|
||||
int coat_ior_offset = compiler.stack_assign(p_coat_ior);
|
||||
int coat_tint_offset = compiler.stack_assign(p_coat_tint);
|
||||
int ior_offset = compiler.stack_assign(p_ior);
|
||||
int transmission_offset = compiler.stack_assign(p_transmission);
|
||||
int anisotropic_rotation_offset = compiler.stack_assign(p_anisotropic_rotation);
|
||||
|
@ -2834,14 +2840,15 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler,
|
|||
compiler.encode_uchar4(
|
||||
specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset),
|
||||
compiler.encode_uchar4(
|
||||
sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset));
|
||||
sheen_offset, sheen_tint_offset, sheen_roughness_offset, SVM_STACK_INVALID));
|
||||
|
||||
compiler.add_node(
|
||||
compiler.encode_uchar4(
|
||||
ior_offset, transmission_offset, anisotropic_rotation_offset, SVM_STACK_INVALID),
|
||||
distribution,
|
||||
subsurface_method,
|
||||
sheen_roughness_offset);
|
||||
compiler.encode_uchar4(
|
||||
coat_offset, coat_roughness_offset, coat_ior_offset, coat_tint_offset));
|
||||
|
||||
float3 bc_default = get_float3(base_color_in->socket_type);
|
||||
|
||||
|
@ -2851,7 +2858,7 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler,
|
|||
__float_as_int(bc_default.y),
|
||||
__float_as_int(bc_default.z));
|
||||
|
||||
compiler.add_node(clearcoat_normal_offset,
|
||||
compiler.add_node(coat_normal_offset,
|
||||
subsurface_radius_offset,
|
||||
subsurface_ior_offset,
|
||||
subsurface_anisotropy_offset);
|
||||
|
@ -2880,8 +2887,10 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler)
|
|||
input("Sheen"),
|
||||
input("Sheen Roughness"),
|
||||
input("Sheen Tint"),
|
||||
input("Clearcoat"),
|
||||
input("Clearcoat Roughness"),
|
||||
input("Coat"),
|
||||
input("Coat Roughness"),
|
||||
input("Coat IOR"),
|
||||
input("Coat Tint"),
|
||||
input("IOR"),
|
||||
input("Transmission"),
|
||||
input("Anisotropic Rotation"));
|
||||
|
|
|
@ -530,8 +530,10 @@ class PrincipledBsdfNode : public BsdfBaseNode {
|
|||
ShaderInput *sheen,
|
||||
ShaderInput *sheen_roughness,
|
||||
ShaderInput *sheen_tint,
|
||||
ShaderInput *clearcoat,
|
||||
ShaderInput *clearcoat_roughness,
|
||||
ShaderInput *coat,
|
||||
ShaderInput *coat_roughness,
|
||||
ShaderInput *coat_ior,
|
||||
ShaderInput *coat_tint,
|
||||
ShaderInput *ior,
|
||||
ShaderInput *transmission,
|
||||
ShaderInput *anisotropic_rotation);
|
||||
|
@ -550,13 +552,15 @@ class PrincipledBsdfNode : public BsdfBaseNode {
|
|||
NODE_SOCKET_API(float, sheen)
|
||||
NODE_SOCKET_API(float, sheen_roughness)
|
||||
NODE_SOCKET_API(float3, sheen_tint)
|
||||
NODE_SOCKET_API(float, clearcoat)
|
||||
NODE_SOCKET_API(float, clearcoat_roughness)
|
||||
NODE_SOCKET_API(float, coat)
|
||||
NODE_SOCKET_API(float, coat_roughness)
|
||||
NODE_SOCKET_API(float, coat_ior)
|
||||
NODE_SOCKET_API(float3, coat_tint)
|
||||
NODE_SOCKET_API(float, ior)
|
||||
NODE_SOCKET_API(float, transmission)
|
||||
NODE_SOCKET_API(float, anisotropic_rotation)
|
||||
NODE_SOCKET_API(float3, normal)
|
||||
NODE_SOCKET_API(float3, clearcoat_normal)
|
||||
NODE_SOCKET_API(float3, coat_normal)
|
||||
NODE_SOCKET_API(float3, tangent)
|
||||
NODE_SOCKET_API(float, surface_mix_weight)
|
||||
NODE_SOCKET_API(ClosureType, distribution)
|
||||
|
|
|
@ -655,6 +655,35 @@ static void versioning_convert_node_tree_socket_lists_to_interface(bNodeTree *nt
|
|||
}
|
||||
}
|
||||
|
||||
/* Convert coat inputs on the Principled BSDF. */
|
||||
static void version_principled_bsdf_coat(bNodeTree *ntree)
|
||||
{
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
if (node->type != SH_NODE_BSDF_PRINCIPLED) {
|
||||
continue;
|
||||
}
|
||||
if (nodeFindSocket(node, SOCK_IN, "Coat IOR") != nullptr) {
|
||||
continue;
|
||||
}
|
||||
bNodeSocket *coat_ior_input = nodeAddStaticSocket(
|
||||
ntree, node, SOCK_IN, SOCK_FLOAT, PROP_NONE, "Coat IOR", "Coat IOR");
|
||||
|
||||
/* Adjust for 4x change in intensity. */
|
||||
bNodeSocket *coat_input = nodeFindSocket(node, SOCK_IN, "Clearcoat");
|
||||
*version_cycles_node_socket_float_value(coat_input) *= 0.25f;
|
||||
/* When the coat input is dynamic, instead of inserting a *0.25 math node, set the Coat IOR
|
||||
* to 1.2 instead - this also roughly quarters reflectivity compared to the 1.5 default. */
|
||||
*version_cycles_node_socket_float_value(coat_ior_input) = (coat_input->link) ? 1.2f : 1.5f;
|
||||
}
|
||||
|
||||
/* Rename sockets. */
|
||||
version_node_input_socket_name(ntree, SH_NODE_BSDF_PRINCIPLED, "Clearcoat", "Coat");
|
||||
version_node_input_socket_name(
|
||||
ntree, SH_NODE_BSDF_PRINCIPLED, "Clearcoat Roughness", "Coat Roughness");
|
||||
version_node_input_socket_name(
|
||||
ntree, SH_NODE_BSDF_PRINCIPLED, "Clearcoat Normal", "Coat Normal");
|
||||
}
|
||||
|
||||
void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
{
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 1)) {
|
||||
|
@ -1062,5 +1091,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 coat inputs on the Principled BSDF. */
|
||||
version_principled_bsdf_coat(ntree);
|
||||
}
|
||||
}
|
||||
FOREACH_NODETREE_END;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -230,15 +230,13 @@ Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection)
|
|||
|
||||
/* Specular BSDF */
|
||||
CLOSURE_EVAL_FUNCTION_DECLARE_3(SpecularBSDF, Diffuse, Glossy, Glossy)
|
||||
Closure closure_eval(ClosureDiffuse diffuse,
|
||||
ClosureReflection reflection,
|
||||
ClosureReflection clearcoat)
|
||||
Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection, ClosureReflection coat)
|
||||
{
|
||||
#if defined(DO_SPLIT_CLOSURE_EVAL)
|
||||
Closure closure = closure_eval(diffuse);
|
||||
Closure closure_reflection = closure_eval(reflection);
|
||||
Closure closure_clearcoat = closure_eval(clearcoat, false);
|
||||
closure.radiance += closure_reflection.radiance + closure_clearcoat.radiance;
|
||||
Closure closure_coat = closure_eval(coat, false);
|
||||
closure.radiance += closure_reflection.radiance + closure_coat.radiance;
|
||||
return closure;
|
||||
#else
|
||||
/* Glue with the old system. */
|
||||
|
@ -250,8 +248,8 @@ Closure closure_eval(ClosureDiffuse diffuse,
|
|||
in_Diffuse_0.albedo = diffuse.color;
|
||||
in_Glossy_1.N = reflection.N;
|
||||
in_Glossy_1.roughness = reflection.roughness;
|
||||
in_Glossy_2.N = clearcoat.N;
|
||||
in_Glossy_2.roughness = clearcoat.roughness;
|
||||
in_Glossy_2.N = coat.N;
|
||||
in_Glossy_2.roughness = coat.roughness;
|
||||
|
||||
CLOSURE_EVAL_FUNCTION_3(SpecularBSDF, Diffuse, Glossy, Glossy);
|
||||
|
||||
|
@ -259,7 +257,7 @@ Closure closure_eval(ClosureDiffuse diffuse,
|
|||
if (!output_sss(diffuse, out_Diffuse_0)) {
|
||||
closure.radiance += out_Diffuse_0.radiance * diffuse.color * diffuse.weight;
|
||||
}
|
||||
closure.radiance += out_Glossy_2.radiance * clearcoat.color * clearcoat.weight;
|
||||
closure.radiance += out_Glossy_2.radiance * coat.color * coat.weight;
|
||||
if (!output_ssr(reflection)) {
|
||||
closure.radiance += out_Glossy_1.radiance * reflection.color * reflection.weight;
|
||||
}
|
||||
|
@ -271,15 +269,15 @@ Closure closure_eval(ClosureDiffuse diffuse,
|
|||
CLOSURE_EVAL_FUNCTION_DECLARE_4(PrincipledBSDF, Diffuse, Glossy, Glossy, Refraction)
|
||||
Closure closure_eval(ClosureDiffuse diffuse,
|
||||
ClosureReflection reflection,
|
||||
ClosureReflection clearcoat,
|
||||
ClosureReflection coat,
|
||||
ClosureRefraction refraction)
|
||||
{
|
||||
#if defined(DO_SPLIT_CLOSURE_EVAL)
|
||||
Closure closure = closure_eval(diffuse);
|
||||
Closure closure_reflection = closure_eval(reflection);
|
||||
Closure closure_clearcoat = closure_eval(clearcoat, false);
|
||||
Closure closure_coat = closure_eval(coat, false);
|
||||
Closure closure_refraction = closure_eval(refraction);
|
||||
closure.radiance += closure_reflection.radiance + closure_clearcoat.radiance +
|
||||
closure.radiance += closure_reflection.radiance + closure_coat.radiance +
|
||||
closure_refraction.radiance;
|
||||
return closure;
|
||||
#else
|
||||
|
@ -290,8 +288,8 @@ Closure closure_eval(ClosureDiffuse diffuse,
|
|||
in_Diffuse_0.albedo = diffuse.color;
|
||||
in_Glossy_1.N = reflection.N;
|
||||
in_Glossy_1.roughness = reflection.roughness;
|
||||
in_Glossy_2.N = clearcoat.N;
|
||||
in_Glossy_2.roughness = clearcoat.roughness;
|
||||
in_Glossy_2.N = coat.N;
|
||||
in_Glossy_2.roughness = coat.roughness;
|
||||
in_Refraction_3.N = refraction.N;
|
||||
in_Refraction_3.roughness = refraction.roughness;
|
||||
in_Refraction_3.ior = refraction.ior;
|
||||
|
@ -299,7 +297,7 @@ Closure closure_eval(ClosureDiffuse diffuse,
|
|||
CLOSURE_EVAL_FUNCTION_4(PrincipledBSDF, Diffuse, Glossy, Glossy, Refraction);
|
||||
|
||||
Closure closure = CLOSURE_DEFAULT;
|
||||
closure.radiance += out_Glossy_2.radiance * clearcoat.color * clearcoat.weight;
|
||||
closure.radiance += out_Glossy_2.radiance * coat.color * coat.weight;
|
||||
closure.radiance += out_Refraction_3.radiance * refraction.color * refraction.weight;
|
||||
if (!output_sss(diffuse, out_Diffuse_0)) {
|
||||
closure.radiance += out_Diffuse_0.radiance * diffuse.color * diffuse.weight;
|
||||
|
@ -312,10 +310,10 @@ Closure closure_eval(ClosureDiffuse diffuse,
|
|||
}
|
||||
|
||||
CLOSURE_EVAL_FUNCTION_DECLARE_2(PrincipledBSDFMetalClearCoat, Glossy, Glossy)
|
||||
Closure closure_eval(ClosureReflection reflection, ClosureReflection clearcoat)
|
||||
Closure closure_eval(ClosureReflection reflection, ClosureReflection coat)
|
||||
{
|
||||
#if defined(DO_SPLIT_CLOSURE_EVAL)
|
||||
Closure closure = closure_eval(clearcoat);
|
||||
Closure closure = closure_eval(coat);
|
||||
Closure closure_reflection = closure_eval(reflection);
|
||||
closure.radiance += closure_reflection.radiance;
|
||||
return closure;
|
||||
|
@ -325,13 +323,13 @@ Closure closure_eval(ClosureReflection reflection, ClosureReflection clearcoat)
|
|||
|
||||
in_Glossy_0.N = reflection.N;
|
||||
in_Glossy_0.roughness = reflection.roughness;
|
||||
in_Glossy_1.N = clearcoat.N;
|
||||
in_Glossy_1.roughness = clearcoat.roughness;
|
||||
in_Glossy_1.N = coat.N;
|
||||
in_Glossy_1.roughness = coat.roughness;
|
||||
|
||||
CLOSURE_EVAL_FUNCTION_2(PrincipledBSDFMetalClearCoat, Glossy, Glossy);
|
||||
|
||||
Closure closure = CLOSURE_DEFAULT;
|
||||
closure.radiance += out_Glossy_1.radiance * clearcoat.color * clearcoat.weight;
|
||||
closure.radiance += out_Glossy_1.radiance * coat.color * coat.weight;
|
||||
if (!output_ssr(reflection)) {
|
||||
closure.radiance += out_Glossy_0.radiance * reflection.color * reflection.weight;
|
||||
}
|
||||
|
|
|
@ -42,20 +42,18 @@ Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection)
|
|||
{
|
||||
return CLOSURE_DEFAULT;
|
||||
}
|
||||
Closure closure_eval(ClosureDiffuse diffuse,
|
||||
ClosureReflection reflection,
|
||||
ClosureReflection clearcoat)
|
||||
Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection, ClosureReflection coat)
|
||||
{
|
||||
return CLOSURE_DEFAULT;
|
||||
}
|
||||
Closure closure_eval(ClosureDiffuse diffuse,
|
||||
ClosureReflection reflection,
|
||||
ClosureReflection clearcoat,
|
||||
ClosureReflection coat,
|
||||
ClosureRefraction refraction)
|
||||
{
|
||||
return CLOSURE_DEFAULT;
|
||||
}
|
||||
Closure closure_eval(ClosureReflection reflection, ClosureReflection clearcoat)
|
||||
Closure closure_eval(ClosureReflection reflection, ClosureReflection coat)
|
||||
{
|
||||
return CLOSURE_DEFAULT;
|
||||
}
|
||||
|
|
|
@ -67,20 +67,18 @@ Closure closure_eval(ClosureHair hair);
|
|||
Closure closure_eval(ClosureReflection reflection, ClosureRefraction refraction);
|
||||
/* Dielectric BSDF. */
|
||||
Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection);
|
||||
/* ClearCoat BSDF. */
|
||||
Closure closure_eval(ClosureReflection reflection, ClosureReflection clearcoat);
|
||||
/* Coat BSDF. */
|
||||
Closure closure_eval(ClosureReflection reflection, ClosureReflection coat);
|
||||
/* Volume BSDF. */
|
||||
Closure closure_eval(ClosureVolumeScatter volume_scatter,
|
||||
ClosureVolumeAbsorption volume_absorption,
|
||||
ClosureEmission emission);
|
||||
/* Specular BSDF. */
|
||||
Closure closure_eval(ClosureDiffuse diffuse,
|
||||
ClosureReflection reflection,
|
||||
ClosureReflection clearcoat);
|
||||
Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection, ClosureReflection coat);
|
||||
/* Principled BSDF. */
|
||||
Closure closure_eval(ClosureDiffuse diffuse,
|
||||
ClosureReflection reflection,
|
||||
ClosureReflection clearcoat,
|
||||
ClosureReflection coat,
|
||||
ClosureRefraction refraction);
|
||||
|
||||
Closure closure_add(inout Closure cl1, inout Closure cl2);
|
||||
|
|
|
@ -166,11 +166,11 @@ Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection)
|
|||
return Closure(0);
|
||||
}
|
||||
|
||||
/* ClearCoat BSDF. */
|
||||
Closure closure_eval(ClosureReflection reflection, ClosureReflection clearcoat)
|
||||
/* Coat BSDF. */
|
||||
Closure closure_eval(ClosureReflection reflection, ClosureReflection coat)
|
||||
{
|
||||
SELECT_CLOSURE(g_reflection_data, g_reflection_rand, reflection);
|
||||
SELECT_CLOSURE(g_reflection_data, g_reflection_rand, clearcoat);
|
||||
SELECT_CLOSURE(g_reflection_data, g_reflection_rand, coat);
|
||||
return Closure(0);
|
||||
}
|
||||
|
||||
|
@ -186,25 +186,23 @@ Closure closure_eval(ClosureVolumeScatter volume_scatter,
|
|||
}
|
||||
|
||||
/* Specular BSDF. */
|
||||
Closure closure_eval(ClosureDiffuse diffuse,
|
||||
ClosureReflection reflection,
|
||||
ClosureReflection clearcoat)
|
||||
Closure closure_eval(ClosureDiffuse diffuse, ClosureReflection reflection, ClosureReflection coat)
|
||||
{
|
||||
SELECT_CLOSURE(g_diffuse_data, g_diffuse_rand, diffuse);
|
||||
SELECT_CLOSURE(g_reflection_data, g_reflection_rand, reflection);
|
||||
SELECT_CLOSURE(g_reflection_data, g_reflection_rand, clearcoat);
|
||||
SELECT_CLOSURE(g_reflection_data, g_reflection_rand, coat);
|
||||
return Closure(0);
|
||||
}
|
||||
|
||||
/* Principled BSDF. */
|
||||
Closure closure_eval(ClosureDiffuse diffuse,
|
||||
ClosureReflection reflection,
|
||||
ClosureReflection clearcoat,
|
||||
ClosureReflection coat,
|
||||
ClosureRefraction refraction)
|
||||
{
|
||||
SELECT_CLOSURE(g_diffuse_data, g_diffuse_rand, diffuse);
|
||||
SELECT_CLOSURE(g_reflection_data, g_reflection_rand, reflection);
|
||||
SELECT_CLOSURE(g_reflection_data, g_reflection_rand, clearcoat);
|
||||
SELECT_CLOSURE(g_reflection_data, g_reflection_rand, coat);
|
||||
SELECT_CLOSURE(g_refraction_data, g_refraction_rand, refraction);
|
||||
return Closure(0);
|
||||
}
|
||||
|
|
|
@ -334,7 +334,7 @@ void WM_OT_obj_export(wmOperatorType *ot)
|
|||
false,
|
||||
"Export Materials with PBR Extensions",
|
||||
"Export MTL library using PBR extensions (roughness, metallic, sheen, "
|
||||
"clearcoat, anisotropy, transmission)");
|
||||
"coat, anisotropy, transmission)");
|
||||
RNA_def_enum(ot->srna,
|
||||
"path_mode",
|
||||
io_obj_path_mode,
|
||||
|
|
|
@ -78,7 +78,7 @@ typedef enum eGPUMaterialFlag {
|
|||
GPU_MATFLAG_HOLDOUT = (1 << 6),
|
||||
GPU_MATFLAG_SHADER_TO_RGBA = (1 << 7),
|
||||
GPU_MATFLAG_AO = (1 << 8),
|
||||
GPU_MATFLAG_CLEARCOAT = (1 << 9),
|
||||
GPU_MATFLAG_COAT = (1 << 9),
|
||||
|
||||
GPU_MATFLAG_OBJECT_INFO = (1 << 10),
|
||||
GPU_MATFLAG_AOV = (1 << 11),
|
||||
|
@ -86,7 +86,7 @@ typedef enum eGPUMaterialFlag {
|
|||
GPU_MATFLAG_BARYCENTRIC = (1 << 20),
|
||||
|
||||
/* Optimization to only add the branches of the principled shader that are necessary. */
|
||||
GPU_MATFLAG_PRINCIPLED_CLEARCOAT = (1 << 21),
|
||||
GPU_MATFLAG_PRINCIPLED_COAT = (1 << 21),
|
||||
GPU_MATFLAG_PRINCIPLED_METALLIC = (1 << 22),
|
||||
GPU_MATFLAG_PRINCIPLED_DIELECTRIC = (1 << 23),
|
||||
GPU_MATFLAG_PRINCIPLED_GLASS = (1 << 24),
|
||||
|
|
|
@ -404,8 +404,8 @@ void GPUCodegen::generate_resources()
|
|||
|
||||
/* Ref. #98190: Defines are optimizations for old compilers.
|
||||
* Might become unnecessary with EEVEE-Next. */
|
||||
if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_CLEARCOAT)) {
|
||||
info.define("PRINCIPLED_CLEARCOAT");
|
||||
if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_COAT)) {
|
||||
info.define("PRINCIPLED_COAT");
|
||||
}
|
||||
if (GPU_material_flag_get(&mat, GPU_MATFLAG_PRINCIPLED_METALLIC)) {
|
||||
info.define("PRINCIPLED_METALLIC");
|
||||
|
|
|
@ -33,8 +33,10 @@ void node_bsdf_principled(vec4 base_color,
|
|||
float sheen,
|
||||
float sheen_roughness,
|
||||
vec4 sheen_tint,
|
||||
float clearcoat,
|
||||
float clearcoat_roughness,
|
||||
float coat,
|
||||
float coat_roughness,
|
||||
float coat_ior,
|
||||
vec4 coat_tint,
|
||||
float ior,
|
||||
float transmission,
|
||||
vec4 emission,
|
||||
|
@ -45,7 +47,7 @@ void node_bsdf_principled(vec4 base_color,
|
|||
vec3 T,
|
||||
float weight,
|
||||
const float do_diffuse,
|
||||
const float do_clearcoat,
|
||||
const float do_coat,
|
||||
const float do_refraction,
|
||||
const float do_multiscatter,
|
||||
float do_sss,
|
||||
|
@ -54,7 +56,8 @@ void node_bsdf_principled(vec4 base_color,
|
|||
/* Match cycles. */
|
||||
metallic = clamp(metallic, 0.0, 1.0);
|
||||
transmission = clamp(transmission, 0.0, 1.0);
|
||||
clearcoat = max(clearcoat, 0.0) * 0.25;
|
||||
coat = max(coat, 0.0);
|
||||
coat_ior = max(coat_ior, 1.0);
|
||||
|
||||
N = safe_normalize(N);
|
||||
CN = safe_normalize(CN);
|
||||
|
@ -76,22 +79,31 @@ void node_bsdf_principled(vec4 base_color,
|
|||
/* Attenuate lower layers */
|
||||
weight *= (1.0 - max_v3(sheen_color));
|
||||
|
||||
/* Second layer: Clearcoat */
|
||||
ClosureReflection clearcoat_data;
|
||||
clearcoat_data.N = CN;
|
||||
clearcoat_data.roughness = clearcoat_roughness;
|
||||
float coat_ior = 1.5;
|
||||
float coat_NV = dot(clearcoat_data.N, V);
|
||||
float reflectance = btdf_lut(coat_NV, clearcoat_data.roughness, coat_ior, 0.0).y;
|
||||
clearcoat_data.weight = weight * clearcoat * reflectance;
|
||||
clearcoat_data.color = vec3(1.0);
|
||||
/* Second layer: Coat */
|
||||
ClosureReflection coat_data;
|
||||
coat_data.N = CN;
|
||||
coat_data.roughness = coat_roughness;
|
||||
float coat_NV = dot(coat_data.N, V);
|
||||
float reflectance = btdf_lut(coat_NV, coat_data.roughness, coat_ior, 0.0).y;
|
||||
coat_data.weight = weight * coat * reflectance;
|
||||
coat_data.color = vec3(1.0);
|
||||
/* Attenuate lower layers */
|
||||
weight *= (1.0 - reflectance * clearcoat);
|
||||
weight *= (1.0 - reflectance * coat);
|
||||
|
||||
/* Attenuated by sheen and clearcoat. */
|
||||
if (coat == 0) {
|
||||
coat_tint.rgb = vec3(1.0);
|
||||
}
|
||||
else if (!all(equal(coat_tint.rgb, vec3(1.0)))) {
|
||||
float coat_neta = 1.0 / coat_ior;
|
||||
float NT = fast_sqrt(1.0 - coat_neta * coat_neta * (1 - NV * NV));
|
||||
/* Tint lower layers. */
|
||||
coat_tint.rgb = pow(coat_tint.rgb, vec3(coat / NT));
|
||||
}
|
||||
|
||||
/* Attenuated by sheen and coat. */
|
||||
ClosureEmission emission_data;
|
||||
emission_data.weight = weight;
|
||||
emission_data.emission = emission.rgb * emission_strength;
|
||||
emission_data.emission = coat_tint.rgb * emission.rgb * emission_strength;
|
||||
|
||||
/* Metallic component */
|
||||
ClosureReflection reflection_data;
|
||||
|
@ -118,7 +130,7 @@ void node_bsdf_principled(vec4 base_color,
|
|||
reflection_data.color += weight * transmission * bsdf.y * reflection_tint;
|
||||
|
||||
refraction_data.weight = weight * transmission * bsdf.x;
|
||||
refraction_data.color = base_color.rgb;
|
||||
refraction_data.color = base_color.rgb * coat_tint.rgb;
|
||||
refraction_data.N = N;
|
||||
refraction_data.roughness = roughness;
|
||||
refraction_data.ior = ior;
|
||||
|
@ -146,36 +158,38 @@ void node_bsdf_principled(vec4 base_color,
|
|||
vec3 diffuse_color = mix(base_color.rgb, subsurface_color.rgb, subsurface);
|
||||
diffuse_data.sss_radius = subsurface_radius * subsurface;
|
||||
diffuse_data.sss_id = uint(do_sss);
|
||||
diffuse_data.color += weight * diffuse_color;
|
||||
diffuse_data.color += weight * diffuse_color * coat_tint.rgb;
|
||||
}
|
||||
|
||||
/* Adjust the weight of picking the closure. */
|
||||
reflection_data.color *= coat_tint.rgb;
|
||||
reflection_data.weight = avg(reflection_data.color);
|
||||
reflection_data.color *= safe_rcp(reflection_data.weight);
|
||||
|
||||
diffuse_data.weight = avg(diffuse_data.color);
|
||||
diffuse_data.color *= safe_rcp(diffuse_data.weight);
|
||||
|
||||
/* Ref. #98190: Defines are optimizations for old compilers.
|
||||
* Might become unnecessary with EEVEE-Next. */
|
||||
if (do_diffuse == 0.0 && do_refraction == 0.0 && do_clearcoat != 0.0) {
|
||||
#ifdef PRINCIPLED_CLEARCOAT
|
||||
/* Metallic & Clearcoat case. */
|
||||
result = closure_eval(reflection_data, clearcoat_data);
|
||||
if (do_diffuse == 0.0 && do_refraction == 0.0 && do_coat != 0.0) {
|
||||
#ifdef PRINCIPLED_COAT
|
||||
/* Metallic & Coat case. */
|
||||
result = closure_eval(reflection_data, coat_data);
|
||||
#endif
|
||||
}
|
||||
else if (do_diffuse == 0.0 && do_refraction == 0.0 && do_clearcoat == 0.0) {
|
||||
else if (do_diffuse == 0.0 && do_refraction == 0.0 && do_coat == 0.0) {
|
||||
#ifdef PRINCIPLED_METALLIC
|
||||
/* Metallic case. */
|
||||
result = closure_eval(reflection_data);
|
||||
#endif
|
||||
}
|
||||
else if (do_diffuse != 0.0 && do_refraction == 0.0 && do_clearcoat == 0.0) {
|
||||
else if (do_diffuse != 0.0 && do_refraction == 0.0 && do_coat == 0.0) {
|
||||
#ifdef PRINCIPLED_DIELECTRIC
|
||||
/* Dielectric case. */
|
||||
result = closure_eval(diffuse_data, reflection_data);
|
||||
#endif
|
||||
}
|
||||
else if (do_diffuse == 0.0 && do_refraction != 0.0 && do_clearcoat == 0.0) {
|
||||
else if (do_diffuse == 0.0 && do_refraction != 0.0 && do_coat == 0.0) {
|
||||
#ifdef PRINCIPLED_GLASS
|
||||
/* Glass case. */
|
||||
result = closure_eval(reflection_data, refraction_data);
|
||||
|
@ -184,7 +198,7 @@ void node_bsdf_principled(vec4 base_color,
|
|||
else {
|
||||
#ifdef PRINCIPLED_ANY
|
||||
/* Un-optimized case. */
|
||||
result = closure_eval(diffuse_data, reflection_data, clearcoat_data, refraction_data);
|
||||
result = closure_eval(diffuse_data, reflection_data, coat_data, refraction_data);
|
||||
#endif
|
||||
}
|
||||
Closure emission_cl = closure_eval(emission_data);
|
||||
|
|
|
@ -481,15 +481,12 @@ void USDMaterialReader::set_principled_node_inputs(bNode *principled,
|
|||
set_node_input(roughness_input, principled, "Roughness", ntree, column, &context);
|
||||
}
|
||||
|
||||
if (pxr::UsdShadeInput clearcoat_input = usd_shader.GetInput(usdtokens::clearcoat)) {
|
||||
Alaska
commented
I'm getting build errors here. Seems to be because you updated the names earlier in
I'm getting build errors here. Seems to be because you updated the names earlier in https://projects.blender.org/blender/blender/commit/96b362cac7fb039f5717d5eb28a556d5dc75f0fb but didn't update them here.
```
/blender/source/blender/io/usd/intern/usd_reader_material.cc:484:70: error: no member named 'coat' in namespace 'usdtokens'
if (pxr::UsdShadeInput coat_input = usd_shader.GetInput(usdtokens::coat)) {
~~~~~~~~~~~^
/blender/source/blender/io/usd/intern/usd_reader_material.cc:488:80: error: no member named 'coatRoughness' in namespace 'usdtokens'
if (pxr::UsdShadeInput coat_roughness_input = usd_shader.GetInput(usdtokens::coatRoughness)) {
~~~~~~~~~~~^~~~~~~~~~~~~
```
Lukas Stockner
commented
Ah, I was building with USD disabled. I'll fix it, thanks. Ah, I was building with USD disabled. I'll fix it, thanks.
|
||||
set_node_input(clearcoat_input, principled, "Clearcoat", ntree, column, &context);
|
||||
if (pxr::UsdShadeInput coat_input = usd_shader.GetInput(usdtokens::clearcoat)) {
|
||||
set_node_input(coat_input, principled, "Coat", ntree, column, &context);
|
||||
}
|
||||
|
||||
if (pxr::UsdShadeInput clearcoat_roughness_input = usd_shader.GetInput(
|
||||
usdtokens::clearcoatRoughness))
|
||||
{
|
||||
set_node_input(
|
||||
clearcoat_roughness_input, principled, "Clearcoat Roughness", ntree, column, &context);
|
||||
if (pxr::UsdShadeInput coat_roughness_input = usd_shader.GetInput(usdtokens::clearcoatRoughness)) {
|
||||
set_node_input(coat_roughness_input, principled, "Coat Roughness", ntree, column, &context);
|
||||
}
|
||||
|
||||
if (pxr::UsdShadeInput opacity_input = usd_shader.GetInput(usdtokens::opacity)) {
|
||||
|
|
|
@ -298,9 +298,8 @@ static InputSpecMap &preview_surface_input_map()
|
|||
{"IOR", {usdtokens::ior, pxr::SdfValueTypeNames->Float, true}},
|
||||
/* Note that for the Normal input set_default_value is false. */
|
||||
{"Normal", {usdtokens::normal, pxr::SdfValueTypeNames->Float3, false}},
|
||||
{"Clearcoat", {usdtokens::clearcoat, pxr::SdfValueTypeNames->Float, true}},
|
||||
{"Clearcoat Roughness",
|
||||
{usdtokens::clearcoatRoughness, pxr::SdfValueTypeNames->Float, true}},
|
||||
{"Coat", {usdtokens::clearcoat, pxr::SdfValueTypeNames->Float, true}},
|
||||
{"Coat Roughness", {usdtokens::clearcoatRoughness, pxr::SdfValueTypeNames->Float, true}},
|
||||
};
|
||||
|
||||
return input_map;
|
||||
|
|
|
@ -237,19 +237,21 @@ static void store_bsdf_properties(const bNode *bsdf_node,
|
|||
mul_v3_fl(emission_col, emission_strength);
|
||||
|
||||
float sheen = -1.0f;
|
||||
float clearcoat = -1.0f;
|
||||
float clearcoat_roughness = -1.0f;
|
||||
float coat = -1.0f;
|
||||
float coat_roughness = -1.0f;
|
||||
float aniso = -1.0f;
|
||||
float aniso_rot = -1.0f;
|
||||
float transmission = -1.0f;
|
||||
if (bsdf_node) {
|
||||
copy_property_from_node(SOCK_FLOAT, bsdf_node, "Sheen", {&sheen, 1});
|
||||
copy_property_from_node(SOCK_FLOAT, bsdf_node, "Clearcoat", {&clearcoat, 1});
|
||||
copy_property_from_node(
|
||||
SOCK_FLOAT, bsdf_node, "Clearcoat Roughness", {&clearcoat_roughness, 1});
|
||||
copy_property_from_node(SOCK_FLOAT, bsdf_node, "Coat", {&coat, 1});
|
||||
copy_property_from_node(SOCK_FLOAT, bsdf_node, "Coat Roughness", {&coat_roughness, 1});
|
||||
copy_property_from_node(SOCK_FLOAT, bsdf_node, "Anisotropic", {&aniso, 1});
|
||||
copy_property_from_node(SOCK_FLOAT, bsdf_node, "Anisotropic Rotation", {&aniso_rot, 1});
|
||||
copy_property_from_node(SOCK_FLOAT, bsdf_node, "Transmission", {&transmission, 1});
|
||||
|
||||
/* Clearcoat used to include an implicit 0.25 factor, so stay compatible to old versions. */
|
||||
coat *= 4.0f;
|
||||
}
|
||||
|
||||
/* See https://wikipedia.org/wiki/Wavefront_.obj_file for all possible values of `illum`. */
|
||||
|
@ -290,8 +292,8 @@ static void store_bsdf_properties(const bNode *bsdf_node,
|
|||
r_mtl_mat.roughness = roughness;
|
||||
r_mtl_mat.metallic = metallic;
|
||||
r_mtl_mat.sheen = sheen;
|
||||
r_mtl_mat.cc_thickness = clearcoat;
|
||||
r_mtl_mat.cc_roughness = clearcoat_roughness;
|
||||
r_mtl_mat.cc_thickness = coat;
|
||||
r_mtl_mat.cc_roughness = coat_roughness;
|
||||
r_mtl_mat.aniso = aniso;
|
||||
r_mtl_mat.aniso_rot = aniso_rot;
|
||||
r_mtl_mat.transmit_color = {transmission, transmission, transmission};
|
||||
|
|
|
@ -327,10 +327,11 @@ static void set_bsdf_socket_values(bNode *bsdf, Material *mat, const MTLMaterial
|
|||
set_property_of_socket(SOCK_FLOAT, "Sheen", {mtl_mat.sheen}, bsdf);
|
||||
}
|
||||
if (mtl_mat.cc_thickness >= 0) {
|
||||
set_property_of_socket(SOCK_FLOAT, "Clearcoat", {mtl_mat.cc_thickness}, bsdf);
|
||||
/* Clearcoat used to include an implicit 0.25 factor, so stay compatible to old versions. */
|
||||
set_property_of_socket(SOCK_FLOAT, "Coat", {0.25f * mtl_mat.cc_thickness}, bsdf);
|
||||
}
|
||||
if (mtl_mat.cc_roughness >= 0) {
|
||||
set_property_of_socket(SOCK_FLOAT, "Clearcoat Roughness", {mtl_mat.cc_roughness}, bsdf);
|
||||
set_property_of_socket(SOCK_FLOAT, "Coat Roughness", {mtl_mat.cc_roughness}, bsdf);
|
||||
}
|
||||
if (mtl_mat.aniso >= 0) {
|
||||
set_property_of_socket(SOCK_FLOAT, "Anisotropic", {mtl_mat.aniso}, bsdf);
|
||||
|
|
|
@ -93,42 +93,62 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
#define SOCK_SHEEN_ROUGHNESS_ID 13
|
||||
b.add_input<decl::Color>("Sheen Tint").default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
#define SOCK_SHEEN_TINT_ID 14
|
||||
b.add_input<decl::Float>("Clearcoat")
|
||||
b.add_input<decl::Float>("Coat")
|
||||
.default_value(0.0f)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
#define SOCK_CLEARCOAT_ID 15
|
||||
b.add_input<decl::Float>("Clearcoat Roughness")
|
||||
.subtype(PROP_FACTOR)
|
||||
.description(
|
||||
Alaska marked this conversation as resolved
Outdated
Alaska
commented
Remove the full stop from the end of Remove the full stop from the end of `"Typically should be zero or one for physically-based materials."`. The Blender UI automatically adds a full stop to the end.
|
||||
"Controls the intensity of the coat layer, both the reflection and the tinting. "
|
||||
"Typically should be zero or one for physically-based materials");
|
||||
#define SOCK_COAT_ID 15
|
||||
b.add_input<decl::Float>("Coat Roughness")
|
||||
.default_value(0.03f)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
#define SOCK_CLEARCOAT_ROUGHNESS_ID 16
|
||||
.subtype(PROP_FACTOR)
|
||||
.description("The roughness of the coat layer");
|
||||
#define SOCK_COAT_ROUGHNESS_ID 16
|
||||
b.add_input<decl::Float>("Coat IOR")
|
||||
LukasStockner marked this conversation as resolved
Alaska
commented
If CoatIORs below 1.0 aren't supported at this time, then I would personally like see to min IOR set to 1.0. If CoatIORs below 1.0 aren't supported at this time, then I would personally like see to min IOR set to 1.0.
|
||||
.default_value(1.5f)
|
||||
.min(1.0f)
|
||||
.max(4.0f)
|
||||
.description(
|
||||
"The index of refraction of the coat layer (affects its reflectivity as well "
|
||||
"as the falloff of coat tinting)");
|
||||
#define SOCK_COAT_IOR_ID 17
|
||||
b.add_input<decl::Color>("Coat Tint")
|
||||
.default_value({1.0f, 1.0f, 1.0f, 1.0f})
|
||||
.description(
|
||||
"Adds a colored tint to the coat layer by modeling absorption in the layer. "
|
||||
"Saturation increases at shallower angles, as the light travels farther through the "
|
||||
"medium "
|
||||
"(depending on the Coat IOR)");
|
||||
#define SOCK_COAT_TINT_ID 18
|
||||
b.add_input<decl::Float>("IOR").default_value(1.45f).min(1.0f).max(1000.0f);
|
||||
#define SOCK_IOR_ID 17
|
||||
#define SOCK_IOR_ID 19
|
||||
b.add_input<decl::Float>("Transmission")
|
||||
.default_value(0.0f)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
#define SOCK_TRANSMISSION_ID 18
|
||||
#define SOCK_TRANSMISSION_ID 20
|
||||
b.add_input<decl::Color>("Emission").default_value({0.0f, 0.0f, 0.0f, 1.0f});
|
||||
#define SOCK_EMISSION_ID 19
|
||||
#define SOCK_EMISSION_ID 21
|
||||
b.add_input<decl::Float>("Emission Strength").default_value(1.0).min(0.0f).max(1000000.0f);
|
||||
#define SOCK_EMISSION_STRENGTH_ID 20
|
||||
#define SOCK_EMISSION_STRENGTH_ID 22
|
||||
b.add_input<decl::Float>("Alpha").default_value(1.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
|
||||
#define SOCK_ALPHA_ID 21
|
||||
#define SOCK_ALPHA_ID 23
|
||||
b.add_input<decl::Vector>("Normal").hide_value();
|
||||
#define SOCK_NORMAL_ID 22
|
||||
b.add_input<decl::Vector>("Clearcoat Normal").hide_value();
|
||||
#define SOCK_CLEARCOAT_NORMAL_ID 23
|
||||
#define SOCK_NORMAL_ID 24
|
||||
b.add_input<decl::Vector>("Coat Normal").hide_value();
|
||||
#define SOCK_COAT_NORMAL_ID 25
|
||||
b.add_input<decl::Vector>("Tangent").hide_value();
|
||||
#define SOCK_TANGENT_ID 24
|
||||
#define SOCK_TANGENT_ID 26
|
||||
b.add_input<decl::Float>("Weight").unavailable();
|
||||
#define SOCK_WEIGHT_ID 25
|
||||
#define SOCK_WEIGHT_ID 27
|
||||
b.add_output<decl::Shader>("BSDF");
|
||||
#define SOCK_BSDF_ID 26
|
||||
#define SOCK_BSDF_ID 28
|
||||
}
|
||||
|
||||
static void node_shader_buts_principled(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
|
@ -158,9 +178,9 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
|
|||
GPU_link(mat, "world_normals_get", &in[SOCK_NORMAL_ID].link);
|
||||
}
|
||||
|
||||
/* Clearcoat Normals */
|
||||
if (!in[SOCK_CLEARCOAT_NORMAL_ID].link) {
|
||||
GPU_link(mat, "world_normals_get", &in[SOCK_CLEARCOAT_NORMAL_ID].link);
|
||||
/* Coat Normals */
|
||||
if (!in[SOCK_COAT_NORMAL_ID].link) {
|
||||
GPU_link(mat, "world_normals_get", &in[SOCK_COAT_NORMAL_ID].link);
|
||||
}
|
||||
|
||||
#if 0 /* Not used at the moment. */
|
||||
|
@ -177,7 +197,7 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
|
|||
bool use_subsurf = socket_not_zero(SOCK_SUBSURFACE_ID) && use_diffuse;
|
||||
bool use_refract = socket_not_one(SOCK_METALLIC_ID) && socket_not_zero(SOCK_TRANSMISSION_ID);
|
||||
bool use_transparency = socket_not_one(SOCK_ALPHA_ID);
|
||||
bool use_clear = socket_not_zero(SOCK_CLEARCOAT_ID);
|
||||
bool use_coat = socket_not_zero(SOCK_COAT_ID);
|
||||
|
||||
eGPUMaterialFlag flag = GPU_MATFLAG_GLOSSY;
|
||||
if (use_diffuse) {
|
||||
|
@ -192,22 +212,22 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
|
|||
if (use_transparency) {
|
||||
flag |= GPU_MATFLAG_TRANSPARENT;
|
||||
}
|
||||
if (use_clear) {
|
||||
flag |= GPU_MATFLAG_CLEARCOAT;
|
||||
if (use_coat) {
|
||||
flag |= GPU_MATFLAG_COAT;
|
||||
}
|
||||
|
||||
/* Ref. #98190: Defines are optimizations for old compilers.
|
||||
* Might become unnecessary with EEVEE-Next. */
|
||||
if (use_diffuse == false && use_refract == false && use_clear == true) {
|
||||
flag |= GPU_MATFLAG_PRINCIPLED_CLEARCOAT;
|
||||
if (use_diffuse == false && use_refract == false && use_coat == true) {
|
||||
flag |= GPU_MATFLAG_PRINCIPLED_COAT;
|
||||
}
|
||||
else if (use_diffuse == false && use_refract == false && use_clear == false) {
|
||||
else if (use_diffuse == false && use_refract == false && use_coat == false) {
|
||||
flag |= GPU_MATFLAG_PRINCIPLED_METALLIC;
|
||||
}
|
||||
else if (use_diffuse == true && use_refract == false && use_clear == false) {
|
||||
else if (use_diffuse == true && use_refract == false && use_coat == false) {
|
||||
flag |= GPU_MATFLAG_PRINCIPLED_DIELECTRIC;
|
||||
}
|
||||
else if (use_diffuse == false && use_refract == true && use_clear == false) {
|
||||
else if (use_diffuse == false && use_refract == true && use_coat == false) {
|
||||
flag |= GPU_MATFLAG_PRINCIPLED_GLASS;
|
||||
}
|
||||
else {
|
||||
|
@ -225,7 +245,7 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
|
|||
float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
|
||||
float use_sss = (use_subsurf) ? 1.0f : 0.0f;
|
||||
float use_diffuse_f = (use_diffuse) ? 1.0f : 0.0f;
|
||||
float use_clear_f = (use_clear) ? 1.0f : 0.0f;
|
||||
float use_coat_f = (use_coat) ? 1.0f : 0.0f;
|
||||
float use_refract_f = (use_refract) ? 1.0f : 0.0f;
|
||||
|
||||
GPU_material_flag_set(mat, flag);
|
||||
|
@ -236,7 +256,7 @@ static int node_shader_gpu_bsdf_principled(GPUMaterial *mat,
|
|||
in,
|
||||
out,
|
||||
GPU_constant(&use_diffuse_f),
|
||||
GPU_constant(&use_clear_f),
|
||||
GPU_constant(&use_coat_f),
|
||||
GPU_constant(&use_refract_f),
|
||||
GPU_constant(&use_multi_scatter),
|
||||
GPU_uniform(&use_sss));
|
||||
|
|
|
@ -53,7 +53,7 @@ static int node_shader_gpu_eevee_specular(GPUMaterial *mat,
|
|||
GPU_link(mat, "world_normals_get", &in[5].link);
|
||||
}
|
||||
|
||||
/* Clearcoat Normals */
|
||||
/* Coat Normals */
|
||||
if (!in[8].link) {
|
||||
GPU_link(mat, "world_normals_get", &in[8].link);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
The
CoatIOR
inclosure color CoatBSDF = dielectric_bsdf(CoatNormal, vector(0.0), color(1.0), color(0.0), coat_r2, coat_r2, CoatIOR, "ggx");
also needs to be set tomax(CoatIOR, 1.0)
to avoid inconsistencies when compared to Cycles SVM when theCoatIOR
is below 1.0.