Shader: Add specular tint to Glass BSDF #114354
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue