From d93f680db9acaaade0354b34857a3ccaf348557f Mon Sep 17 00:00:00 2001 From: Pascal Schoen Date: Mon, 24 Oct 2016 09:14:51 +0200 Subject: Added subsurface radius parameter to control the per color channel effection radius of the subsurface scattering. --- intern/cycles/kernel/shaders/node_disney_bsdf.osl | 3 ++- intern/cycles/kernel/svm/svm_closure.h | 9 +++++---- intern/cycles/render/nodes.cpp | 10 ++++++---- intern/cycles/render/nodes.h | 4 ++-- source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c | 1 + 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/intern/cycles/kernel/shaders/node_disney_bsdf.osl b/intern/cycles/kernel/shaders/node_disney_bsdf.osl index 00c60085aa6..b4a9722c1a5 100644 --- a/intern/cycles/kernel/shaders/node_disney_bsdf.osl +++ b/intern/cycles/kernel/shaders/node_disney_bsdf.osl @@ -21,6 +21,7 @@ shader node_disney_bsdf( string distribution = "Multiscatter GGX", color BaseColor = color(0.8, 0.8, 0.8), float Subsurface = 0.0, + vector SubsurfaceRadius = vector(1.0, 1.0, 1.0), color SubsurfaceColor = color(0.7, 0.1, 0.1), float Metallic = 0.0, float Specular = 0.5, @@ -53,7 +54,7 @@ shader node_disney_bsdf( if (diffuse_weight > 1e-5) { if (Subsurface > 1e-5) { - BSDF = bssrdf_disney(Normal, vector(Subsurface, Subsurface, Subsurface), 0.0, BaseColor, SubsurfaceColor, Roughness); + BSDF = bssrdf_disney(Normal, Subsurface * SubsurfaceRadius, 0.0, BaseColor, SubsurfaceColor, Roughness); } else { BSDF = disney_diffuse(Normal, BaseColor, Roughness); } diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h index 93fe99c0583..a9ba922f85e 100644 --- a/intern/cycles/kernel/svm/svm_closure.h +++ b/intern/cycles/kernel/svm/svm_closure.h @@ -127,9 +127,10 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * float3 base_color = stack_valid(data_base_color.x) ? stack_load_float3(stack, data_base_color.x) : make_float3(__uint_as_float(data_base_color.y), __uint_as_float(data_base_color.z), __uint_as_float(data_base_color.w)); - // get the additional clearcoat normal - uint4 data_clearcoat_normal = read_node(kg, offset); - float3 CN = stack_valid(data_clearcoat_normal.x) ? stack_load_float3(stack, data_clearcoat_normal.x) : ccl_fetch(sd, N); + // get the additional clearcoat normal and subsurface scattering radius + uint4 data_cn_ssr = read_node(kg, offset); + float3 CN = stack_valid(data_cn_ssr.x) ? stack_load_float3(stack, data_cn_ssr.x) : ccl_fetch(sd, N); + float3 subsurface_radius = stack_valid(data_cn_ssr.y) ? stack_load_float3(stack, data_cn_ssr.y) : make_float3(1.0f, 1.0f, 1.0f); // get the subsurface color uint4 data_subsurface_color = read_node(kg, offset); @@ -168,7 +169,7 @@ ccl_device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float * } else if(subsurf_sample_weight > CLOSURE_WEIGHT_CUTOFF) { /* radius * scale */ - float3 radius = make_float3(1.0f, 1.0f, 1.0f) * subsurface; + float3 radius = subsurface_radius * subsurface; /* sharpness */ float sharpness = 0.0f; /* texture color blur */ diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp index f67413e4f2c..cefb1a1dd0c 100644 --- a/intern/cycles/render/nodes.cpp +++ b/intern/cycles/render/nodes.cpp @@ -2233,6 +2233,7 @@ NODE_DEFINE(DisneyBsdfNode) SOCKET_IN_COLOR(subsurface_color, "Subsurface Color", make_float3(0.8f, 0.8f, 0.8f)); SOCKET_IN_FLOAT(metallic, "Metallic", 0.0f); SOCKET_IN_FLOAT(subsurface, "Subsurface", 0.0f); + SOCKET_IN_VECTOR(subsurface_radius, "Subsurface Radius", make_float3(0.1f, 0.1f, 0.1f)); SOCKET_IN_FLOAT(specular, "Specular", 0.0f); SOCKET_IN_FLOAT(roughness, "Roughness", 0.0f); SOCKET_IN_FLOAT(specular_tint, "Specular Tint", 0.0f); @@ -2264,7 +2265,7 @@ DisneyBsdfNode::DisneyBsdfNode() distribution_orig = NBUILTIN_CLOSURES; } -void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic, ShaderInput *p_subsurface, +void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic, ShaderInput *p_subsurface, ShaderInput *p_subsurface_radius, ShaderInput *p_specular, ShaderInput *p_roughness, ShaderInput *p_specular_tint, ShaderInput *p_anisotropic, ShaderInput *p_sheen, ShaderInput *p_sheen_tint, ShaderInput *p_clearcoat, ShaderInput *p_clearcoat_gloss, ShaderInput *p_ior, ShaderInput *p_transparency, ShaderInput *p_anisotropic_rotation, ShaderInput *p_refraction_roughness) @@ -2294,6 +2295,7 @@ void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic, Sha int transparency_offset = compiler.stack_assign(p_transparency); int refraction_roughness_offset = compiler.stack_assign(p_refraction_roughness); int anisotropic_rotation_offset = compiler.stack_assign(p_anisotropic_rotation); + int subsurface_radius_offset = compiler.stack_assign(p_subsurface_radius); compiler.add_node(NODE_CLOSURE_BSDF, compiler.encode_uchar4(closure, @@ -2315,7 +2317,7 @@ void DisneyBsdfNode::compile(SVMCompiler& compiler, ShaderInput *p_metallic, Sha compiler.add_node(((base_color_in->link) ? compiler.stack_assign(base_color_in) : SVM_STACK_INVALID), __float_as_int(bc_default.x), __float_as_int(bc_default.y), __float_as_int(bc_default.z)); - compiler.add_node(clearcoat_normal_offset, SVM_STACK_INVALID, SVM_STACK_INVALID, SVM_STACK_INVALID); + compiler.add_node(clearcoat_normal_offset, subsurface_radius_offset, SVM_STACK_INVALID, SVM_STACK_INVALID); float3 ss_default = get_float3(subsurface_color_in->socket_type); @@ -2331,8 +2333,8 @@ bool DisneyBsdfNode::has_integrator_dependency() void DisneyBsdfNode::compile(SVMCompiler& compiler) { - compile(compiler, input("Metallic"), input("Subsurface"), input("Specular"), input("Roughness"), - input("Specular Tint"), input("Anisotropic"), input("Sheen"), input("Sheen Tint"), + compile(compiler, input("Metallic"), input("Subsurface"), input("Subsurface Radius"), input("Specular"), + input("Roughness"), input("Specular Tint"), input("Anisotropic"), input("Sheen"), input("Sheen Tint"), input("Clearcoat"), input("Clearcoat Gloss"), input("IOR"), input("Transparency"), input("Anisotropic Rotation"), input("Refraction Roughness")); } diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h index b071900d8e3..dd43d8ca45d 100644 --- a/intern/cycles/render/nodes.h +++ b/intern/cycles/render/nodes.h @@ -369,13 +369,13 @@ public: bool has_spatial_varying() { return true; } bool has_surface_bssrdf() { return true; } bool has_bssrdf_bump(); - void compile(SVMCompiler& compiler, ShaderInput *metallic, ShaderInput *subsurface, + void compile(SVMCompiler& compiler, ShaderInput *metallic, ShaderInput *subsurface, ShaderInput *subsurface_radius, ShaderInput *specular, ShaderInput *roughness, ShaderInput *specular_tint, ShaderInput *anisotropic, ShaderInput *sheen, ShaderInput *sheen_tint, ShaderInput *clearcoat, ShaderInput *clearcoat_gloss, ShaderInput *ior, ShaderInput *transparency, ShaderInput *anisotropic_rotation, ShaderInput *refraction_roughness); float3 base_color; - float3 subsurface_color; + float3 subsurface_color, subsurface_radius; float metallic, subsurface, specular, roughness, specular_tint, anisotropic, sheen, sheen_tint, clearcoat, clearcoat_gloss, ior, transparency, anisotropic_rotation, refraction_roughness; diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c index adb82cca7b5..0157173becd 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_disney.c @@ -32,6 +32,7 @@ static bNodeSocketTemplate sh_node_bsdf_disney_in[] = { { SOCK_RGBA, 1, N_("Base Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Subsurface"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, + { SOCK_VECTOR, 1, N_("Subsurface Radius"), 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f}, { SOCK_RGBA, 1, N_("Subsurface Color"), 0.7f, 0.1f, 0.1f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Metallic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, { SOCK_FLOAT, 1, N_("Specular"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR}, -- cgit v1.2.3