Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/cycles/kernel/closure/bssrdf.h62
-rw-r--r--intern/cycles/kernel/osl/osl_bssrdf.cpp31
-rw-r--r--intern/cycles/kernel/osl/osl_bssrdf.h2
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp4
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h2
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp1
-rw-r--r--intern/cycles/kernel/shaders/node_subsurface_scattering.osl9
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h7
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h15
-rw-r--r--intern/cycles/render/nodes.cpp17
-rw-r--r--intern/cycles/render/nodes.h2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl2
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c11
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c36
14 files changed, 161 insertions, 40 deletions
diff --git a/intern/cycles/kernel/closure/bssrdf.h b/intern/cycles/kernel/closure/bssrdf.h
index d6f889f3285..4ceff655dd5 100644
--- a/intern/cycles/kernel/closure/bssrdf.h
+++ b/intern/cycles/kernel/closure/bssrdf.h
@@ -31,6 +31,7 @@ __device int bssrdf_setup(ShaderClosure *sc, ClosureType type)
}
else {
sc->data1 = clamp(sc->data1, 0.0f, 1.0f); /* texture blur */
+ sc->T.x = clamp(sc->T.x, 0.0f, 1.0f); /* sharpness */
sc->type = type;
return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSSRDF;
@@ -95,17 +96,49 @@ __device void bssrdf_gaussian_sample(ShaderClosure *sc, float xi, float *r, floa
__device float bssrdf_cubic_eval(ShaderClosure *sc, float r)
{
- const float Rm = sc->data0;
+ const float sharpness = sc->T.x;
- if(r >= Rm)
- return 0.0f;
-
- /* integrate (2*pi*r * 10*(R - r)^3)/(pi * R^5) from 0 to R = 1 */
- const float Rm5 = (Rm*Rm) * (Rm*Rm) * Rm;
- const float f = Rm - min(r, Rm);
- const float f3 = f*f*f;
+ if(sharpness == 0.0f) {
+ const float Rm = sc->data0;
+
+ if(r >= Rm)
+ return 0.0f;
+
+ /* integrate (2*pi*r * 10*(R - r)^3)/(pi * R^5) from 0 to R = 1 */
+ const float Rm5 = (Rm*Rm) * (Rm*Rm) * Rm;
+ const float f = Rm - r;
+ const float num = f*f*f;
+
+ return (10.0f * num) / (Rm5 * M_PI_F);
- return (f3 * 10.0f) / (Rm5 * M_PI_F);
+ }
+ else {
+ float Rm = sc->data0*(1.0f + sharpness);
+
+ if(r >= Rm)
+ return 0.0f;
+
+ /* custom variation with extra sharpness, to match the previous code */
+ const float y = 1.0f/(1.0f + sharpness);
+ float Rmy, ry, ryinv;
+
+ if(sharpness == 1.0f) {
+ Rmy = sqrtf(Rm);
+ ry = sqrtf(r);
+ ryinv = (ry > 0.0f)? 1.0f/ry: 0.0f;
+ }
+ else {
+ Rmy = powf(Rm, y);
+ ry = powf(r, y);
+ ryinv = (r > 0.0f)? powf(r, 2.0f*y - 2.0f): 0.0f;
+ }
+
+ const float Rmy5 = (Rmy*Rmy) * (Rmy*Rmy) * Rmy;
+ const float f = Rmy - ry;
+ const float num = f*(f*f)*(y*ryinv);
+
+ return (10.0f * num) / (Rmy5 * M_PI_F);
+ }
}
__device float bssrdf_cubic_pdf(ShaderClosure *sc, float r)
@@ -143,9 +176,16 @@ __device float bssrdf_cubic_quintic_root_find(float xi)
__device void bssrdf_cubic_sample(ShaderClosure *sc, float xi, float *r, float *h)
{
- const float Rm = sc->data0;
- const float r_ = bssrdf_cubic_quintic_root_find(xi) * Rm;
+ float Rm = sc->data0;
+ float r_ = bssrdf_cubic_quintic_root_find(xi);
+ const float sharpness = sc->T.x;
+ if(sharpness != 0.0f) {
+ r_ = powf(r_, 1.0f + sharpness);
+ Rm *= (1.0f + sharpness);
+ }
+
+ r_ *= Rm;
*r = r_;
/* h^2 + r^2 = Rm^2 */
diff --git a/intern/cycles/kernel/osl/osl_bssrdf.cpp b/intern/cycles/kernel/osl/osl_bssrdf.cpp
index 7405b0be567..975967c0bbb 100644
--- a/intern/cycles/kernel/osl/osl_bssrdf.cpp
+++ b/intern/cycles/kernel/osl/osl_bssrdf.cpp
@@ -56,10 +56,8 @@ public:
void setup()
{
- sc.type = CLOSURE_BSSRDF_COMPATIBLE_ID;
- sc.prim = NULL;
+ sc.type = CLOSURE_BSSRDF_CUBIC_ID;
sc.data0 = fabsf(average(radius));
- sc.data1 = 0.0f; // XXX texture blur
}
bool mergeable(const ClosurePrimitive *other) const
@@ -85,6 +83,19 @@ ClosureParam *closure_bssrdf_cubic_params()
return params;
}
+ClosureParam *closure_bssrdf_cubic_extended_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, sc.N),
+ CLOSURE_FLOAT3_PARAM(CubicBSSRDFClosure, radius),
+ CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.data1),
+ CLOSURE_FLOAT_PARAM(CubicBSSRDFClosure, sc.T.x),
+ CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_FINISH_PARAM(CubicBSSRDFClosure)
+ };
+ return params;
+}
+
CLOSURE_PREPARE(closure_bssrdf_cubic_prepare, CubicBSSRDFClosure)
/* Gaussian */
@@ -97,9 +108,7 @@ public:
void setup()
{
sc.type = CLOSURE_BSSRDF_GAUSSIAN_ID;
- sc.prim = NULL;
sc.data0 = fabsf(average(radius));
- sc.data1 = 0.0f; // XXX texture blurring!
}
bool mergeable(const ClosurePrimitive *other) const
@@ -125,6 +134,18 @@ ClosureParam *closure_bssrdf_gaussian_params()
return params;
}
+ClosureParam *closure_bssrdf_gaussian_extended_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, sc.N),
+ CLOSURE_FLOAT3_PARAM(GaussianBSSRDFClosure, radius),
+ CLOSURE_FLOAT_PARAM(GaussianBSSRDFClosure, sc.data1),
+ CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_FINISH_PARAM(GaussianBSSRDFClosure)
+ };
+ return params;
+}
+
CLOSURE_PREPARE(closure_bssrdf_gaussian_prepare, GaussianBSSRDFClosure)
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_bssrdf.h b/intern/cycles/kernel/osl/osl_bssrdf.h
index ee9fc7c4ac5..fc1a4c587cc 100644
--- a/intern/cycles/kernel/osl/osl_bssrdf.h
+++ b/intern/cycles/kernel/osl/osl_bssrdf.h
@@ -48,7 +48,7 @@ public:
ShaderClosure sc;
float3 radius;
- CBSSRDFClosure() : OSL::ClosurePrimitive(BSSRDF) { }
+ CBSSRDFClosure() : OSL::ClosurePrimitive(BSSRDF) { memset(&sc, 0, sizeof(sc)); }
~CBSSRDFClosure() { }
int scattering() const { return LABEL_DIFFUSE; }
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index c03e50d4313..6a3f27fb7b1 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -221,6 +221,10 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
closure_bssrdf_cubic_params(), closure_bssrdf_cubic_prepare);
register_closure(ss, "bssrdf_gaussian", id++,
closure_bssrdf_gaussian_params(), closure_bssrdf_gaussian_prepare);
+ register_closure(ss, "bssrdf_cubic", id++,
+ closure_bssrdf_cubic_extended_params(), closure_bssrdf_cubic_prepare);
+ register_closure(ss, "bssrdf_gaussian", id++,
+ closure_bssrdf_gaussian_extended_params(), closure_bssrdf_gaussian_prepare);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index e3a7e890597..6632c2c57e5 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -52,6 +52,8 @@ OSL::ClosureParam *closure_westin_backscatter_params();
OSL::ClosureParam *closure_westin_sheen_params();
OSL::ClosureParam *closure_bssrdf_cubic_params();
OSL::ClosureParam *closure_bssrdf_gaussian_params();
+OSL::ClosureParam *closure_bssrdf_cubic_extended_params();
+OSL::ClosureParam *closure_bssrdf_gaussian_extended_params();
void closure_emission_prepare(OSL::RendererServices *, int id, void *data);
void closure_background_prepare(OSL::RendererServices *, int id, void *data);
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index c55f36bcc9d..d2ccb7da84c 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -239,6 +239,7 @@ static void flatten_surface_closure_tree(ShaderData *sd, int path_flag,
sc.type = bssrdf->sc.type;
sc.N = bssrdf->sc.N;
sc.data1 = bssrdf->sc.data1;
+ sc.T.x = bssrdf->sc.T.x;
sc.prim = NULL;
/* disable in case of diffuse ancestor, can't see it well then and
diff --git a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
index 18864118172..5c1d1be0ee7 100644
--- a/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
+++ b/intern/cycles/kernel/shaders/node_subsurface_scattering.osl
@@ -20,14 +20,15 @@ shader node_subsurface_scattering(
color Color = 0.8,
float Scale = 1.0,
vector Radius = vector(0.1, 0.1, 0.1),
- float TextureBlur = 0.0, // XXX use
+ float TextureBlur = 0.0,
+ float Sharpness = 0.0,
string Falloff = "Cubic",
normal Normal = N,
output closure color BSSRDF = 0)
{
if(Falloff == "Gaussian")
- BSSRDF = Color * bssrdf_gaussian(N, Scale * Radius);
- else /* Cubic, hardcoded to compatible closure for now */
- BSSRDF = Color * bssrdf_cubic(N, Scale * Radius);
+ BSSRDF = Color * bssrdf_gaussian(N, Scale * Radius, TextureBlur);
+ else
+ BSSRDF = Color * bssrdf_cubic(N, Scale * Radius, TextureBlur, Sharpness);
}
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index 7d1c2443ee7..3ad2bbc0588 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -465,11 +465,12 @@ closure color holdout() BUILTIN;
closure color ambient_occlusion() BUILTIN;
// BSSRDF
-closure color bssrdf_cubic(normal N, vector radius) BUILTIN;
-closure color bssrdf_gaussian(normal N, vector radius) BUILTIN;
+closure color bssrdf_cubic(normal N, vector radius, float texture_blur, float sharpness) BUILTIN;
+closure color bssrdf_gaussian(normal N, vector radius, float texture_blur) BUILTIN;
// Backwards compatibility
-
+closure color bssrdf_cubic(normal N, vector radius) BUILTIN;
+closure color bssrdf_gaussian(normal N, vector radius) BUILTIN;
closure color specular_toon(normal N, float size, float smooth) BUILTIN;
// Renderer state
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 42d98092b41..9a9aefa5b29 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -108,13 +108,13 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
if(mix_weight == 0.0f)
return;
- float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N;
+ float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N;
#else
decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, NULL);
float mix_weight = 1.0f;
uint4 data_node = read_node(kg, offset);
- float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N;
+ float3 N = stack_valid(data_node.x)? stack_load_float3(stack, data_node.x): sd->N;
#endif
float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __uint_as_float(node.z);
@@ -279,10 +279,10 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
sc->N = N;
#ifdef __ANISOTROPIC__
- sc->T = stack_load_float3(stack, data_node.z);
+ sc->T = stack_load_float3(stack, data_node.y);
/* rotate tangent */
- float rotation = stack_load_float(stack, data_node.w);
+ float rotation = stack_load_float(stack, data_node.z);
if(rotation != 0.0f)
sc->T = rotate_around_axis(sc->T, sc->N, rotation * M_2PI_F);
@@ -353,7 +353,9 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
if(sample_weight > 1e-5f && sd->num_closure+2 < MAX_CLOSURE) {
/* radius * scale */
- float3 radius = stack_load_float3(stack, data_node.w)*param1;
+ float3 radius = stack_load_float3(stack, data_node.z)*param1;
+ /* sharpness */
+ float sharpness = stack_load_float(stack, data_node.w);
/* texture color blur */
float texture_blur = param2;
@@ -363,6 +365,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
sc->sample_weight = sample_weight;
sc->data0 = radius.x;
sc->data1 = texture_blur;
+ sc->T.x = sharpness;
#ifdef __OSL__
sc->prim = NULL;
#endif
@@ -378,6 +381,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
sc->sample_weight = sample_weight;
sc->data0 = radius.y;
sc->data1 = texture_blur;
+ sc->T.x = sharpness;
#ifdef __OSL__
sc->prim = NULL;
#endif
@@ -393,6 +397,7 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
sc->sample_weight = sample_weight;
sc->data0 = radius.z;
sc->data1 = texture_blur;
+ sc->T.x = sharpness;
#ifdef __OSL__
sc->prim = NULL;
#endif
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index a9c17c8bcd5..06acb9e749e 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1375,7 +1375,7 @@ BsdfNode::BsdfNode(bool scattering_)
}
}
-void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3)
+void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3, ShaderInput *param4)
{
ShaderInput *color_in = input("Color");
ShaderInput *normal_in = input("Normal");
@@ -1394,6 +1394,8 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *
compiler.stack_assign(param2);
if(param3)
compiler.stack_assign(param3);
+ if(param4)
+ compiler.stack_assign(param4);
if(normal_in->link)
compiler.stack_assign(normal_in);
@@ -1410,12 +1412,14 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *
__float_as_int((param2)? param2->value.x: 0.0f));
if(tangent_in) {
- compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset, tangent_in->stack_offset,
- (param3)? param3->stack_offset: SVM_STACK_INVALID);
+ compiler.add_node(normal_in->stack_offset, tangent_in->stack_offset,
+ (param3)? param3->stack_offset: SVM_STACK_INVALID,
+ (param4)? param4->stack_offset: SVM_STACK_INVALID);
}
else {
- compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset, SVM_STACK_INVALID,
- (param3)? param3->stack_offset: SVM_STACK_INVALID);
+ compiler.add_node(normal_in->stack_offset, SVM_STACK_INVALID,
+ (param3)? param3->stack_offset: SVM_STACK_INVALID,
+ (param4)? param4->stack_offset: SVM_STACK_INVALID);
}
}
@@ -1707,12 +1711,13 @@ SubsurfaceScatteringNode::SubsurfaceScatteringNode()
add_input("Scale", SHADER_SOCKET_FLOAT, 0.01f);
add_input("Radius", SHADER_SOCKET_VECTOR, make_float3(0.1f, 0.1f, 0.1f));
+ add_input("Sharpness", SHADER_SOCKET_FLOAT, 0.0f);
add_input("Texture Blur", SHADER_SOCKET_FLOAT, 1.0f);
}
void SubsurfaceScatteringNode::compile(SVMCompiler& compiler)
{
- BsdfNode::compile(compiler, input("Scale"), input("Texture Blur"), input("Radius"));
+ BsdfNode::compile(compiler, input("Scale"), input("Texture Blur"), input("Radius"), input("Sharpness"));
}
void SubsurfaceScatteringNode::compile(OSLCompiler& compiler)
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index 1a2494d96ea..50338ddd5c0 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -203,7 +203,7 @@ public:
BsdfNode(bool scattering = false);
SHADER_NODE_BASE_CLASS(BsdfNode);
- void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL);
+ void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL, ShaderInput *param4 = NULL);
ClosureType closure;
bool scattering;
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 2aee5b4846a..644cf71d626 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -2087,7 +2087,7 @@ void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out vec4 result)
node_bsdf_diffuse(color, 0.0, N, result);
}
-void node_subsurface_scattering(vec4 color, float roughness, vec3 N, out vec4 result)
+void node_subsurface_scattering(vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, out vec4 result)
{
node_bsdf_diffuse(color, 0.0, N, result);
}
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 819d2613f29..eb18f791b04 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -2819,6 +2819,15 @@ static void rna_ShaderNodeScript_update(Main *bmain, Scene *scene, PointerRNA *p
ED_node_tag_update_nodetree(bmain, ntree);
}
+static void rna_ShaderNodeSubsurface_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+ bNode *node = (bNode *)ptr->data;
+
+ nodeUpdate(ntree, node);
+ rna_Node_update(bmain, scene, ptr);
+}
+
#else
static EnumPropertyItem prop_image_layer_items[] = {
@@ -3642,7 +3651,7 @@ static void def_sh_subsurface(StructRNA *srna)
RNA_def_property_enum_sdna(prop, NULL, "custom1");
RNA_def_property_enum_items(prop, prop_subsurface_falloff_items);
RNA_def_property_ui_text(prop, "Falloff", "Function to determine how much light nearby points contribute based on their distance to the shading point");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodeSubsurface_update");
}
static void def_sh_script(StructRNA *srna)
diff --git a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
index 8ad529d192e..fd864f1c7c6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
+++ b/source/blender/nodes/shader/nodes/node_shader_subsurface_scattering.c
@@ -33,7 +33,8 @@ static bNodeSocketTemplate sh_node_subsurface_scattering_in[] = {
{ SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
{ SOCK_FLOAT, 1, N_("Scale"), 1.0, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
{ SOCK_VECTOR, 1, N_("Radius"), 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f},
- { SOCK_FLOAT, 1, N_("Texture Blur"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Sharpness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Texture Blur"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
{ SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
{ -1, 0, "" }
};
@@ -43,6 +44,20 @@ static bNodeSocketTemplate sh_node_subsurface_scattering_out[] = {
{ -1, 0, "" }
};
+static void node_shader_init_subsurface_scattering(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ /*bNodeSocket *sock;*/
+
+ node->custom1 = SHD_SUBSURFACE_CUBIC;
+
+ /*for (sock = node->inputs.first; sock; sock = sock->next) {
+ if (strcmp(sock->name, "Sharpness") == 0) {
+ bNodeSocketValueFloat *dval = sock->default_value;
+ dval->value = 0.0f;
+ }
+ }*/
+}
+
static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
if (!in[1].link)
@@ -51,6 +66,22 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat, bNode *UNUSED
return GPU_stack_link(mat, "node_subsurface_scattering", in, out);
}
+static void node_shader_update_subsurface_scattering(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ bNodeSocket *sock;
+ int falloff = node->custom1;
+
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ if (strcmp(sock->name, "Sharpness") == 0) {
+ if (falloff == SHD_SUBSURFACE_CUBIC)
+ sock->flag &= ~SOCK_UNAVAIL;
+ else
+ sock->flag |= SOCK_UNAVAIL;
+
+ }
+ }
+}
+
/* node type definition */
void register_node_type_sh_subsurface_scattering(void)
{
@@ -60,9 +91,10 @@ void register_node_type_sh_subsurface_scattering(void)
node_type_compatibility(&ntype, NODE_NEW_SHADING);
node_type_socket_templates(&ntype, sh_node_subsurface_scattering_in, sh_node_subsurface_scattering_out);
node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
- node_type_init(&ntype, NULL);
+ node_type_init(&ntype, node_shader_init_subsurface_scattering);
node_type_storage(&ntype, "", NULL, NULL);
node_type_gpu(&ntype, node_shader_gpu_subsurface_scattering);
+ node_type_update(&ntype, node_shader_update_subsurface_scattering, NULL);
nodeRegisterType(&ntype);
}