Cycles: add distance-dependent transmission color in Principled BSDF #111806
|
@ -26,6 +26,7 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
|
|||
float ClearcoatRoughness = 0.03,
|
||||
float IOR = 1.45,
|
||||
float Transmission = 0.0,
|
||||
float TransmissionDepth = 0.0,
|
||||
normal Normal = N,
|
||||
normal ClearcoatNormal = N,
|
||||
normal Tangent = normalize(dPdu),
|
||||
|
@ -83,8 +84,21 @@ shader node_principled_bsdf(string distribution = "multi_ggx",
|
|||
float eta = max(IOR, 1e-5);
|
||||
eta = backfacing() ? 1.0 / eta : eta;
|
||||
|
||||
color refractTint = BaseColor;
|
||||
if (TransmissionDepth > 0) {
|
||||
if (backfacing()) {
|
||||
float RayLength;
|
||||
getattribute("path:ray_length", RayLength);
|
||||
reflectTint = pow(max(BaseColor, color(1e-5)), RayLength / TransmissionDepth);
|
||||
refractTint = reflectTint;
|
||||
}
|
||||
else {
|
||||
refractTint = color(1.0);
|
||||
}
|
||||
}
|
||||
|
||||
TransmissionBSDF = dielectric_bsdf(
|
||||
Normal, vector(0.0), reflectTint, BaseColor, r2, r2, eta, distribution);
|
||||
Normal, vector(0.0), reflectTint, refractTint, r2, r2, eta, distribution);
|
||||
BSDF = mix(BSDF, TransmissionBSDF, clamp(Transmission, 0.0, 1.0));
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
case CLOSURE_BSDF_PRINCIPLED_ID: {
|
||||
uint specular_offset, roughness_offset, specular_tint_offset, anisotropic_offset,
|
||||
sheen_offset, sheen_tint_offset, clearcoat_offset, clearcoat_roughness_offset,
|
||||
eta_offset, transmission_offset, anisotropic_rotation_offset, pad1;
|
||||
eta_offset, transmission_offset, transmission_depth_offset, anisotropic_rotation_offset;
|
||||
uint4 data_node2 = read_node(kg, &offset);
|
||||
|
||||
float3 T = stack_load_float3(stack, data_node.y);
|
||||
|
@ -84,8 +84,11 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
&sheen_tint_offset,
|
||||
&clearcoat_offset,
|
||||
&clearcoat_roughness_offset);
|
||||
svm_unpack_node_uchar4(
|
||||
data_node2.x, &eta_offset, &transmission_offset, &anisotropic_rotation_offset, &pad1);
|
||||
svm_unpack_node_uchar4(data_node2.x,
|
||||
&eta_offset,
|
||||
&transmission_offset,
|
||||
&transmission_depth_offset,
|
||||
&anisotropic_rotation_offset);
|
||||
|
||||
// get Disney principled parameters
|
||||
float metallic = saturatef(param1);
|
||||
|
@ -100,6 +103,7 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
float clearcoat = stack_load_float(stack, clearcoat_offset);
|
||||
float clearcoat_roughness = stack_load_float(stack, clearcoat_roughness_offset);
|
||||
float transmission = saturatef(stack_load_float(stack, transmission_offset));
|
||||
float transmission_depth = stack_load_float(stack, transmission_depth_offset);
|
||||
float anisotropic_rotation = stack_load_float(stack, anisotropic_rotation_offset);
|
||||
float eta = fmaxf(stack_load_float(stack, eta_offset), 1e-5f);
|
||||
|
||||
|
@ -250,7 +254,20 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
|
||||
fresnel->reflection_tint = mix(
|
||||
one_spectrum(), rgb_to_spectrum(base_color), specular_tint);
|
||||
fresnel->transmission_tint = rgb_to_spectrum(base_color);
|
||||
if (transmission_depth == 0.0f) {
|
||||
fresnel->transmission_tint = rgb_to_spectrum(base_color);
|
||||
}
|
||||
else if (sd->flag & SD_BACKFACING) {
|
||||
/* Use Beer-Lambert opsorption law. Clamp to avoid singularity when some color channel
|
||||
* is zero. */
|
||||
fresnel->reflection_tint = power(
|
||||
max(rgb_to_spectrum(base_color), make_spectrum(1e-5f)),
|
||||
sd->ray_length / transmission_depth);
|
||||
fresnel->transmission_tint = fresnel->reflection_tint;
|
||||
}
|
||||
else {
|
||||
fresnel->transmission_tint = one_spectrum();
|
||||
}
|
||||
|
||||
/* setup bsdf */
|
||||
sd->flag |= bsdf_microfacet_ggx_glass_setup(bsdf);
|
||||
|
|
|
@ -2678,6 +2678,7 @@ NODE_DEFINE(PrincipledBsdfNode)
|
|||
SOCKET_IN_FLOAT(clearcoat_roughness, "Clearcoat Roughness", 0.03f);
|
||||
SOCKET_IN_FLOAT(ior, "IOR", 0.0f);
|
||||
SOCKET_IN_FLOAT(transmission, "Transmission", 0.0f);
|
||||
SOCKET_IN_FLOAT(transmission_depth, "Transmission Depth", 0.0f);
|
||||
SOCKET_IN_FLOAT(anisotropic_rotation, "Anisotropic Rotation", 0.0f);
|
||||
SOCKET_IN_COLOR(emission, "Emission", zero_float3());
|
||||
SOCKET_IN_FLOAT(emission_strength, "Emission Strength", 1.0f);
|
||||
|
@ -2789,6 +2790,7 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler,
|
|||
ShaderInput *p_clearcoat_roughness,
|
||||
ShaderInput *p_ior,
|
||||
ShaderInput *p_transmission,
|
||||
ShaderInput *p_transmission_depth,
|
||||
ShaderInput *p_anisotropic_rotation)
|
||||
{
|
||||
ShaderInput *base_color_in = input("Base Color");
|
||||
|
@ -2815,6 +2817,7 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler,
|
|||
int clearcoat_roughness_offset = compiler.stack_assign(p_clearcoat_roughness);
|
||||
int ior_offset = compiler.stack_assign(p_ior);
|
||||
int transmission_offset = compiler.stack_assign(p_transmission);
|
||||
int transmission_depth_offset = compiler.stack_assign(p_transmission_depth);
|
||||
int anisotropic_rotation_offset = compiler.stack_assign(p_anisotropic_rotation);
|
||||
int subsurface_radius_offset = compiler.stack_assign(p_subsurface_radius);
|
||||
int subsurface_ior_offset = compiler.stack_assign(p_subsurface_ior);
|
||||
|
@ -2838,7 +2841,7 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler,
|
|||
|
||||
compiler.add_node(
|
||||
compiler.encode_uchar4(
|
||||
ior_offset, transmission_offset, anisotropic_rotation_offset, SVM_STACK_INVALID),
|
||||
ior_offset, transmission_offset, transmission_depth_offset, anisotropic_rotation_offset),
|
||||
distribution,
|
||||
subsurface_method,
|
||||
sheen_roughness_offset);
|
||||
|
@ -2884,6 +2887,7 @@ void PrincipledBsdfNode::compile(SVMCompiler &compiler)
|
|||
input("Clearcoat Roughness"),
|
||||
input("IOR"),
|
||||
input("Transmission"),
|
||||
input("Transmission Depth"),
|
||||
input("Anisotropic Rotation"));
|
||||
}
|
||||
|
||||
|
|
|
@ -534,6 +534,7 @@ class PrincipledBsdfNode : public BsdfBaseNode {
|
|||
ShaderInput *clearcoat_roughness,
|
||||
ShaderInput *ior,
|
||||
ShaderInput *transmission,
|
||||
ShaderInput *transmission_depth,
|
||||
ShaderInput *anisotropic_rotation);
|
||||
|
||||
NODE_SOCKET_API(float3, base_color)
|
||||
|
@ -554,6 +555,7 @@ class PrincipledBsdfNode : public BsdfBaseNode {
|
|||
NODE_SOCKET_API(float, clearcoat_roughness)
|
||||
NODE_SOCKET_API(float, ior)
|
||||
NODE_SOCKET_API(float, transmission)
|
||||
NODE_SOCKET_API(float, transmission_depth)
|
||||
NODE_SOCKET_API(float, anisotropic_rotation)
|
||||
NODE_SOCKET_API(float3, normal)
|
||||
NODE_SOCKET_API(float3, clearcoat_normal)
|
||||
|
|
|
@ -37,6 +37,7 @@ void node_bsdf_principled(vec4 base_color,
|
|||
float clearcoat_roughness,
|
||||
float ior,
|
||||
float transmission,
|
||||
float transmission_depth,
|
||||
vec4 emission,
|
||||
float emission_strength,
|
||||
float alpha,
|
||||
|
|
|
@ -111,22 +111,31 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
.max(1.0f)
|
||||
.subtype(PROP_FACTOR);
|
||||
#define SOCK_TRANSMISSION_ID 18
|
||||
b.add_input<decl::Float>("Transmission Depth")
|
||||
.default_value(0.0f)
|
||||
.min(0.0f)
|
||||
.max(1000000.0f)
|
||||
.description(
|
||||
"Distance traveled inside the medium by white light before its color becomes exactly "
|
||||
"base color, determining the extinction coefficient of the interior medium based on "
|
||||
"Beer-Lambert law; if zero, base color acts as a constant transmission tint");
|
||||
#define SOCK_TRANSMISSION_DEPTH_ID 19
|
||||
b.add_input<decl::Color>("Emission").default_value({0.0f, 0.0f, 0.0f, 1.0f});
|
||||
#define SOCK_EMISSION_ID 19
|
||||
#define SOCK_EMISSION_ID 20
|
||||
b.add_input<decl::Float>("Emission Strength").default_value(1.0).min(0.0f).max(1000000.0f);
|
||||
#define SOCK_EMISSION_STRENGTH_ID 20
|
||||
#define SOCK_EMISSION_STRENGTH_ID 21
|
||||
b.add_input<decl::Float>("Alpha").default_value(1.0f).min(0.0f).max(1.0f).subtype(PROP_FACTOR);
|
||||
#define SOCK_ALPHA_ID 21
|
||||
#define SOCK_ALPHA_ID 22
|
||||
b.add_input<decl::Vector>("Normal").hide_value();
|
||||
#define SOCK_NORMAL_ID 22
|
||||
#define SOCK_NORMAL_ID 23
|
||||
b.add_input<decl::Vector>("Clearcoat Normal").hide_value();
|
||||
#define SOCK_CLEARCOAT_NORMAL_ID 23
|
||||
#define SOCK_CLEARCOAT_NORMAL_ID 24
|
||||
b.add_input<decl::Vector>("Tangent").hide_value();
|
||||
#define SOCK_TANGENT_ID 24
|
||||
#define SOCK_TANGENT_ID 25
|
||||
b.add_input<decl::Float>("Weight").unavailable();
|
||||
#define SOCK_WEIGHT_ID 25
|
||||
#define SOCK_WEIGHT_ID 26
|
||||
b.add_output<decl::Shader>("BSDF");
|
||||
#define SOCK_BSDF_ID 26
|
||||
#define SOCK_BSDF_ID 27
|
||||
}
|
||||
|
||||
static void node_shader_buts_principled(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
|
|
Loading…
Reference in New Issue