Shader: Add Roughness to Subsurface Scattering Node #114499
|
@ -8,6 +8,7 @@ shader node_subsurface_scattering(color Color = 0.8,
|
||||||
float Scale = 1.0,
|
float Scale = 1.0,
|
||||||
vector Radius = vector(0.1, 0.1, 0.1),
|
vector Radius = vector(0.1, 0.1, 0.1),
|
||||||
float IOR = 1.4,
|
float IOR = 1.4,
|
||||||
|
float Roughness = 1.0,
|
||||||
float Anisotropy = 0.0,
|
float Anisotropy = 0.0,
|
||||||
string method = "random_walk",
|
string method = "random_walk",
|
||||||
normal Normal = N,
|
normal Normal = N,
|
||||||
|
@ -23,5 +24,5 @@ shader node_subsurface_scattering(color Color = 0.8,
|
||||||
"anisotropy",
|
"anisotropy",
|
||||||
Anisotropy,
|
Anisotropy,
|
||||||
"roughness",
|
"roughness",
|
||||||
1.0);
|
clamp(Roughness, 0.0, 1.0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -872,7 +872,7 @@ ccl_device
|
||||||
bssrdf->albedo = closure_weight;
|
bssrdf->albedo = closure_weight;
|
||||||
bssrdf->N = maybe_ensure_valid_specular_reflection(sd, N);
|
bssrdf->N = maybe_ensure_valid_specular_reflection(sd, N);
|
||||||
bssrdf->ior = param2;
|
bssrdf->ior = param2;
|
||||||
bssrdf->alpha = 1.0f;
|
bssrdf->alpha = saturatef(stack_load_float(stack, data_node.w));
|
||||||
bssrdf->anisotropy = stack_load_float(stack, data_node.z);
|
bssrdf->anisotropy = stack_load_float(stack, data_node.z);
|
||||||
|
|
||||||
sd->flag |= bssrdf_setup(sd, bssrdf, path_flag, (ClosureType)type);
|
sd->flag |= bssrdf_setup(sd, bssrdf, path_flag, (ClosureType)type);
|
||||||
|
|
|
@ -2899,6 +2899,7 @@ NODE_DEFINE(SubsurfaceScatteringNode)
|
||||||
SOCKET_IN_VECTOR(radius, "Radius", make_float3(0.1f, 0.1f, 0.1f));
|
SOCKET_IN_VECTOR(radius, "Radius", make_float3(0.1f, 0.1f, 0.1f));
|
||||||
|
|
||||||
SOCKET_IN_FLOAT(subsurface_ior, "IOR", 1.4f);
|
SOCKET_IN_FLOAT(subsurface_ior, "IOR", 1.4f);
|
||||||
|
SOCKET_IN_FLOAT(subsurface_roughness, "Roughness", 1.0f);
|
||||||
SOCKET_IN_FLOAT(subsurface_anisotropy, "Anisotropy", 0.0f);
|
SOCKET_IN_FLOAT(subsurface_anisotropy, "Anisotropy", 0.0f);
|
||||||
|
|
||||||
SOCKET_OUT_CLOSURE(BSSRDF, "BSSRDF");
|
SOCKET_OUT_CLOSURE(BSSRDF, "BSSRDF");
|
||||||
|
@ -2914,7 +2915,12 @@ SubsurfaceScatteringNode::SubsurfaceScatteringNode() : BsdfNode(get_node_type())
|
||||||
void SubsurfaceScatteringNode::compile(SVMCompiler &compiler)
|
void SubsurfaceScatteringNode::compile(SVMCompiler &compiler)
|
||||||
{
|
{
|
||||||
closure = method;
|
closure = method;
|
||||||
BsdfNode::compile(compiler, input("Scale"), input("IOR"), input("Radius"), input("Anisotropy"));
|
BsdfNode::compile(compiler,
|
||||||
|
input("Scale"),
|
||||||
|
input("IOR"),
|
||||||
|
input("Radius"),
|
||||||
|
input("Anisotropy"),
|
||||||
|
input("Roughness"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubsurfaceScatteringNode::compile(OSLCompiler &compiler)
|
void SubsurfaceScatteringNode::compile(OSLCompiler &compiler)
|
||||||
|
|
|
@ -653,6 +653,7 @@ class SubsurfaceScatteringNode : public BsdfNode {
|
||||||
NODE_SOCKET_API(float, scale)
|
NODE_SOCKET_API(float, scale)
|
||||||
NODE_SOCKET_API(float3, radius)
|
NODE_SOCKET_API(float3, radius)
|
||||||
NODE_SOCKET_API(float, subsurface_ior)
|
NODE_SOCKET_API(float, subsurface_ior)
|
||||||
|
NODE_SOCKET_API(float, subsurface_roughness)
|
||||||
NODE_SOCKET_API(float, subsurface_anisotropy)
|
NODE_SOCKET_API(float, subsurface_anisotropy)
|
||||||
NODE_SOCKET_API(ClosureType, method)
|
NODE_SOCKET_API(ClosureType, method)
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
||||||
|
|
||||||
/* Blender file format version. */
|
/* Blender file format version. */
|
||||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||||
#define BLENDER_FILE_SUBVERSION 22
|
#define BLENDER_FILE_SUBVERSION 23
|
||||||
|
|
||||||
/* Minimum Blender version that supports reading file written with the current
|
/* Minimum Blender version that supports reading file written with the current
|
||||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||||
|
|
|
@ -534,6 +534,12 @@ void do_versions_after_linking_400(FileData *fd, Main *bmain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 23)) {
|
||||||
|
/* Shift animation data to accomidate the new Roughness input. */
|
||||||
|
version_node_socket_index_animdata(
|
||||||
|
bmain, NTREE_SHADER, SH_NODE_SUBSURFACE_SCATTERING, 4, 1, 5);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||||
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
||||||
|
|
|
@ -6,6 +6,7 @@ void node_subsurface_scattering(vec4 color,
|
||||||
float scale,
|
float scale,
|
||||||
vec3 radius,
|
vec3 radius,
|
||||||
float ior,
|
float ior,
|
||||||
|
float roughness,
|
||||||
float anisotropy,
|
float anisotropy,
|
||||||
vec3 N,
|
vec3 N,
|
||||||
float weight,
|
float weight,
|
||||||
|
@ -14,6 +15,7 @@ void node_subsurface_scattering(vec4 color,
|
||||||
{
|
{
|
||||||
color = max(color, vec4(0.0));
|
color = max(color, vec4(0.0));
|
||||||
ior = max(ior, 1e-5);
|
ior = max(ior, 1e-5);
|
||||||
|
/* roughness = saturate(roughness) */
|
||||||
N = safe_normalize(N);
|
N = safe_normalize(N);
|
||||||
|
|
||||||
ClosureSubsurface sss_data;
|
ClosureSubsurface sss_data;
|
||||||
|
|
|
@ -19,6 +19,11 @@ static void node_declare(NodeDeclarationBuilder &b)
|
||||||
b.add_input<decl::Float>("Scale").default_value(0.05f).min(0.0f).max(1000.0f);
|
b.add_input<decl::Float>("Scale").default_value(0.05f).min(0.0f).max(1000.0f);
|
||||||
b.add_input<decl::Vector>("Radius").default_value({1.0f, 0.2f, 0.1f}).min(0.0f).max(100.0f);
|
b.add_input<decl::Vector>("Radius").default_value({1.0f, 0.2f, 0.1f}).min(0.0f).max(100.0f);
|
||||||
b.add_input<decl::Float>("IOR").default_value(1.4f).min(1.01f).max(3.8f).subtype(PROP_FACTOR);
|
b.add_input<decl::Float>("IOR").default_value(1.4f).min(1.01f).max(3.8f).subtype(PROP_FACTOR);
|
||||||
|
b.add_input<decl::Float>("Roughness")
|
||||||
|
.default_value(1.0f)
|
||||||
|
.min(0.0f)
|
||||||
|
.max(1.0f)
|
||||||
|
.subtype(PROP_FACTOR);
|
||||||
b.add_input<decl::Float>("Anisotropy")
|
b.add_input<decl::Float>("Anisotropy")
|
||||||
.default_value(0.0f)
|
.default_value(0.0f)
|
||||||
.min(0.0f)
|
.min(0.0f)
|
||||||
|
@ -46,8 +51,8 @@ static int node_shader_gpu_subsurface_scattering(GPUMaterial *mat,
|
||||||
GPUNodeStack *in,
|
GPUNodeStack *in,
|
||||||
GPUNodeStack *out)
|
GPUNodeStack *out)
|
||||||
{
|
{
|
||||||
if (!in[5].link) {
|
if (!in[6].link) {
|
||||||
GPU_link(mat, "world_normals_get", &in[5].link);
|
GPU_link(mat, "world_normals_get", &in[6].link);
|
||||||
}
|
}
|
||||||
|
|
||||||
bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->runtime->original->inputs, 2);
|
bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->runtime->original->inputs, 2);
|
||||||
|
@ -70,6 +75,9 @@ static void node_shader_update_subsurface_scattering(bNodeTree *ntree, bNode *no
|
||||||
if (STR_ELEM(sock->name, "IOR", "Anisotropy")) {
|
if (STR_ELEM(sock->name, "IOR", "Anisotropy")) {
|
||||||
bke::nodeSetSocketAvailability(ntree, sock, sss_method != SHD_SUBSURFACE_BURLEY);
|
bke::nodeSetSocketAvailability(ntree, sock, sss_method != SHD_SUBSURFACE_BURLEY);
|
||||||
}
|
}
|
||||||
|
if (STR_ELEM(sock->name, "Roughness")) {
|
||||||
|
bke::nodeSetSocketAvailability(ntree, sock, sss_method == SHD_SUBSURFACE_RANDOM_WALK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue