Shader: Add Conductor BSDF Node #114958

Open
Alaska wants to merge 14 commits from Alaska/blender:metallic-bsdf into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
10 changed files with 58 additions and 41 deletions
Showing only changes of commit 5d6f651aef - Show all commits

View File

@ -137,6 +137,11 @@ class NODE_MT_category_shader_shader(Menu):
"ShaderNodeBackground",
poll=world_shader_nodes_poll(context),
)
node_add_menu.add_node_type(
layout,
"ShaderNodeBsdfConductor",
poll=object_shader_nodes_poll(context),
)
node_add_menu.add_node_type(
layout,
"ShaderNodeBsdfDiffuse",

View File

@ -966,6 +966,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define SH_NODE_COMBINE_COLOR 711
#define SH_NODE_SEPARATE_COLOR 712
#define SH_NODE_MIX 713
#define SH_NODE_BSDF_CONDUCTOR 714
/** \} */

View File

@ -500,6 +500,7 @@ set(GLSL_SRC
shaders/material/gpu_shader_material_combine_hsv.glsl
shaders/material/gpu_shader_material_combine_rgb.glsl
shaders/material/gpu_shader_material_combine_xyz.glsl
shaders/material/gpu_shader_material_conductor.glsl
shaders/material/gpu_shader_material_diffuse.glsl
shaders/material/gpu_shader_material_displacement.glsl
shaders/material/gpu_shader_material_eevee_specular.glsl

View File

@ -1,30 +1,31 @@
/* SPDX-FileCopyrightText: 2019-2023 Blender Authors
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
void node_bsdf_glossy(vec4 color,
float roughness,
float anisotropy,
float rotation,
vec3 N,
vec3 T,
float weight,
const float do_multiscatter,
out Closure result)
void node_bsdf_conductor(vec4 color,
vec4 tint,
float roughness,
float anisotropy,
float rotation,
vec3 N,
vec3 T,
float weight,
const float do_multiscatter,
out Closure result)
{
N = safe_normalize(N);
vec3 V = coordinate_incoming(g_data.P);
float NV = dot(N, V);
vec2 split_sum = brdf_lut(NV, roughness);
ClosureReflection reflection_data;
reflection_data.weight = weight;
reflection_data.color = (do_multiscatter != 0.0) ?
F_brdf_multi_scatter(color.rgb, color.rgb, split_sum) :
F_brdf_single_scatter(color.rgb, color.rgb, split_sum);
reflection_data.N = N;
reflection_data.roughness = roughness;
vec3 F0 = color.rgb;
vec3 F82 = min(tint.rgb, vec3(1.0));
vec3 metallic_brdf;
brdf_f82_tint_lut(F0, F82, NV, roughness, do_multiscatter != 0.0, metallic_brdf);
reflection_data.color = metallic_brdf;
reflection_data.weight = weight;
result = closure_eval(reflection_data);
}

View File

@ -61,6 +61,7 @@ DefNode(ShaderNode, SH_NODE_ATTRIBUTE, def_sh_attribute, "ATT
DefNode(ShaderNode, SH_NODE_AMBIENT_OCCLUSION, def_sh_ambient_occlusion,"AMBIENT_OCCLUSION", AmbientOcclusion, "Ambient Occlusion", "Compute how much the hemisphere above the shading point is occluded, for example to add weathering effects to corners.\nNote: For Cycles, this may slow down renders significantly")
DefNode(ShaderNode, SH_NODE_BACKGROUND, 0, "BACKGROUND", Background, "Background", "Add background light emission.\nNote: This node should only be used for the world surface output")
DefNode(ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "Create a \"hole\" in the image with zero alpha transparency, which is useful for compositing.\nNote: the holdout shader can only create alpha when transparency is enabled in the film settings")
DefNode(ShaderNode, SH_NODE_BSDF_CONDUCTOR, def_glossy, "BSDF_CONDUCTOR", BsdfConductor, "Conductor BSDF", "PlaceHolder: Reflection with microfacet distribution, used for materials such as metal or mirrors")
DefNode(ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse BSDF", "Lambertian and Oren-Nayar diffuse reflection")
DefNode(ShaderNode, SH_NODE_BSDF_PRINCIPLED, def_principled, "BSDF_PRINCIPLED", BsdfPrincipled, "Principled BSDF", "Physically-based, easy-to-use shader for rendering surface materials, based on the Disney principled model also known as the \"PBR\" shader")
DefNode(ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfAnisotropic, "Glossy BSDF", "Reflection with microfacet distribution, used for materials such as metal or mirrors")

View File

@ -36,6 +36,7 @@ set(SRC
nodes/node_shader_bsdf_diffuse.cc
nodes/node_shader_bsdf_glass.cc
nodes/node_shader_bsdf_glossy.cc
nodes/node_shader_bsdf_conductor.cc
nodes/node_shader_bsdf_hair.cc
nodes/node_shader_bsdf_hair_principled.cc
nodes/node_shader_bsdf_principled.cc

View File

@ -19,6 +19,7 @@ void register_shader_nodes()
register_node_type_sh_bevel();
register_node_type_sh_blackbody();
register_node_type_sh_brightcontrast();
register_node_type_sh_bsdf_conductor();
register_node_type_sh_bsdf_diffuse();
register_node_type_sh_bsdf_glass();
register_node_type_sh_bsdf_glossy();

View File

@ -15,6 +15,7 @@ void register_node_type_sh_background();
void register_node_type_sh_bevel();
void register_node_type_sh_blackbody();
void register_node_type_sh_brightcontrast();
void register_node_type_sh_bsdf_conductor();
void register_node_type_sh_bsdf_diffuse();
void register_node_type_sh_bsdf_glass();
void register_node_type_sh_bsdf_glossy();

View File

@ -898,6 +898,7 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
break;
}
case SH_NODE_BACKGROUND:
case SH_NODE_BSDF_CONDUCTOR:
case SH_NODE_BSDF_DIFFUSE:
case SH_NODE_BSDF_GLASS:
case SH_NODE_BSDF_GLOSSY:
@ -955,6 +956,7 @@ static bool closure_node_filter(const bNode *node)
case SH_NODE_ADD_SHADER:
case SH_NODE_MIX_SHADER:
case SH_NODE_BACKGROUND:
case SH_NODE_BSDF_CONDUCTOR:
case SH_NODE_BSDF_DIFFUSE:
case SH_NODE_BSDF_GLASS:
case SH_NODE_BSDF_GLOSSY:

View File

@ -1,4 +1,4 @@
/* SPDX-FileCopyrightText: 2005 Blender Authors
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
@ -7,17 +7,22 @@
#include "UI_interface.hh"
#include "UI_resources.hh"
namespace blender::nodes::node_shader_bsdf_glossy_cc {
namespace blender::nodes::node_shader_bsdf_conductor_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Color>("Color").default_value({0.8f, 0.8f, 0.8f, 1.0f});
b.add_input<decl::Color>("Tint").default_value({1.0f, 1.0f, 1.0f, 1.0f});
b.add_input<decl::Float>("Roughness")
.default_value(0.5f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>("Anisotropy").default_value(0.0f).min(-1.0f).max(1.0f);
b.add_input<decl::Float>("Anisotropy")
.default_value(0.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>("Rotation")
.default_value(0.0f)
.min(0.0f)
@ -29,31 +34,32 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Shader>("BSDF");
}
static void node_shader_buts_glossy(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
static void node_shader_buts_conductor(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
static void node_shader_init_glossy(bNodeTree * /*ntree*/, bNode *node)
static void node_shader_init_conductor(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_GLOSSY_MULTI_GGX;
}
static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat,
bNode *node,
bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
static int node_shader_gpu_bsdf_conductor(GPUMaterial *mat,
bNode *node,
bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
if (!in[4].link) {
GPU_link(mat, "world_normals_get", &in[4].link);
if (!in[5].link) {
GPU_link(mat, "world_normals_get", &in[5].link);
}
GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY);
float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
return GPU_stack_link(mat, node, "node_bsdf_glossy", in, out, GPU_constant(&use_multi_scatter));
return GPU_stack_link(
mat, node, "node_bsdf_conductor", in, out, GPU_constant(&use_multi_scatter));
}
NODE_SHADER_MATERIALX_BEGIN
@ -64,6 +70,7 @@ NODE_SHADER_MATERIALX_BEGIN
}
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
NodeItem tint = get_input_value("Tint", NodeItem::Type::Color3);
NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Vector2);
NodeItem anisotropy = get_input_value("Anisotropy", NodeItem::Type::Color3);
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
@ -71,7 +78,7 @@ NODE_SHADER_MATERIALX_BEGIN
NodeItem artistic_ior = create_node("artistic_ior",
NodeItem::Type::Multioutput,
{{"reflectivity", color}, {"edge_color", color}});
{{"reflectivity", color}, {"edge_color", tint}});
NodeItem ior_out = artistic_ior.add_output("ior", NodeItem::Type::Color3);
NodeItem extinction_out = artistic_ior.add_output("extinction", NodeItem::Type::Color3);
@ -86,27 +93,23 @@ NODE_SHADER_MATERIALX_BEGIN
#endif
NODE_SHADER_MATERIALX_END
} // namespace blender::nodes::node_shader_bsdf_glossy_cc
} // namespace blender::nodes::node_shader_bsdf_conductor_cc
/* node type definition */
void register_node_type_sh_bsdf_glossy()
void register_node_type_sh_bsdf_conductor()
{
namespace file_ns = blender::nodes::node_shader_bsdf_glossy_cc;
namespace file_ns = blender::nodes::node_shader_bsdf_conductor_cc;
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_BSDF_GLOSSY, "Glossy BSDF", NODE_CLASS_SHADER);
sh_node_type_base(&ntype, SH_NODE_BSDF_CONDUCTOR, "Conductor BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_shader_nodes_poll;
ntype.draw_buttons = file_ns::node_shader_buts_glossy;
ntype.draw_buttons = file_ns::node_shader_buts_conductor;
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE);
ntype.initfunc = file_ns::node_shader_init_glossy;
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_glossy;
ntype.initfunc = file_ns::node_shader_init_conductor;
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_conductor;
ntype.materialx_fn = file_ns::node_shader_materialx;
nodeRegisterType(&ntype);
/* Needed to preserve API compatibility with older versions which had separate
* Glossy and Anisotropic nodes. */
nodeRegisterAlias(&ntype, "ShaderNodeBsdfGlossy");
}