Cycles: Merge Anisotropic BSDF node into Glossy BSDF node #104445

Merged
Lukas Stockner merged 3 commits from LukasStockner/blender:remove-anisotropic-bsdf-node into main 2023-05-18 23:12:28 +02:00
28 changed files with 197 additions and 344 deletions

View File

@ -523,27 +523,6 @@ static ShaderNode *add_node(Scene *scene,
else if (b_node.is_a(&RNA_ShaderNodeHoldout)) {
node = graph->create_node<HoldoutNode>();
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
BL::ShaderNodeBsdfAnisotropic b_aniso_node(b_node);
AnisotropicBsdfNode *aniso = graph->create_node<AnisotropicBsdfNode>();
switch (b_aniso_node.distribution()) {
case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
aniso->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
break;
case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
aniso->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID);
break;
case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX:
aniso->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
break;
case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
aniso->set_distribution(CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
break;
}
node = aniso;
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfDiffuse)) {
node = graph->create_node<DiffuseBsdfNode>();
}
@ -566,24 +545,21 @@ static ShaderNode *add_node(Scene *scene,
node = subsurface;
}
else if (b_node.is_a(&RNA_ShaderNodeBsdfGlossy)) {
BL::ShaderNodeBsdfGlossy b_glossy_node(b_node);
else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
BL::ShaderNodeBsdfAnisotropic b_glossy_node(b_node);
GlossyBsdfNode *glossy = graph->create_node<GlossyBsdfNode>();
switch (b_glossy_node.distribution()) {
case BL::ShaderNodeBsdfGlossy::distribution_SHARP:
glossy->set_distribution(CLOSURE_BSDF_REFLECTION_ID);
break;
case BL::ShaderNodeBsdfGlossy::distribution_BECKMANN:
case BL::ShaderNodeBsdfAnisotropic::distribution_BECKMANN:
glossy->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
break;
case BL::ShaderNodeBsdfGlossy::distribution_GGX:
case BL::ShaderNodeBsdfAnisotropic::distribution_GGX:
glossy->set_distribution(CLOSURE_BSDF_MICROFACET_GGX_ID);
break;
case BL::ShaderNodeBsdfGlossy::distribution_ASHIKHMIN_SHIRLEY:
case BL::ShaderNodeBsdfAnisotropic::distribution_ASHIKHMIN_SHIRLEY:
glossy->set_distribution(CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
break;
case BL::ShaderNodeBsdfGlossy::distribution_MULTI_GGX:
case BL::ShaderNodeBsdfAnisotropic::distribution_MULTI_GGX:
glossy->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
break;
}
@ -593,9 +569,6 @@ static ShaderNode *add_node(Scene *scene,
BL::ShaderNodeBsdfGlass b_glass_node(b_node);
GlassBsdfNode *glass = graph->create_node<GlassBsdfNode>();
switch (b_glass_node.distribution()) {
case BL::ShaderNodeBsdfGlass::distribution_SHARP:
glass->set_distribution(CLOSURE_BSDF_SHARP_GLASS_ID);
break;
case BL::ShaderNodeBsdfGlass::distribution_BECKMANN:
glass->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID);
break;
@ -612,9 +585,6 @@ static ShaderNode *add_node(Scene *scene,
BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
RefractionBsdfNode *refraction = graph->create_node<RefractionBsdfNode>();
switch (b_refraction_node.distribution()) {
case BL::ShaderNodeBsdfRefraction::distribution_SHARP:
refraction->set_distribution(CLOSURE_BSDF_REFRACTION_ID);
break;
case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN:
refraction->set_distribution(CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
break;

View File

@ -6,7 +6,6 @@
set(SRC_OSL
node_add_closure.osl
node_ambient_occlusion.osl
node_anisotropic_bsdf.osl
node_attribute.osl
node_background.osl
node_bevel.osl

View File

@ -1,45 +0,0 @@
/* SPDX-License-Identifier: Apache-2.0
* Copyright 2011-2022 Blender Foundation */
#include "stdcycles.h"
shader node_anisotropic_bsdf(color Color = 0.0,
string distribution = "GGX",
float Roughness = 0.0,
float Anisotropy = 0.0,
float Rotation = 0.0,
normal Normal = N,
normal Tangent = normalize(dPdu),
output closure color BSDF = 0)
{
/* rotate tangent around normal */
vector T = Tangent;
if (Rotation != 0.0)
T = rotate(T, Rotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
/* compute roughness */
float roughness = Roughness * Roughness;
float roughness_u, roughness_v;
float aniso = clamp(Anisotropy, -0.99, 0.99);
if (aniso < 0.0) {
roughness_u = roughness / (1.0 + aniso);
roughness_v = roughness * (1.0 + aniso);
}
else {
roughness_u = roughness * (1.0 - aniso);
roughness_v = roughness / (1.0 - aniso);
}
if (distribution == "sharp")
BSDF = Color * reflection(Normal);
else if (distribution == "beckmann")
BSDF = Color * microfacet_beckmann_aniso(Normal, T, roughness_u, roughness_v);
else if (distribution == "GGX")
BSDF = Color * microfacet_ggx_aniso(Normal, T, roughness_u, roughness_v);
else if (distribution == "Multiscatter GGX")
BSDF = Color * microfacet_multi_ggx_aniso(Normal, T, roughness_u, roughness_v, Color);
else
BSDF = Color * ashikhmin_shirley(Normal, T, roughness_u, roughness_v);
}

View File

@ -7,13 +7,40 @@
shader node_glossy_bsdf(color Color = 0.8,
string distribution = "ggx",
float Roughness = 0.2,
float Anisotropy = 0.0,
float Rotation = 0.0,
normal Normal = N,
normal Tangent = 0.0,
output closure color BSDF = 0)
{
/* compute roughness */
float roughness = Roughness * Roughness;
float roughness_u, roughness_v;
float aniso = clamp(Anisotropy, -0.99, 0.99);
/* rotate tangent around normal */
vector T = Tangent;
if (abs(aniso) <= 1e-4) {
roughness_u = roughness;
roughness_v = roughness;
}
else {
if (Rotation != 0.0)
T = rotate(T, Rotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
if (aniso < 0.0) {
roughness_u = roughness / (1.0 + aniso);
roughness_v = roughness * (1.0 + aniso);
}
else {
roughness_u = roughness * (1.0 - aniso);
roughness_v = roughness / (1.0 - aniso);
}
}
if (distribution == "Multiscatter GGX")
BSDF = Color * microfacet_multi_ggx(Normal, roughness, Color);
else
BSDF = Color * microfacet(distribution, Normal, roughness, 0.0, 0);
BSDF = Color * microfacet(distribution, Normal, T, roughness_u, roughness_v, 0.0, 0);
}

View File

@ -494,7 +494,10 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
bsdf->ior = 1.0f;
bsdf->fresnel = NULL;
if (data_node.y == SVM_STACK_INVALID) {
/* compute roughness */
float anisotropy = clamp(param2, -0.99f, 0.99f);
if (data_node.y == SVM_STACK_INVALID || fabsf(anisotropy) <= 1e-4f) {
/* Isotropic case. */
bsdf->T = zero_float3();
bsdf->alpha_x = roughness;
bsdf->alpha_y = roughness;
@ -507,8 +510,6 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
if (rotation != 0.0f)
bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
/* compute roughness */
float anisotropy = clamp(param2, -0.99f, 0.99f);
if (anisotropy < 0.0f) {
bsdf->alpha_x = roughness / (1.0f + anisotropy);
bsdf->alpha_y = roughness * (1.0f + anisotropy);

View File

@ -2335,68 +2335,6 @@ void BsdfNode::compile(OSLCompiler & /*compiler*/)
assert(0);
}
/* Anisotropic BSDF Closure */
NODE_DEFINE(AnisotropicBsdfNode)
{
NodeType *type = NodeType::add("anisotropic_bsdf", create, NodeType::SHADER);
SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
SOCKET_IN_NORMAL(normal, "Normal", zero_float3(), SocketType::LINK_NORMAL);
SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
static NodeEnum distribution_enum;
distribution_enum.insert("beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_ID);
distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_ID);
distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID);
SOCKET_IN_VECTOR(tangent, "Tangent", zero_float3(), SocketType::LINK_TANGENT);
SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.5f);
SOCKET_IN_FLOAT(rotation, "Rotation", 0.0f);
SOCKET_OUT_CLOSURE(BSDF, "BSDF");
return type;
}
AnisotropicBsdfNode::AnisotropicBsdfNode() : BsdfNode(get_node_type())
{
closure = CLOSURE_BSDF_MICROFACET_GGX_ID;
}
void AnisotropicBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if (shader->has_surface_link()) {
ShaderInput *tangent_in = input("Tangent");
if (!tangent_in->link)
attributes->add(ATTR_STD_GENERATED);
}
ShaderNode::attributes(shader, attributes);
}
void AnisotropicBsdfNode::compile(SVMCompiler &compiler)
{
closure = distribution;
if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID)
BsdfNode::compile(
compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), input("Color"));
else
BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation"));
}
void AnisotropicBsdfNode::compile(OSLCompiler &compiler)
{
compiler.parameter(this, "distribution");
compiler.add(this, "node_anisotropic_bsdf");
}
/* Glossy BSDF Closure */
NODE_DEFINE(GlossyBsdfNode)
@ -2414,7 +2352,12 @@ NODE_DEFINE(GlossyBsdfNode)
distribution_enum.insert("ashikhmin_shirley", CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID);
distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_GGX_ID);
SOCKET_IN_VECTOR(tangent, "Tangent", zero_float3(), SocketType::LINK_TANGENT);
SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
SOCKET_IN_FLOAT(anisotropy, "Anisotropy", 0.0f);
SOCKET_IN_FLOAT(rotation, "Rotation", 0.0f);
SOCKET_OUT_CLOSURE(BSDF, "BSDF");
@ -2427,8 +2370,32 @@ GlossyBsdfNode::GlossyBsdfNode() : BsdfNode(get_node_type())
distribution_orig = NBUILTIN_CLOSURES;
}
bool GlossyBsdfNode::is_isotropic()
{
ShaderInput *anisotropy_input = input("Anisotropy");
/* Keep in sync with the thresholds in OSL's node_glossy_bsdf and SVM's svm_node_closure_bsdf. */
return (!anisotropy_input->link && fabsf(anisotropy) <= 1e-4f);
}
void GlossyBsdfNode::attributes(Shader *shader, AttributeRequestSet *attributes)
{
if (shader->has_surface_link()) {
ShaderInput *tangent_in = input("Tangent");
if (!tangent_in->link && !is_isotropic())
attributes->add(ATTR_STD_GENERATED);
}
ShaderNode::attributes(shader, attributes);
}
void GlossyBsdfNode::simplify_settings(Scene *scene)
{
/* If the anisotropy is close enough to zero, fall back to the isotropic case. */
ShaderInput *tangent_input = input("Tangent");
if (tangent_input->link && is_isotropic()) {
tangent_input->disconnect();
}
if (distribution_orig == NBUILTIN_CLOSURES) {
roughness_orig = roughness;
distribution_orig = distribution;
@ -2478,9 +2445,10 @@ void GlossyBsdfNode::compile(SVMCompiler &compiler)
if (closure == CLOSURE_BSDF_REFLECTION_ID)
BsdfNode::compile(compiler, NULL, NULL);
else if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID)
BsdfNode::compile(compiler, input("Roughness"), NULL, NULL, input("Color"));
BsdfNode::compile(
compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), input("Color"));
else
BsdfNode::compile(compiler, input("Roughness"), NULL);
BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation"));
}
void GlossyBsdfNode::compile(OSLCompiler &compiler)

View File

@ -495,27 +495,6 @@ class BsdfNode : public BsdfBaseNode {
NODE_SOCKET_API(float, surface_mix_weight)
};
class AnisotropicBsdfNode : public BsdfNode {
public:
SHADER_NODE_CLASS(AnisotropicBsdfNode)
NODE_SOCKET_API(float3, tangent)
NODE_SOCKET_API(float, roughness)
NODE_SOCKET_API(float, anisotropy)
NODE_SOCKET_API(float, rotation)
NODE_SOCKET_API(ClosureType, distribution)
ClosureType get_closure_type()
{
return distribution;
}
void attributes(Shader *shader, AttributeRequestSet *attributes);
bool has_attribute_dependency()
{
return true;
}
};
class DiffuseBsdfNode : public BsdfNode {
public:
SHADER_NODE_CLASS(DiffuseBsdfNode)
@ -624,12 +603,23 @@ class GlossyBsdfNode : public BsdfNode {
return distribution;
}
NODE_SOCKET_API(float3, tangent)
NODE_SOCKET_API(float, roughness)
NODE_SOCKET_API(float, anisotropy)
NODE_SOCKET_API(float, rotation)
NODE_SOCKET_API(ClosureType, distribution)
void attributes(Shader *shader, AttributeRequestSet *attributes);
bool has_attribute_dependency()
{
return true;
}
private:
float roughness_orig;
ClosureType distribution_orig;
bool is_isotropic();
};
class GlassBsdfNode : public BsdfNode {

View File

@ -191,7 +191,6 @@ shader_node_categories = [
NodeItem("ShaderNodeBsdfRefraction", poll=object_eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfGlass", poll=object_eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfTranslucent", poll=object_eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfAnisotropic", poll=object_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfVelvet", poll=object_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfToon", poll=object_cycles_shader_nodes_poll),
NodeItem("ShaderNodeSubsurfaceScattering", poll=object_eevee_cycles_shader_nodes_poll),

View File

@ -554,8 +554,10 @@ struct bNodeSocket *ntreeAddSocketInterface(struct bNodeTree *ntree,
* \{ */
struct bNodeType *nodeTypeFind(const char *idname);
const char *nodeTypeFindAlias(const char *idname);
void nodeRegisterType(struct bNodeType *ntype);
void nodeUnregisterType(struct bNodeType *ntype);
void nodeRegisterAlias(struct bNodeType *nt, const char *alias);
struct GHashIterator *nodeTypeGetIterator(void);
/* Helper macros for iterating over node types. */
@ -893,9 +895,9 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i
#define SH_NODE_MIX_SHADER 128
#define SH_NODE_ATTRIBUTE 129
#define SH_NODE_BACKGROUND 130
#define SH_NODE_BSDF_ANISOTROPIC 131
#define SH_NODE_BSDF_GLOSSY 131
#define SH_NODE_BSDF_DIFFUSE 132
#define SH_NODE_BSDF_GLOSSY 133
#define SH_NODE_BSDF_GLOSSY_LEGACY 133
#define SH_NODE_BSDF_GLASS 134
#define SH_NODE_BSDF_TRANSLUCENT 137
#define SH_NODE_BSDF_TRANSPARENT 138

View File

@ -1352,6 +1352,7 @@ namespace blender::bke {
static GHash *nodetreetypes_hash = nullptr;
static GHash *nodetypes_hash = nullptr;
static GHash *nodetypes_alias_hash = nullptr;
static GHash *nodesockettypes_hash = nullptr;
} // namespace blender::bke
@ -1416,6 +1417,19 @@ bNodeType *nodeTypeFind(const char *idname)
return nullptr;
}
const char *nodeTypeFindAlias(const char *alias)
{
if (alias[0]) {
const char *idname = static_cast<const char *>(
BLI_ghash_lookup(blender::bke::nodetypes_alias_hash, alias));
if (idname) {
return idname;
}
}
return alias;
}
static void node_free_type(void *nodetype_v)
{
bNodeType *nodetype = static_cast<bNodeType *>(nodetype_v);
@ -1458,6 +1472,11 @@ void nodeUnregisterType(bNodeType *nt)
BLI_ghash_remove(blender::bke::nodetypes_hash, nt->idname, nullptr, node_free_type);
}
void nodeRegisterAlias(bNodeType *nt, const char *alias)
{
BLI_ghash_insert(blender::bke::nodetypes_alias_hash, BLI_strdup(alias), BLI_strdup(nt->idname));
}
namespace blender::bke {
bool node_type_is_undefined(const bNode *node)
@ -4389,6 +4408,7 @@ void BKE_node_system_init()
{
blender::bke::nodetreetypes_hash = BLI_ghash_str_new("nodetreetypes_hash gh");
blender::bke::nodetypes_hash = BLI_ghash_str_new("nodetypes_hash gh");
blender::bke::nodetypes_alias_hash = BLI_ghash_str_new("nodetypes_alias_hash gh");
blender::bke::nodesockettypes_hash = BLI_ghash_str_new("nodesockettypes_hash gh");
register_nodes();
@ -4396,6 +4416,11 @@ void BKE_node_system_init()
void BKE_node_system_exit()
{
if (blender::bke::nodetypes_alias_hash) {
BLI_ghash_free(blender::bke::nodetypes_alias_hash, MEM_freeN, MEM_freeN);
blender::bke::nodetypes_alias_hash = nullptr;
}
if (blender::bke::nodetypes_hash) {
NODE_TYPES_BEGIN (nt) {
if (nt->rna_ext.free) {

View File

@ -2176,6 +2176,46 @@ static void versioning_replace_legacy_mix_rgb_node(bNodeTree *ntree)
}
}
static void versioning_replace_legacy_glossy_node(bNodeTree *ntree)
{
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type == SH_NODE_BSDF_GLOSSY_LEGACY) {
strcpy(node->idname, "ShaderNodeBsdfAnisotropic");
node->type = SH_NODE_BSDF_GLOSSY;
}
}
}
static void versioning_remove_microfacet_sharp_distribution(bNodeTree *ntree)
{
/* Find all glossy, glass and refraction BSDF nodes that have their distribution
* set to SHARP and set them to GGX, disconnect any link to the Roughness input
* and set its value to zero. */
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (!ELEM(node->type, SH_NODE_BSDF_GLOSSY, SH_NODE_BSDF_GLASS, SH_NODE_BSDF_REFRACTION)) {
continue;
}
if (node->custom1 != SHD_GLOSSY_SHARP_DEPRECATED) {
continue;
}
node->custom1 = SHD_GLOSSY_GGX;
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
if (!STREQ(socket->identifier, "Roughness")) {
continue;
}
if (socket->link != nullptr) {
nodeRemLink(ntree, socket->link);
}
bNodeSocketValueFloat *socket_value = (bNodeSocketValueFloat *)socket->default_value;
socket_value->value = 0.0f;
break;
}
}
}
static void version_fix_image_format_copy(Main *bmain, ImageFormatData *format)
{
/* Fix bug where curves in image format were not properly copied to file output
@ -4371,5 +4411,12 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
*/
{
/* Keep this block, even when empty. */
/* Convert anisotropic BSDF node to glossy BSDF. */
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
versioning_replace_legacy_glossy_node(ntree);
versioning_remove_microfacet_sharp_distribution(ntree);
}
FOREACH_NODETREE_END;
}
}

View File

@ -181,8 +181,8 @@ static void displacement_principled_nodes(bNode *node)
static bool node_has_roughness(const bNode *node)
{
return ELEM(node->type,
SH_NODE_BSDF_ANISOTROPIC,
SH_NODE_BSDF_GLASS,
SH_NODE_BSDF_GLOSSY_LEGACY,
SH_NODE_BSDF_GLOSSY,
SH_NODE_BSDF_REFRACTION);
}

View File

@ -504,7 +504,6 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_VECTOR_DISPLACEMENT:
ntype->draw_buttons = node_shader_buts_displacement;
break;
case SH_NODE_BSDF_GLOSSY:
case SH_NODE_BSDF_GLASS:
case SH_NODE_BSDF_REFRACTION:
ntype->draw_buttons = node_shader_buts_glossy;

View File

@ -464,7 +464,6 @@ set(GLSL_SRC
shaders/material/gpu_shader_material_add_shader.glsl
shaders/material/gpu_shader_material_ambient_occlusion.glsl
shaders/material/gpu_shader_material_anisotropic.glsl
shaders/material/gpu_shader_material_attribute.glsl
shaders/material/gpu_shader_material_background.glsl
shaders/material/gpu_shader_material_bevel.glsl

View File

@ -1,27 +0,0 @@
void node_bsdf_anisotropic(vec4 color,
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 = cameraVec(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;
result = closure_eval(reflection_data);
}

View File

@ -1,6 +1,13 @@
void node_bsdf_glossy(
vec4 color, float roughness, vec3 N, float weight, float do_multiscatter, out Closure result)
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)
{
N = safe_normalize(N);
vec3 V = cameraVec(g_data.P);

View File

@ -1698,7 +1698,7 @@ typedef struct NodeShaderMix {
/* glossy distributions */
#define SHD_GLOSSY_BECKMANN 0
#define SHD_GLOSSY_SHARP 1
#define SHD_GLOSSY_SHARP_DEPRECATED 1 /* deprecated */
#define SHD_GLOSSY_GGX 2
#define SHD_GLOSSY_ASHIKHMIN_SHIRLEY 3
#define SHD_GLOSSY_MULTI_GGX 4

View File

@ -1185,6 +1185,9 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree,
return NULL;
}
/* If the given idname is an alias, translate it to the proper idname. */
type = nodeTypeFindAlias(type);
ntype = nodeTypeFind(type);
if (!ntype) {
BKE_reportf(reports, RPT_ERROR, "Node type %s undefined", type);
@ -4740,11 +4743,6 @@ static const EnumPropertyItem node_ycc_items[] = {
};
static const EnumPropertyItem node_glossy_items[] = {
{SHD_GLOSSY_SHARP,
"SHARP",
0,
"Sharp",
"Results in perfectly sharp reflections like a mirror. The Roughness value is not used"},
{SHD_GLOSSY_BECKMANN, "BECKMANN", 0, "Beckmann", ""},
{SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""},
{SHD_GLOSSY_ASHIKHMIN_SHIRLEY, "ASHIKHMIN_SHIRLEY", 0, "Ashikhmin-Shirley", ""},
@ -4757,25 +4755,7 @@ static const EnumPropertyItem node_glossy_items[] = {
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem node_anisotropic_items[] = {
{SHD_GLOSSY_BECKMANN, "BECKMANN", 0, "Beckmann", ""},
{SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""},
{SHD_GLOSSY_MULTI_GGX,
"MULTI_GGX",
0,
"Multiscatter GGX",
"Slower than GGX but gives a more energy conserving results, which would otherwise be "
"visible as excessive darkening"},
{SHD_GLOSSY_ASHIKHMIN_SHIRLEY, "ASHIKHMIN_SHIRLEY", 0, "Ashikhmin-Shirley", ""},
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem node_glass_items[] = {
{SHD_GLOSSY_SHARP,
"SHARP",
0,
"Sharp",
"Results in perfectly sharp reflections like a mirror. The Roughness value is not used"},
{SHD_GLOSSY_BECKMANN, "BECKMANN", 0, "Beckmann", ""},
{SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""},
{SHD_GLOSSY_MULTI_GGX,
@ -4788,11 +4768,6 @@ static const EnumPropertyItem node_glass_items[] = {
};
static const EnumPropertyItem node_refraction_items[] = {
{SHD_GLOSSY_SHARP,
"SHARP",
0,
"Sharp",
"Results in perfectly sharp reflections like a mirror. The Roughness value is not used"},
{SHD_GLOSSY_BECKMANN, "BECKMANN", 0, "Beckmann", ""},
{SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""},
{0, NULL, 0, NULL, NULL},
@ -6301,17 +6276,6 @@ static void def_refraction(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_anisotropic(StructRNA *srna)
{
PropertyRNA *prop;
prop = RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, node_anisotropic_items);
RNA_def_property_ui_text(prop, "Distribution", "Light scattering distribution on rough surface");
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_toon(StructRNA *srna)
{
PropertyRNA *prop;

View File

@ -59,10 +59,9 @@ 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_ANISOTROPIC, def_anisotropic, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic BSDF", "Glossy reflection with separate control over U and V direction roughness")
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", BsdfGlossy, "Glossy BSDF", "Reflection with microfacet distribution, used for materials such as metal or mirrors")
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")
DefNode(ShaderNode, SH_NODE_BSDF_GLASS, def_glass, "BSDF_GLASS", BsdfGlass, "Glass BSDF", "Glass-like shader mixing refraction and reflection at grazing angles")
DefNode(ShaderNode, SH_NODE_BSDF_REFRACTION, def_refraction, "BSDF_REFRACTION", BsdfRefraction, "Refraction BSDF", "Glossy refraction with sharp or microfacet distribution, typically used for materials that transmit light")
DefNode(ShaderNode, SH_NODE_BSDF_TRANSLUCENT, 0, "BSDF_TRANSLUCENT", BsdfTranslucent, "Translucent BSDF", "Lambertian diffuse transmission")

View File

@ -32,7 +32,6 @@ set(SRC
nodes/node_shader_bevel.cc
nodes/node_shader_blackbody.cc
nodes/node_shader_brightness.cc
nodes/node_shader_bsdf_anisotropic.cc
nodes/node_shader_bsdf_diffuse.cc
nodes/node_shader_bsdf_glass.cc
nodes/node_shader_bsdf_glossy.cc

View File

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

View File

@ -13,7 +13,6 @@ 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_anisotropic();
void register_node_type_sh_bsdf_diffuse();
void register_node_type_sh_bsdf_glass();
void register_node_type_sh_bsdf_glossy();

View File

@ -884,7 +884,6 @@ static void ntree_shader_weight_tree_invert(bNodeTree *ntree, bNode *output_node
break;
}
case SH_NODE_BACKGROUND:
case SH_NODE_BSDF_ANISOTROPIC:
case SH_NODE_BSDF_DIFFUSE:
case SH_NODE_BSDF_GLASS:
case SH_NODE_BSDF_GLOSSY:
@ -942,7 +941,6 @@ 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_ANISOTROPIC:
case SH_NODE_BSDF_DIFFUSE:
case SH_NODE_BSDF_GLASS:
case SH_NODE_BSDF_GLOSSY:

View File

@ -1,77 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-or-later
* Copyright 2005 Blender Foundation */
#include "node_shader_util.hh"
#include "UI_interface.h"
#include "UI_resources.h"
namespace blender::nodes::node_shader_bsdf_anisotropic_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::Float>("Roughness")
.default_value(0.5f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Float>("Anisotropy").default_value(0.5f).min(-1.0f).max(1.0f);
b.add_input<decl::Float>("Rotation")
.default_value(0.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Vector>("Normal").hide_value();
b.add_input<decl::Vector>("Tangent").hide_value();
b.add_input<decl::Float>("Weight").unavailable();
b.add_output<decl::Shader>("BSDF");
}
static void node_shader_buts_anisotropic(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
}
static void node_shader_init_anisotropic(bNodeTree * /*ntree*/, bNode *node)
{
node->custom1 = SHD_GLOSSY_GGX;
}
static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat,
bNode *node,
bNodeExecData * /*execdata*/,
GPUNodeStack *in,
GPUNodeStack *out)
{
if (!in[4].link) {
GPU_link(mat, "world_normals_get", &in[4].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_anisotropic", in, out, GPU_constant(&use_multi_scatter));
}
} // namespace blender::nodes::node_shader_bsdf_anisotropic_cc
/* node type definition */
void register_node_type_sh_bsdf_anisotropic()
{
namespace file_ns = blender::nodes::node_shader_bsdf_anisotropic_cc;
static bNodeType ntype;
sh_node_type_base(&ntype, SH_NODE_BSDF_ANISOTROPIC, "Anisotropic BSDF", NODE_CLASS_SHADER);
ntype.declare = file_ns::node_declare;
ntype.add_ui_poll = object_cycles_shader_nodes_poll;
ntype.draw_buttons = file_ns::node_shader_buts_anisotropic;
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE);
ntype.initfunc = file_ns::node_shader_init_anisotropic;
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_anisotropic;
nodeRegisterType(&ntype);
}

View File

@ -34,10 +34,6 @@ static int node_shader_gpu_bsdf_glass(GPUMaterial *mat,
GPU_link(mat, "world_normals_get", &in[3].link);
}
if (node->custom1 == SHD_GLOSSY_SHARP) {
GPU_link(mat, "set_value_zero", &in[1].link);
}
GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT);
float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;

View File

@ -3,6 +3,9 @@
#include "node_shader_util.hh"
#include "UI_interface.h"
#include "UI_resources.h"
namespace blender::nodes::node_shader_bsdf_glossy_cc {
static void node_declare(NodeDeclarationBuilder &b)
@ -13,11 +16,23 @@ static void node_declare(NodeDeclarationBuilder &b)
.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>("Rotation")
.default_value(0.0f)
.min(0.0f)
.max(1.0f)
.subtype(PROP_FACTOR);
b.add_input<decl::Vector>("Normal").hide_value();
b.add_input<decl::Vector>("Tangent").hide_value();
b.add_input<decl::Float>("Weight").unavailable();
b.add_output<decl::Shader>("BSDF");
}
static void node_shader_buts_glossy(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)
{
node->custom1 = SHD_GLOSSY_GGX;
@ -29,12 +44,8 @@ static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
if (!in[2].link) {
GPU_link(mat, "world_normals_get", &in[2].link);
}
if (node->custom1 == SHD_GLOSSY_SHARP) {
GPU_link(mat, "set_value_zero", &in[1].link);
if (!in[4].link) {
GPU_link(mat, "world_normals_get", &in[4].link);
}
GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY);
@ -56,9 +67,14 @@ void register_node_type_sh_bsdf_glossy()
sh_node_type_base(&ntype, SH_NODE_BSDF_GLOSSY, "Glossy 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;
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;
nodeRegisterType(&ntype);
/* Needed to preserve API compatibility with older versions which had separate
* Glossy and Anisotropic nodes. */
nodeRegisterAlias(&ntype, "ShaderNodeBsdfGlossy");
}

View File

@ -34,10 +34,6 @@ static int node_shader_gpu_bsdf_refraction(GPUMaterial *mat,
GPU_link(mat, "world_normals_get", &in[3].link);
}
if (node->custom1 == SHD_GLOSSY_SHARP) {
GPU_link(mat, "set_value_zero", &in[1].link);
}
GPU_material_flag_set(mat, GPU_MATFLAG_REFRACT);
return GPU_stack_link(mat, node, "node_bsdf_refraction", in, out);

View File

@ -4086,6 +4086,9 @@ static PyObject *pyrna_struct_bl_rna_get_subclass(PyObject *cls, PyObject *args)
PointerRNA ptr;
if (srna_base == &RNA_Node) {
/* If the given idname is an alias, translate it to the proper idname. */
id = nodeTypeFindAlias(id);
bNodeType *nt = nodeTypeFind(id);
if (nt) {
RNA_pointer_create(NULL, &RNA_Struct, nt->rna_ext.srna, &ptr);