forked from bartvdbraak/blender
Cycles: add a sharpness input to the Cubic SSS falloff. When set to 1 this will
give a result more similar to the Compatible falloff option. The scale is x2 though to keep the perceived scatter radius roughly the same while changing the sharpness. Difference with compatible will be mainly on non-flat geometry.
This commit is contained in:
parent
9467d99405
commit
b314209356
@ -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;
|
||||
|
||||
return (f3 * 10.0f) / (Rm5 * M_PI_F);
|
||||
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);
|
||||
|
||||
}
|
||||
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 */
|
||||
|
@ -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
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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, ¶m1_offset, ¶m2_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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user