diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-02-08 18:19:04 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-02-09 21:58:42 +0300 |
commit | a6968e87f1338081f30725f8f2ca3460e280fea2 (patch) | |
tree | 0fdc61c15c86953fb431894871e7cf0a75dc5031 | |
parent | 0df9b2c71517a98760a5e577f434d9d86e4e1910 (diff) |
Cycles: add random walk subsurface scattering to Principled BSDF.
Differential Revision: https://developer.blender.org/D3054
-rw-r--r-- | intern/cycles/blender/addon/version_update.py | 7 | ||||
-rw-r--r-- | intern/cycles/blender/blender_shader.cpp | 8 | ||||
-rw-r--r-- | intern/cycles/kernel/closure/bssrdf.h | 7 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_subsurface.h | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/osl/osl_bssrdf.cpp | 4 | ||||
-rw-r--r-- | intern/cycles/kernel/shaders/node_principled_bsdf.osl | 11 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_closure.h | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/svm/svm_types.h | 5 | ||||
-rw-r--r-- | intern/cycles/render/nodes.cpp | 9 | ||||
-rw-r--r-- | intern/cycles/render/nodes.h | 1 | ||||
-rw-r--r-- | source/blender/editors/space_node/drawnode.c | 10 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nodetree.c | 17 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c | 1 |
13 files changed, 75 insertions, 15 deletions
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py index 400d6dac454..90cecec215d 100644 --- a/intern/cycles/blender/addon/version_update.py +++ b/intern/cycles/blender/addon/version_update.py @@ -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) diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp index d6f7a08431d..33384709947 100644 --- a/intern/cycles/blender/blender_shader.cpp +++ b/intern/cycles/blender/blender_shader.cpp @@ -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)) { diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h index 790368ee888..8578767b07e 100644 --- a/intern/cycles/kernel/closure/bssrdf.h +++ b/intern/cycles/kernel/closure/bssrdf.h @@ -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); } diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h index a0dba7e1386..80dda31c61e 100644 --- a/intern/cycles/kernel/kernel_subsurface.h +++ b/intern/cycles/kernel/kernel_subsurface.h @@ -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) { diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp index 907afe7d17a..da7368bbc61 100644 --- a/intern/cycles/kernel/osl/osl_bssrdf.cpp +++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp @@ -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) diff --git a/intern/cycles/kernel/shaders/node_principled_bsdf.osl b/intern/cycles/kernel/shaders/node_principled_bsdf.osl index 0e31dcedee4..fc0a1c894da 100644 --- a/intern/cycles/kernel/shaders/node_principled_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_principled_bsdf.osl @@ -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); } diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index f013dc396d0..fa43e1b60d0 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -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); } diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h index 9a87b4ee358..c0ce0f52cd0 100644 --- a/intern/cycles/kernel/svm/svm_types.h +++ b/intern/cycles/kernel/svm/svm_types.h @@ -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) diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index 7e8298e09c1..cb884ba9231 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -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"); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index a00b48ca5bc..f664ebf545d 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -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); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index eccf3c057d4..9d873795eaf 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -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; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index bbe78d43f50..ccd16e16760 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -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) diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c index e0330d110ca..cd83139dcaa 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c @@ -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) |