Shader: use single Principled BSDF input for metallic and specular tint
To match Standard Surface and OpenPBR. Ref #99447 Ref #112848
This commit is contained in:
@@ -16,7 +16,6 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
|
||||
float Metallic = 0.0,
|
||||
float Specular = 0.5,
|
||||
color SpecularTint = color(1.0),
|
||||
color MetallicTint = 1.0,
|
||||
float Roughness = 0.5,
|
||||
float Anisotropic = 0.0,
|
||||
float AnisotropicRotation = 0.0,
|
||||
@@ -96,7 +95,7 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
|
||||
color f0 = BaseColor;
|
||||
color f90 = color(1.0);
|
||||
MetallicBSDF = microfacet_f82_tint(
|
||||
distribution, Normal, T, alpha_x, alpha_y, f0, MetallicTint);
|
||||
distribution, Normal, T, alpha_x, alpha_y, f0, SpecularTint);
|
||||
BSDF = mix(BSDF, MetallicBSDF, clamp(Metallic, 0.0, 1.0));
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
||||
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, coat_normal_offset, dummy, alpha_offset,
|
||||
emission_strength_offset, emission_offset, metallic_tint_offset;
|
||||
emission_strength_offset, emission_offset, unused;
|
||||
uint4 data_node2 = read_node(kg, &offset);
|
||||
|
||||
float3 T = stack_load_float3(stack, data_node.y);
|
||||
@@ -87,11 +87,8 @@ 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,
|
||||
&sheen_roughness_offset,
|
||||
&metallic_tint_offset);
|
||||
svm_unpack_node_uchar4(
|
||||
data_node.w, &sheen_offset, &sheen_tint_offset, &sheen_roughness_offset, &unused);
|
||||
svm_unpack_node_uchar4(data_node2.x,
|
||||
&eta_offset,
|
||||
&transmission_offset,
|
||||
@@ -271,7 +268,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
||||
bsdf->alpha_y = alpha_y;
|
||||
|
||||
fresnel->f0 = rgb_to_spectrum(base_color);
|
||||
const Spectrum f82 = rgb_to_spectrum(stack_load_float3(stack, metallic_tint_offset));
|
||||
const Spectrum f82 = specular_tint;
|
||||
|
||||
/* setup bsdf */
|
||||
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
|
||||
|
||||
@@ -2708,7 +2708,6 @@ NODE_DEFINE(PrincipledBsdfNode)
|
||||
SOCKET_IN_FLOAT(specular, "Specular", 0.0f);
|
||||
SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
|
||||
SOCKET_IN_COLOR(specular_tint, "Specular Tint", one_float3());
|
||||
SOCKET_IN_COLOR(metallic_tint, "Metallic 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);
|
||||
@@ -2807,7 +2806,6 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler)
|
||||
int specular_offset = compiler.stack_assign(input("Specular"));
|
||||
int roughness_offset = compiler.stack_assign(input("Roughness"));
|
||||
int specular_tint_offset = compiler.stack_assign(input("Specular Tint"));
|
||||
int metallic_tint_offset = compiler.stack_assign(input("Metallic Tint"));
|
||||
int anisotropic_offset = compiler.stack_assign(input("Anisotropic"));
|
||||
int sheen_offset = compiler.stack_assign(input("Sheen"));
|
||||
int sheen_roughness_offset = compiler.stack_assign(input("Sheen Roughness"));
|
||||
@@ -2840,8 +2838,7 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler)
|
||||
tangent_offset,
|
||||
compiler.encode_uchar4(
|
||||
specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset),
|
||||
compiler.encode_uchar4(
|
||||
sheen_offset, sheen_tint_offset, sheen_roughness_offset, metallic_tint_offset));
|
||||
compiler.encode_uchar4(sheen_offset, sheen_tint_offset, sheen_roughness_offset));
|
||||
|
||||
compiler.add_node(
|
||||
compiler.encode_uchar4(
|
||||
|
||||
@@ -528,7 +528,6 @@ class PrincipledBsdfNode : public BsdfBaseNode {
|
||||
NODE_SOCKET_API(float, specular)
|
||||
NODE_SOCKET_API(float, roughness)
|
||||
NODE_SOCKET_API(float3, specular_tint)
|
||||
NODE_SOCKET_API(float3, metallic_tint)
|
||||
NODE_SOCKET_API(float, anisotropic)
|
||||
NODE_SOCKET_API(float, sheen)
|
||||
NODE_SOCKET_API(float, sheen_roughness)
|
||||
|
||||
@@ -802,6 +802,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)
|
||||
@@ -911,65 +970,6 @@ static void version_node_group_split_socket(bNodeTreeInterface &tree_interface,
|
||||
csocket->flag &= ~NODE_INTERFACE_SOCKET_OUTPUT;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
{
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 1)) {
|
||||
|
||||
@@ -31,7 +31,6 @@ void node_bsdf_principled(vec4 base_color,
|
||||
vec3 subsurface_radius,
|
||||
float subsurface_ior,
|
||||
float subsurface_anisotropy,
|
||||
vec4 metallic_tint,
|
||||
float specular,
|
||||
vec4 specular_tint,
|
||||
float anisotropic,
|
||||
|
||||
@@ -104,33 +104,32 @@ static void node_declare(NodeDeclarationBuilder &b)
|
||||
.draw_buttons([](uiLayout *layout, bContext * /*C*/, PointerRNA *ptr) {
|
||||
uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
|
||||
});
|
||||
spec.add_input<decl::Color>("Metallic Tint").default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
#define SOCK_METALLIC_TINT_ID 13
|
||||
spec.add_input<decl::Float>("Specular")
|
||||
.default_value(0.5f)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
#define SOCK_SPECULAR_ID 14
|
||||
#define SOCK_SPECULAR_ID 13
|
||||
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 15
|
||||
"Tint dielectric reflection at normal incidence for artistic control, and metallic "
|
||||
"reflection at near-grazing incidence to simulate complex index of refraction");
|
||||
#define SOCK_SPECULAR_TINT_ID 14
|
||||
spec.add_input<decl::Float>("Anisotropic")
|
||||
.default_value(0.0f)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
#define SOCK_ANISOTROPIC_ID 16
|
||||
#define SOCK_ANISOTROPIC_ID 15
|
||||
spec.add_input<decl::Float>("Anisotropic Rotation")
|
||||
.default_value(0.0f)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
#define SOCK_ANISOTROPIC_ROTATION_ID 17
|
||||
#define SOCK_ANISOTROPIC_ROTATION_ID 16
|
||||
spec.add_input<decl::Vector>("Tangent").hide_value();
|
||||
#define SOCK_TANGENT_ID 18
|
||||
#define SOCK_TANGENT_ID 17
|
||||
|
||||
/* Panel for Coat settings. */
|
||||
PanelDeclarationBuilder &coat = b.add_panel("Coat").default_closed(true);
|
||||
@@ -142,14 +141,14 @@ static void node_declare(NodeDeclarationBuilder &b)
|
||||
.description(
|
||||
"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 19
|
||||
#define SOCK_COAT_ID 18
|
||||
coat.add_input<decl::Float>("Coat Roughness")
|
||||
.default_value(0.03f)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR)
|
||||
.description("The roughness of the coat layer");
|
||||
#define SOCK_COAT_ROUGHNESS_ID 20
|
||||
#define SOCK_COAT_ROUGHNESS_ID 19
|
||||
coat.add_input<decl::Float>("Coat IOR")
|
||||
.default_value(1.5f)
|
||||
.min(1.0f)
|
||||
@@ -157,37 +156,37 @@ static void node_declare(NodeDeclarationBuilder &b)
|
||||
.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 21
|
||||
#define SOCK_COAT_IOR_ID 20
|
||||
coat.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 22
|
||||
#define SOCK_COAT_TINT_ID 21
|
||||
coat.add_input<decl::Vector>("Coat Normal").hide_value();
|
||||
#define SOCK_COAT_NORMAL_ID 23
|
||||
#define SOCK_COAT_NORMAL_ID 22
|
||||
|
||||
/* Panel for Sheen settings. */
|
||||
PanelDeclarationBuilder &sheen = b.add_panel("Sheen").default_closed(true);
|
||||
sheen.add_input<decl::Float>("Sheen").default_value(0.0f).min(0.0f).max(1.0f).subtype(
|
||||
PROP_FACTOR);
|
||||
#define SOCK_SHEEN_ID 24
|
||||
#define SOCK_SHEEN_ID 23
|
||||
sheen.add_input<decl::Float>("Sheen Roughness")
|
||||
.default_value(0.5f)
|
||||
.min(0.0f)
|
||||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
#define SOCK_SHEEN_ROUGHNESS_ID 25
|
||||
#define SOCK_SHEEN_ROUGHNESS_ID 24
|
||||
sheen.add_input<decl::Color>("Sheen Tint").default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
#define SOCK_SHEEN_TINT_ID 26
|
||||
#define SOCK_SHEEN_TINT_ID 25
|
||||
|
||||
/* Panel for Emission settings. */
|
||||
PanelDeclarationBuilder &emis = b.add_panel("Emission").default_closed(true);
|
||||
emis.add_input<decl::Color>("Emission Color").default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
#define SOCK_EMISSION_ID 27
|
||||
#define SOCK_EMISSION_ID 26
|
||||
emis.add_input<decl::Float>("Emission Strength").default_value(0.0).min(0.0f).max(1000000.0f);
|
||||
#define SOCK_EMISSION_STRENGTH_ID 28
|
||||
#define SOCK_EMISSION_STRENGTH_ID 27
|
||||
}
|
||||
|
||||
static void node_shader_init_principled(bNodeTree * /*ntree*/, bNode *node)
|
||||
|
||||
Reference in New Issue
Block a user