Shader: Add specular tint to Glass BSDF #114354

Closed
Alaska wants to merge 4 commits from Alaska:update-glass-bsdf into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
8 changed files with 67 additions and 17 deletions

View File

@ -6,18 +6,23 @@
#include "stdcycles.h"
shader node_glass_bsdf(color Color = 0.8,
color SpecularTint = 1.0,
string distribution = "ggx",
float Roughness = 0.2,
float IOR = 1.45,
normal Normal = N,
output closure color BSDF = 0)
{
float r2 = Roughness * Roughness;
color base_color = clamp(Color, color(0.0), color(1.0));
float r2 = clamp(Roughness, 0.0, 1.0);
r2 *= r2;
float eta = max(IOR, 1e-5);
eta = backfacing() ? 1.0 / eta : eta;
color F0 = F0_from_ior(eta);
color F0 = F0_from_ior(eta) * SpecularTint;
color F90 = color(1.0);
BSDF = generalized_schlick_bsdf(
Normal, vector(0.0), Color, Color, r2, r2, F0, F90, -eta, distribution);
Normal, vector(0.0), color(1.0), base_color, r2, r2, F0, F90, -eta, distribution);
}

View File

@ -571,14 +571,15 @@ ccl_device
float ior = fmaxf(param2, 1e-5f);
bsdf->ior = (sd->flag & SD_BACKFACING) ? 1.0f / ior : ior;
bsdf->alpha_x = bsdf->alpha_y = sqr(param1);
bsdf->alpha_x = bsdf->alpha_y = sqr(saturatef(param1));
fresnel->f0 = make_float3(F0_from_ior(ior));
const float3 specular_tint = stack_load_float3(stack, data_node.w);
fresnel->f0 = F0_from_ior(ior) * specular_tint;
fresnel->f90 = one_spectrum();
fresnel->exponent = -ior;
const float3 color = stack_load_float3(stack, data_node.z);
fresnel->reflection_tint = color;
fresnel->transmission_tint = color;
fresnel->reflection_tint = one_spectrum();
const float3 color = saturate(stack_load_float3(stack, data_node.z));
fresnel->transmission_tint = rgb_to_spectrum(color);
/* setup bsdf */
if (type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) {

View File

@ -2415,6 +2415,7 @@ NODE_DEFINE(GlassBsdfNode)
NodeType *type = NodeType::add("glass_bsdf", create, NodeType::SHADER);
SOCKET_IN_COLOR(color, "Color", make_float3(0.8f, 0.8f, 0.8f));
SOCKET_IN_COLOR(specular_tint, "Specular Tint", make_float3(1.0f, 1.0f, 1.0f));
SOCKET_IN_NORMAL(normal, "Normal", zero_float3(), SocketType::LINK_NORMAL);
SOCKET_IN_FLOAT(surface_mix_weight, "SurfaceMixWeight", 0.0f, SocketType::SVM_INTERNAL);
@ -2440,7 +2441,8 @@ GlassBsdfNode::GlassBsdfNode() : BsdfNode(get_node_type())
void GlassBsdfNode::compile(SVMCompiler &compiler)
{
closure = distribution;
BsdfNode::compile(compiler, input("Roughness"), input("IOR"), input("Color"));
BsdfNode::compile(
compiler, input("Roughness"), input("IOR"), input("Color"), input("Specular Tint"));
}
void GlassBsdfNode::compile(OSLCompiler &compiler)

View File

@ -608,6 +608,7 @@ class GlassBsdfNode : public BsdfNode {
return distribution;
}
NODE_SOCKET_API(float3, specular_tint)
NODE_SOCKET_API(float, roughness)
NODE_SOCKET_API(float, IOR)
NODE_SOCKET_API(ClosureType, distribution)

View File

@ -29,7 +29,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 10
#define BLENDER_FILE_SUBVERSION 11
/* 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

View File

@ -354,6 +354,29 @@ static void versioning_replace_splitviewer(bNodeTree *ntree)
}
}
static void version_glass_bsdf_specular_tint(bNodeTree *ntree)
{
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
if (node->type != SH_NODE_BSDF_GLASS) {
continue;
}
bNodeSocket *color_socket = nodeFindSocket(node, SOCK_IN, "Color");
float *base_color = version_cycles_node_socket_rgba_value(color_socket);
bNodeSocket *spec_tint_socket = nodeFindSocket(node, SOCK_IN, "Specular Tint");
copy_v4_v4(version_cycles_node_socket_rgba_value(spec_tint_socket), base_color);
if (color_socket->link) {
nodeAddLink(ntree,
color_socket->link->fromnode,
color_socket->link->fromsock,
node,
spec_tint_socket);
}
}
}
void do_versions_after_linking_400(FileData *fd, Main *bmain)
{
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 400, 9)) {
@ -448,6 +471,17 @@ void do_versions_after_linking_400(FileData *fd, Main *bmain)
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 11)) {
version_node_socket_index_animdata(bmain, NTREE_SHADER, SH_NODE_BSDF_GLASS, 1, 1, 4);
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
if (ntree->type == NTREE_SHADER) {
/* Add specular tint to Glass BSDF. */
version_glass_bsdf_specular_tint(ntree);
}
}
FOREACH_NODETREE_END;
}
/**
* Always bump subversion in BKE_blender_version.h when adding versioning
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.

View File

@ -3,6 +3,7 @@
* SPDX-License-Identifier: GPL-2.0-or-later */
void node_bsdf_glass(vec4 color,
vec4 specular_tint,
float roughness,
float ior,
vec3 N,
@ -13,22 +14,27 @@ void node_bsdf_glass(vec4 color,
color = max(color, vec4(0.0));
roughness = saturate(roughness);
ior = max(ior, 1e-5);
N = safe_normalize(N);
vec3 V = coordinate_incoming(g_data.P);
float NV = dot(N, V);
vec2 bsdf = bsdf_lut(NV, roughness, ior, do_multiscatter != 0.0);
vec3 F0 = vec3(F0_from_ior(ior)) * specular_tint.rgb;
vec3 F90 = vec3(1.0);
vec3 reflectance, transmittance;
bsdf_lut(
F0, F90, color.rgb, NV, roughness, ior, do_multiscatter != 0.0, reflectance, transmittance);
ClosureReflection reflection_data;
reflection_data.weight = bsdf.x * weight;
reflection_data.color = color.rgb;
reflection_data.weight = weight;
reflection_data.color = reflectance;
reflection_data.N = N;
reflection_data.roughness = roughness;
ClosureRefraction refraction_data;
refraction_data.weight = bsdf.y * weight;
refraction_data.color = color.rgb;
refraction_data.weight = weight;
refraction_data.color = transmittance;
refraction_data.N = N;
refraction_data.roughness = roughness;
refraction_data.ior = ior;

View File

@ -9,6 +9,7 @@ namespace blender::nodes::node_shader_bsdf_glass_cc {
static void node_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Color>("Color").default_value({1.0f, 1.0f, 1.0f, 1.0f});
b.add_input<decl::Color>("Specular Tint").default_value({1.0f, 1.0f, 1.0f, 1.0f});
b.add_input<decl::Float>("Roughness")
.default_value(0.0f)
.min(0.0f)
@ -31,8 +32,8 @@ static int node_shader_gpu_bsdf_glass(GPUMaterial *mat,
GPUNodeStack *in,
GPUNodeStack *out)
{
if (!in[3].link) {
GPU_link(mat, "world_normals_get", &in[3].link);
if (!in[4].link) {
GPU_link(mat, "world_normals_get", &in[4].link);
}
GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY | GPU_MATFLAG_REFRACT);