Cycles: add random walk subsurface scattering to Principled BSDF.
Differential Revision: https://developer.blender.org/D3054
This commit is contained in:
parent
0df9b2c715
commit
a6968e87f1
Notes:
blender-bot
2023-02-14 06:10:03 +01:00
Referenced by issue #54159, Bake Actions causes skewed bones on Rigify armature
|
@ -130,10 +130,13 @@ def displacement_nodes_insert():
|
|||
if check_is_new_shading_material(material):
|
||||
displacement_node_insert(material, material.node_tree, traversed)
|
||||
|
||||
def displacement_node_space(node):
|
||||
def displacement_principled_nodes(node):
|
||||
if node.bl_idname == 'ShaderNodeDisplacement':
|
||||
if node.space != 'WORLD':
|
||||
node.space = 'OBJECT'
|
||||
if node.bl_idname == 'ShaderNodeBsdfPrincipled':
|
||||
if node.subsurface_method != 'RANDOM_WALK':
|
||||
node.subsurface_method = 'BURLEY'
|
||||
|
||||
|
||||
def mapping_node_order_flip(node):
|
||||
|
@ -372,4 +375,4 @@ def do_versions(self):
|
|||
if not cmat.is_property_set("displacement_method"):
|
||||
cmat.displacement_method = 'BUMP'
|
||||
|
||||
foreach_cycles_node(displacement_node_space)
|
||||
foreach_cycles_node(displacement_principled_nodes)
|
||||
|
|
|
@ -535,6 +535,14 @@ static ShaderNode *add_node(Scene *scene,
|
|||
principled->distribution = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
|
||||
break;
|
||||
}
|
||||
switch (b_principled_node.subsurface_method()) {
|
||||
case BL::ShaderNodeBsdfPrincipled::subsurface_method_BURLEY:
|
||||
principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_ID;
|
||||
break;
|
||||
case BL::ShaderNodeBsdfPrincipled::subsurface_method_RANDOM_WALK:
|
||||
principled->subsurface_method = CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID;
|
||||
break;
|
||||
}
|
||||
node = principled;
|
||||
}
|
||||
else if(b_node.is_a(&RNA_ShaderNodeBsdfTranslucent)) {
|
||||
|
|
|
@ -373,7 +373,9 @@ ccl_device int bssrdf_setup(ShaderData *sd, Bssrdf *bssrdf, ClosureType type)
|
|||
if(bssrdf_channels < 3) {
|
||||
/* Add diffuse BSDF if any radius too small. */
|
||||
#ifdef __PRINCIPLED__
|
||||
if(type == CLOSURE_BSSRDF_PRINCIPLED_ID) {
|
||||
if(type == CLOSURE_BSSRDF_PRINCIPLED_ID ||
|
||||
type == CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
|
||||
{
|
||||
float roughness = bssrdf->roughness;
|
||||
float3 N = bssrdf->N;
|
||||
|
||||
|
@ -409,7 +411,8 @@ ccl_device int bssrdf_setup(ShaderData *sd, Bssrdf *bssrdf, ClosureType type)
|
|||
|
||||
if(type == CLOSURE_BSSRDF_BURLEY_ID ||
|
||||
type == CLOSURE_BSSRDF_PRINCIPLED_ID ||
|
||||
type == CLOSURE_BSSRDF_RANDOM_WALK_ID)
|
||||
type == CLOSURE_BSSRDF_RANDOM_WALK_ID ||
|
||||
type == CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
|
||||
{
|
||||
bssrdf_burley_setup(bssrdf);
|
||||
}
|
||||
|
|
|
@ -78,7 +78,9 @@ ccl_device void subsurface_scatter_setup_diffuse_bsdf(KernelGlobals *kg, ShaderD
|
|||
if(hit) {
|
||||
Bssrdf *bssrdf = (Bssrdf *)sc;
|
||||
#ifdef __PRINCIPLED__
|
||||
if(bssrdf->type == CLOSURE_BSSRDF_PRINCIPLED_ID) {
|
||||
if(bssrdf->type == CLOSURE_BSSRDF_PRINCIPLED_ID ||
|
||||
bssrdf->type == CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
|
||||
{
|
||||
PrincipledDiffuseBsdf *bsdf = (PrincipledDiffuseBsdf*)bsdf_alloc(sd, sizeof(PrincipledDiffuseBsdf), weight);
|
||||
|
||||
if(bsdf) {
|
||||
|
|
|
@ -53,6 +53,7 @@ static ustring u_gaussian("gaussian");
|
|||
static ustring u_burley("burley");
|
||||
static ustring u_principled("principled");
|
||||
static ustring u_random_walk("random_walk");
|
||||
static ustring u_principled_random_walk("principled_random_walk");
|
||||
|
||||
class CBSSRDFClosure : public CClosurePrimitive {
|
||||
public:
|
||||
|
@ -83,6 +84,9 @@ public:
|
|||
else if (method == u_random_walk) {
|
||||
alloc(sd, path_flag, weight, CLOSURE_BSSRDF_RANDOM_WALK_ID);
|
||||
}
|
||||
else if (method == u_principled_random_walk) {
|
||||
alloc(sd, path_flag, weight, CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID);
|
||||
}
|
||||
}
|
||||
|
||||
void alloc(ShaderData *sd, int path_flag, float3 weight, ClosureType type)
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
shader node_principled_bsdf(
|
||||
string distribution = "Multiscatter GGX",
|
||||
string subsurface_method = "burley",
|
||||
color BaseColor = color(0.8, 0.8, 0.8),
|
||||
float Subsurface = 0.0,
|
||||
vector SubsurfaceRadius = vector(1.0, 1.0, 1.0),
|
||||
|
@ -58,8 +59,14 @@ shader node_principled_bsdf(
|
|||
if (diffuse_weight > 1e-5) {
|
||||
if (Subsurface > 1e-5) {
|
||||
color mixed_ss_base_color = SubsurfaceColor * Subsurface + BaseColor * (1.0 - Subsurface);
|
||||
BSDF = mixed_ss_base_color * bssrdf("principled", Normal, Subsurface * SubsurfaceRadius, SubsurfaceColor, "roughness", Roughness);
|
||||
} else {
|
||||
if (subsurface_method == "burley") {
|
||||
BSDF = mixed_ss_base_color * bssrdf("principled", Normal, Subsurface * SubsurfaceRadius, SubsurfaceColor, "roughness", Roughness);
|
||||
}
|
||||
else {
|
||||
BSDF = mixed_ss_base_color * bssrdf("principled_random_walk", Normal, Subsurface * SubsurfaceRadius, SubsurfaceColor, "roughness", Roughness);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BSDF = BaseColor * principled_diffuse(Normal, Roughness);
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,8 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
|||
float transmission_roughness = stack_load_float(stack, transmission_roughness_offset);
|
||||
float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
|
||||
|
||||
ClosureType distribution = stack_valid(data_node2.y) ? (ClosureType) data_node2.y : CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
|
||||
ClosureType distribution = (ClosureType) data_node2.y;
|
||||
ClosureType subsurface_method = (ClosureType) data_node2.z;
|
||||
|
||||
/* rotate tangent */
|
||||
if(anisotropic_rotation != 0.0f)
|
||||
|
@ -193,7 +194,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
|||
bssrdf->roughness = roughness;
|
||||
|
||||
/* setup bsdf */
|
||||
sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)CLOSURE_BSSRDF_PRINCIPLED_ID);
|
||||
sd->flag |= bssrdf_setup(sd, bssrdf, subsurface_method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -781,6 +782,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *
|
|||
bssrdf->texture_blur = param2;
|
||||
bssrdf->sharpness = stack_load_float(stack, data_node.w);
|
||||
bssrdf->N = N;
|
||||
bssrdf->roughness = 0.0f;
|
||||
sd->flag |= bssrdf_setup(sd, bssrdf, (ClosureType)type);
|
||||
}
|
||||
|
||||
|
|
|
@ -447,6 +447,7 @@ typedef enum ClosureType {
|
|||
CLOSURE_BSSRDF_PRINCIPLED_ID,
|
||||
CLOSURE_BSSRDF_BURLEY_ID,
|
||||
CLOSURE_BSSRDF_RANDOM_WALK_ID,
|
||||
CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID,
|
||||
|
||||
/* Other */
|
||||
CLOSURE_HOLDOUT_ID,
|
||||
|
@ -478,8 +479,8 @@ typedef enum ClosureType {
|
|||
#define CLOSURE_IS_BSDF_MICROFACET(type) ((type >= CLOSURE_BSDF_MICROFACET_GGX_ID && type <= CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID) ||\
|
||||
(type >= CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID && type <= CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID) ||\
|
||||
(type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID))
|
||||
#define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_RANDOM_WALK_ID)
|
||||
#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_RANDOM_WALK_ID)
|
||||
#define CLOSURE_IS_BSDF_OR_BSSRDF(type) (type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
|
||||
#define CLOSURE_IS_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID)
|
||||
#define CLOSURE_IS_DISK_BSSRDF(type) (type >= CLOSURE_BSSRDF_CUBIC_ID && type <= CLOSURE_BSSRDF_BURLEY_ID)
|
||||
#define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
|
||||
#define CLOSURE_IS_VOLUME_SCATTER(type) (type == CLOSURE_VOLUME_HENYEY_GREENSTEIN_ID)
|
||||
|
|
|
@ -2312,6 +2312,12 @@ NODE_DEFINE(PrincipledBsdfNode)
|
|||
distribution_enum.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
|
||||
distribution_enum.insert("Multiscatter GGX", CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
|
||||
SOCKET_ENUM(distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID);
|
||||
|
||||
static NodeEnum subsurface_method_enum;
|
||||
subsurface_method_enum.insert("burley", CLOSURE_BSSRDF_PRINCIPLED_ID);
|
||||
subsurface_method_enum.insert("random_walk", CLOSURE_BSSRDF_PRINCIPLED_RANDOM_WALK_ID);
|
||||
SOCKET_ENUM(subsurface_method, "Subsurface Method", subsurface_method_enum, CLOSURE_BSSRDF_PRINCIPLED_ID);
|
||||
|
||||
SOCKET_IN_COLOR(base_color, "Base Color", make_float3(0.8f, 0.8f, 0.8f));
|
||||
SOCKET_IN_COLOR(subsurface_color, "Subsurface Color", make_float3(0.8f, 0.8f, 0.8f));
|
||||
SOCKET_IN_FLOAT(metallic, "Metallic", 0.0f);
|
||||
|
@ -2410,7 +2416,7 @@ void PrincipledBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic,
|
|||
compiler.encode_uchar4(sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset));
|
||||
|
||||
compiler.add_node(compiler.encode_uchar4(ior_offset, transmission_offset, anisotropic_rotation_offset, transmission_roughness_offset),
|
||||
distribution, SVM_STACK_INVALID, SVM_STACK_INVALID);
|
||||
distribution, subsurface_method, SVM_STACK_INVALID);
|
||||
|
||||
float3 bc_default = get_float3(base_color_in->socket_type);
|
||||
|
||||
|
@ -2442,6 +2448,7 @@ void PrincipledBsdfNode::compile(SVMCompiler& compiler)
|
|||
void PrincipledBsdfNode::compile(OSLCompiler& compiler)
|
||||
{
|
||||
compiler.parameter(this, "distribution");
|
||||
compiler.parameter(this, "subsurface_method");
|
||||
compiler.add(this, "node_principled_bsdf");
|
||||
}
|
||||
|
||||
|
|
|
@ -390,6 +390,7 @@ public:
|
|||
float3 normal, clearcoat_normal, tangent;
|
||||
float surface_mix_weight;
|
||||
ClosureType distribution, distribution_orig;
|
||||
ClosureType subsurface_method;
|
||||
|
||||
bool has_integrator_dependency();
|
||||
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
||||
|
|
|
@ -1082,6 +1082,12 @@ static void node_shader_buts_glossy(uiLayout *layout, bContext *UNUSED(C), Point
|
|||
uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_shader_buts_principled(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
|
||||
uiItemR(layout, ptr, "subsurface_method", 0, "", ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_shader_buts_anisotropic(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "distribution", 0, "", ICON_NONE);
|
||||
|
@ -1254,9 +1260,11 @@ static void node_shader_set_butfunc(bNodeType *ntype)
|
|||
case SH_NODE_BSDF_GLOSSY:
|
||||
case SH_NODE_BSDF_GLASS:
|
||||
case SH_NODE_BSDF_REFRACTION:
|
||||
case SH_NODE_BSDF_PRINCIPLED:
|
||||
ntype->draw_buttons = node_shader_buts_glossy;
|
||||
break;
|
||||
case SH_NODE_BSDF_PRINCIPLED:
|
||||
ntype->draw_buttons = node_shader_buts_principled;
|
||||
break;
|
||||
case SH_NODE_BSDF_ANISOTROPIC:
|
||||
ntype->draw_buttons = node_shader_buts_anisotropic;
|
||||
break;
|
||||
|
|
|
@ -3293,11 +3293,18 @@ static const EnumPropertyItem node_script_mode_items[] = {
|
|||
};
|
||||
|
||||
static const EnumPropertyItem node_principled_distribution_items[] = {
|
||||
{ SHD_GLOSSY_GGX, "GGX", 0, "GGX", "" },
|
||||
{ SHD_GLOSSY_MULTI_GGX, "MULTI_GGX", 0, "Multiscatter GGX", "" },
|
||||
{SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""},
|
||||
{SHD_GLOSSY_MULTI_GGX, "MULTI_GGX", 0, "Multiscatter GGX", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static const EnumPropertyItem node_subsurface_method_items[] = {
|
||||
{SHD_SUBSURFACE_BURLEY, "BURLEY", 0, "Christensen-Burley", "Approximation to physically based volume scattering"},
|
||||
{SHD_SUBSURFACE_RANDOM_WALK, "RANDOM_WALK", 0, "Random Walk", "Volumetric approximation to physically based volume scattering"},
|
||||
{ 0, NULL, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
/* -- Common nodes ---------------------------------------------------------- */
|
||||
|
||||
static void def_group_input(StructRNA *srna)
|
||||
|
@ -4241,6 +4248,12 @@ static void def_principled(StructRNA *srna)
|
|||
RNA_def_property_enum_items(prop, node_principled_distribution_items);
|
||||
RNA_def_property_ui_text(prop, "Distribution", "");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodePrincipled_update");
|
||||
|
||||
prop = RNA_def_property(srna, "subsurface_method", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "custom2");
|
||||
RNA_def_property_enum_items(prop, node_subsurface_method_items);
|
||||
RNA_def_property_ui_text(prop, "Subsurface Method", "Method for rendering subsurface scattering");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodePrincipled_update");
|
||||
}
|
||||
|
||||
static void def_refraction(StructRNA *srna)
|
||||
|
|
|
@ -61,6 +61,7 @@ static bNodeSocketTemplate sh_node_bsdf_principled_out[] = {
|
|||
static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node)
|
||||
{
|
||||
node->custom1 = SHD_GLOSSY_MULTI_GGX;
|
||||
node->custom2 = SHD_SUBSURFACE_BURLEY;
|
||||
}
|
||||
|
||||
static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
|
||||
|
|
Loading…
Reference in New Issue