Shader: Add Conductor BSDF Node #114958
|
@ -563,6 +563,18 @@ static ShaderNode *add_node(Scene *scene,
|
|||
conductor->set_distribution(CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (b_conductor_node.fresnel_type()) {
|
||||
case BL::ShaderNodeBsdfConductor::fresnel_type_ARTISTIC_CONDUCTOR:
|
||||
conductor->set_fresnel_type(CLOSURE_BSDF_ARTISTIC_CONDUCTOR);
|
||||
break;
|
||||
case BL::ShaderNodeBsdfConductor::fresnel_type_CONDUCTOR:
|
||||
conductor->set_fresnel_type(CLOSURE_BSDF_CONDUCTOR);
|
||||
break;
|
||||
case BL::ShaderNodeBsdfConductor::fresnel_type_F82:
|
||||
conductor->set_fresnel_type(CLOSURE_BSDF_CONDUCTOR_F82);
|
||||
break;
|
||||
}
|
||||
node = conductor;
|
||||
}
|
||||
else if (b_node.is_a(&RNA_ShaderNodeBsdfAnisotropic)) {
|
||||
|
|
|
@ -74,6 +74,43 @@ ccl_device Spectrum fresnel_conductor(float cosi, const Spectrum eta, const Spec
|
|||
return (Rparl2 + Rperp2) * 0.5f;
|
||||
}
|
||||
|
||||
ccl_device float3 conductor_ior_from_color(float3 r, const float3 edge_tint)
|
||||
{
|
||||
r = clamp(r, zero_float3(), make_float3(0.99));
|
||||
const float3 r_sqrt = sqrt(r);
|
||||
const float3 one = one_float3();
|
||||
|
||||
const float3 n_min = (one - r) / (one + r);
|
||||
const float3 n_max = (one + r_sqrt) / (one - r_sqrt);
|
||||
|
||||
return mix(n_max, n_min, edge_tint);
|
||||
}
|
||||
|
||||
ccl_device float3 conductor_extinction_from_color(float3 r, const float3 eta)
|
||||
{
|
||||
r = clamp(r, zero_float3(), make_float3(0.99));
|
||||
const float3 one = one_float3();
|
||||
|
||||
const float3 np1 = eta + one;
|
||||
const float3 nm1 = eta - one;
|
||||
float3 k2 = ((r * np1 * np1) - (nm1 * nm1)) / (one - r);
|
||||
k2 = max(k2, zero_float3());
|
||||
|
||||
return sqrt(k2);
|
||||
}
|
||||
|
||||
ccl_device void complex_ior_from_base_edge(const float3 reflectivity,
|
||||
const float3 edge_tint,
|
||||
ccl_private float3 *eta,
|
||||
ccl_private float3 *k)
|
||||
{
|
||||
/* Equations from "Artist Friendly Metallic Fresnel", Ole Gulbrandsen, 2014
|
||||
* https://jcgt.org/published/0003/04/03/paper.pdf */
|
||||
|
||||
*eta = conductor_ior_from_color(reflectivity, edge_tint);
|
||||
*k = conductor_extinction_from_color(reflectivity, *eta);
|
||||
}
|
||||
|
||||
ccl_device float ior_from_F0(float f0)
|
||||
{
|
||||
const float sqrt_f0 = sqrtf(clamp(f0, 0.0f, 0.99f));
|
||||
|
|
|
@ -5,9 +5,12 @@
|
|||
#include "node_fresnel.h"
|
||||
#include "stdcycles.h"
|
||||
|
||||
shader node_conductor_bsdf(color Color = 1.0,
|
||||
color Tint = 1.0,
|
||||
shader node_conductor_bsdf(color BaseColor = 1.0,
|
||||
color EdgeTint = 1.0,
|
||||
vector IOR = vector(0.183, 0.421, 1.373),
|
||||
vector ExtinctionCoefficient = vector(3.424, 2.346, 1.770),
|
||||
string distribution = "multi_ggx",
|
||||
string fresnel_type = "conductor",
|
||||
float Roughness = 0.5,
|
||||
float Anisotropy = 0.0,
|
||||
float Rotation = 0.0,
|
||||
|
@ -29,7 +32,23 @@ shader node_conductor_bsdf(color Color = 1.0,
|
|||
T = rotate(T, Rotation * M_2PI, point(0.0, 0.0, 0.0), Normal);
|
||||
}
|
||||
|
||||
color F0 = clamp(Color, color(0.0), color(1.0));
|
||||
color F82 = clamp(Tint, color(0.0), color(1.0));
|
||||
BSDF = microfacet_f82_tint(distribution, Normal, T, alpha_x, alpha_y, F0, F82);
|
||||
color F0 = clamp(BaseColor, color(0.0), color(1.0));
|
||||
color F82 = clamp(EdgeTint, color(0.0), color(1.0));
|
||||
|
||||
if (fresnel_type == "f82") {
|
||||
BSDF = microfacet_f82_tint(distribution, Normal, T, alpha_x, alpha_y, F0, F82);
|
||||
}
|
||||
else {
|
||||
vector n, k;
|
||||
if (fresnel_type == "conductor") {
|
||||
n = max(IOR, 0.0);
|
||||
k = max(ExtinctionCoefficient, 0.0);
|
||||
}
|
||||
else {
|
||||
n = conductor_ior_from_color(F0, F82);
|
||||
k = conductor_extinction_from_color(F0, n);
|
||||
}
|
||||
|
||||
BSDF = conductor_bsdf(Normal, T, alpha_x, alpha_y, n, k, distribution);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,36 @@ color fresnel_conductor(float cosi, color eta, color k)
|
|||
return (Rparl2 + Rperp2) * 0.5;
|
||||
}
|
||||
|
||||
vector conductor_ior_from_color(color reflectivity, color edge_tint)
|
||||
{
|
||||
/* "Artist Friendly Metallic Fresnel", Ole Gulbrandsen, 2014
|
||||
* https://jcgt.org/published/0003/04/03/paper.pdf */
|
||||
|
||||
vector r = clamp(reflectivity, 0.0, 0.99);
|
||||
vector r_sqrt = sqrt(r);
|
||||
vector one = 1.0;
|
||||
|
||||
vector n_min = (one - r) / (one + r);
|
||||
vector n_max = (one + r_sqrt) / (one - r_sqrt);
|
||||
|
||||
return mix(n_max, n_min, edge_tint);
|
||||
}
|
||||
|
||||
vector conductor_extinction_from_color(color reflectivity, vector n)
|
||||
{
|
||||
/* "Artist Friendly Metallic Fresnel", Ole Gulbrandsen, 2014
|
||||
* https://jcgt.org/published/0003/04/03/paper.pdf */
|
||||
|
||||
vector r = clamp(reflectivity, 0.0, 0.99);
|
||||
|
||||
vector np1 = n + 1.0;
|
||||
vector nm1 = n - 1.0;
|
||||
vector k2 = ((r * np1 * np1) - (nm1 * nm1)) / (1.0 - r);
|
||||
k2 = max(k2, 0.0);
|
||||
|
||||
return sqrt(k2);
|
||||
}
|
||||
|
||||
float F0_from_ior(float eta)
|
||||
{
|
||||
float f0 = (eta - 1.0) / (eta + 1.0);
|
||||
|
|
|
@ -450,22 +450,20 @@ ccl_device
|
|||
bsdf_transparent_setup(sd, weight, path_flag);
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_CONDUCTOR: {
|
||||
case CLOSURE_BSDF_CONDUCTOR:
|
||||
case CLOSURE_BSDF_CONDUCTOR_F82:
|
||||
case CLOSURE_BSDF_ARTISTIC_CONDUCTOR: {
|
||||
#ifdef __CAUSTICS_TRICKS__
|
||||
if (!kernel_data.integrator.caustics_reflective && (path_flag & PATH_RAY_DIFFUSE))
|
||||
break;
|
||||
#endif
|
||||
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
|
||||
sd, sizeof(MicrofacetBsdf), rgb_to_spectrum(make_float3(mix_weight)));
|
||||
ccl_private FresnelF82Tint *fresnel = (bsdf != NULL) ?
|
||||
(ccl_private FresnelF82Tint *)closure_alloc_extra(
|
||||
sd, sizeof(FresnelF82Tint)) :
|
||||
NULL;
|
||||
|
||||
if (bsdf && fresnel) {
|
||||
uint color_offest, tint_offset, rotation_offset, tangent_offset;
|
||||
if (!(bsdf == NULL)) {
|
||||
uint base_ior_offest, edge_tint_k_offset, rotation_offset, tangent_offset;
|
||||
svm_unpack_node_uchar4(
|
||||
node.z, &color_offest, &tint_offset, &rotation_offset, &tangent_offset);
|
||||
node.z, &base_ior_offest, &edge_tint_k_offset, &rotation_offset, &tangent_offset);
|
||||
|
||||
float3 valid_reflection_N = maybe_ensure_valid_specular_reflection(sd, N);
|
||||
float3 T = stack_load_float3(stack, tangent_offset);
|
||||
|
@ -487,9 +485,6 @@ ccl_device
|
|||
bsdf->alpha_x = alpha_x;
|
||||
bsdf->alpha_y = alpha_y;
|
||||
|
||||
fresnel->f0 = rgb_to_spectrum(saturate(stack_load_float3(stack, color_offest)));
|
||||
const Spectrum f82 = rgb_to_spectrum(saturate(stack_load_float3(stack, tint_offset)));
|
||||
|
||||
ClosureType distribution = (ClosureType)node.w;
|
||||
/* setup bsdf */
|
||||
if (distribution == CLOSURE_BSDF_MICROFACET_BECKMANN_ID) {
|
||||
|
@ -498,8 +493,39 @@ ccl_device
|
|||
else {
|
||||
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
|
||||
}
|
||||
|
||||
const bool is_multiggx = (distribution == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
|
||||
bsdf_microfacet_setup_fresnel_f82_tint(kg, bsdf, sd, fresnel, f82, is_multiggx);
|
||||
|
||||
if (type == CLOSURE_BSDF_CONDUCTOR || type == CLOSURE_BSDF_ARTISTIC_CONDUCTOR) {
|
||||
ccl_private FresnelConductor *fresnel = (ccl_private FresnelConductor *)
|
||||
closure_alloc_extra(sd, sizeof(FresnelConductor));
|
||||
|
||||
float3 n, k;
|
||||
if (type == CLOSURE_BSDF_CONDUCTOR) {
|
||||
n = max(stack_load_float3(stack, base_ior_offest), zero_float3());
|
||||
k = max(stack_load_float3(stack, edge_tint_k_offset), zero_float3());
|
||||
}
|
||||
else {
|
||||
const float3 color = saturate(stack_load_float3(stack, base_ior_offest));
|
||||
const float3 tint = saturate(stack_load_float3(stack, edge_tint_k_offset));
|
||||
complex_ior_from_base_edge(color, tint, &n, &k);
|
||||
}
|
||||
|
||||
fresnel->n = rgb_to_spectrum(n);
|
||||
fresnel->k = rgb_to_spectrum(k);
|
||||
bsdf_microfacet_setup_fresnel_conductor(kg, bsdf, sd, fresnel, is_multiggx);
|
||||
}
|
||||
else {
|
||||
ccl_private FresnelF82Tint *fresnel = (ccl_private FresnelF82Tint *)closure_alloc_extra(
|
||||
sd, sizeof(FresnelF82Tint));
|
||||
|
||||
const float3 color = saturate(stack_load_float3(stack, base_ior_offest));
|
||||
const float3 tint = saturate(stack_load_float3(stack, edge_tint_k_offset));
|
||||
|
||||
fresnel->f0 = rgb_to_spectrum(color);
|
||||
const Spectrum f82 = rgb_to_spectrum(tint);
|
||||
bsdf_microfacet_setup_fresnel_f82_tint(kg, bsdf, sd, fresnel, f82, is_multiggx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -426,7 +426,9 @@ typedef enum ClosureType {
|
|||
CLOSURE_BSDF_TRANSLUCENT_ID,
|
||||
|
||||
/* Glossy */
|
||||
CLOSURE_BSDF_CONDUCTOR, /* virtual closure */
|
||||
CLOSURE_BSDF_CONDUCTOR, /* virtual closure */
|
||||
CLOSURE_BSDF_ARTISTIC_CONDUCTOR, /* virtual closure */
|
||||
CLOSURE_BSDF_CONDUCTOR_F82, /* virtual closure */
|
||||
CLOSURE_BSDF_MICROFACET_GGX_ID,
|
||||
CLOSURE_BSDF_MICROFACET_BECKMANN_ID,
|
||||
CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID, /* virtual closure */
|
||||
|
|
|
@ -1198,6 +1198,8 @@ int ShaderGraph::get_num_closures()
|
|||
num_closures += MAX_VOLUME_STACK_SIZE;
|
||||
}
|
||||
else if (closure_type == CLOSURE_BSDF_CONDUCTOR ||
|
||||
closure_type == CLOSURE_BSDF_ARTISTIC_CONDUCTOR ||
|
||||
closure_type == CLOSURE_BSDF_CONDUCTOR_F82 ||
|
||||
closure_type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID ||
|
||||
closure_type == CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID ||
|
||||
closure_type == CLOSURE_BSDF_HAIR_CHIANG_ID ||
|
||||
|
|
|
@ -2404,7 +2404,7 @@ NODE_DEFINE(ConductorBsdfNode)
|
|||
{
|
||||
NodeType *type = NodeType::add("Conductor_bsdf", create, NodeType::SHADER);
|
||||
|
||||
SOCKET_IN_COLOR(color, "Color", make_float3(1.0f, 1.0f, 1.0f));
|
||||
SOCKET_IN_COLOR(color, "Base Color", 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);
|
||||
|
||||
|
@ -2415,7 +2415,17 @@ NODE_DEFINE(ConductorBsdfNode)
|
|||
SOCKET_ENUM(
|
||||
distribution, "Distribution", distribution_enum, CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID);
|
||||
|
||||
SOCKET_IN_COLOR(tint, "Tint", make_float3(1.0f, 1.0f, 1.0f));
|
||||
static NodeEnum fresnel_type_enum;
|
||||
fresnel_type_enum.insert("f82", CLOSURE_BSDF_CONDUCTOR_F82);
|
||||
fresnel_type_enum.insert("artist_conductor", CLOSURE_BSDF_ARTISTIC_CONDUCTOR);
|
||||
fresnel_type_enum.insert("conductor", CLOSURE_BSDF_CONDUCTOR);
|
||||
SOCKET_ENUM(fresnel_type, "fresnel_type", fresnel_type_enum, CLOSURE_BSDF_ARTISTIC_CONDUCTOR);
|
||||
|
||||
SOCKET_IN_COLOR(edge_tint, "Edge Tint", make_float3(1.0f, 1.0f, 1.0f));
|
||||
|
||||
SOCKET_IN_VECTOR(ior, "IOR", make_float3(0.183f, 0.421f, 1.373f));
|
||||
SOCKET_IN_VECTOR(k, "Extinction Coefficient", make_float3(3.424f, 2.346f, 1.770f));
|
||||
|
||||
SOCKET_IN_VECTOR(tangent, "Tangent", zero_float3(), SocketType::LINK_TANGENT);
|
||||
|
||||
SOCKET_IN_FLOAT(roughness, "Roughness", 0.5f);
|
||||
|
@ -2465,21 +2475,32 @@ void ConductorBsdfNode::compile(SVMCompiler &compiler)
|
|||
{
|
||||
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, one_float3());
|
||||
|
||||
ShaderInput *color_in = input("Color");
|
||||
ShaderInput *base_color_in = input("Base Color");
|
||||
ShaderInput *edge_tint_in = input("Edge Tint");
|
||||
ShaderInput *ior_in = input("IOR");
|
||||
ShaderInput *k_in = input("Extinction Coefficient");
|
||||
|
||||
int base_color_ior_offset = fresnel_type == CLOSURE_BSDF_CONDUCTOR ?
|
||||
compiler.stack_assign(ior_in) :
|
||||
compiler.stack_assign(base_color_in);
|
||||
int edge_tint_k_offset = fresnel_type == CLOSURE_BSDF_CONDUCTOR ?
|
||||
compiler.stack_assign(k_in) :
|
||||
compiler.stack_assign(edge_tint_in);
|
||||
|
||||
ShaderInput *anisotropy_in = input("Anisotropy");
|
||||
ShaderInput *rotation_in = input("Rotation");
|
||||
ShaderInput *tint_in = input("Tint");
|
||||
ShaderInput *roughness_in = input("Roughness");
|
||||
ShaderInput *tangent_in = input("Tangent");
|
||||
|
||||
int normal_offset = compiler.stack_assign_if_linked(input("Normal"));
|
||||
|
||||
compiler.add_node(NODE_CLOSURE_BSDF,
|
||||
compiler.encode_uchar4(closure,
|
||||
compiler.encode_uchar4(fresnel_type,
|
||||
compiler.stack_assign(roughness_in),
|
||||
compiler.stack_assign(anisotropy_in),
|
||||
compiler.closure_mix_weight_offset()),
|
||||
compiler.encode_uchar4(compiler.stack_assign(color_in),
|
||||
compiler.stack_assign(tint_in),
|
||||
compiler.encode_uchar4(base_color_ior_offset,
|
||||
edge_tint_k_offset,
|
||||
compiler.stack_assign(rotation_in),
|
||||
compiler.stack_assign(tangent_in)),
|
||||
distribution);
|
||||
|
@ -2489,6 +2510,7 @@ void ConductorBsdfNode::compile(SVMCompiler &compiler)
|
|||
void ConductorBsdfNode::compile(OSLCompiler &compiler)
|
||||
{
|
||||
compiler.parameter(this, "distribution");
|
||||
compiler.parameter(this, "fresnel_type");
|
||||
compiler.add(this, "node_conductor_bsdf");
|
||||
}
|
||||
|
||||
|
|
|
@ -597,12 +597,15 @@ class ConductorBsdfNode : public BsdfNode {
|
|||
return closure;
|
||||
}
|
||||
|
||||
NODE_SOCKET_API(float3, tint)
|
||||
NODE_SOCKET_API(float3, edge_tint)
|
||||
NODE_SOCKET_API(float3, ior)
|
||||
NODE_SOCKET_API(float3, k)
|
||||
NODE_SOCKET_API(float3, tangent)
|
||||
NODE_SOCKET_API(float, roughness)
|
||||
NODE_SOCKET_API(float, anisotropy)
|
||||
NODE_SOCKET_API(float, rotation)
|
||||
NODE_SOCKET_API(ClosureType, distribution)
|
||||
NODE_SOCKET_API(ClosureType, fresnel_type)
|
||||
|
||||
void attributes(Shader *shader, AttributeRequestSet *attributes);
|
||||
bool has_attribute_dependency()
|
||||
|
|
|
@ -341,6 +341,11 @@ ccl_device_inline float3 mix(const float3 a, const float3 b, float t)
|
|||
return a + t * (b - a);
|
||||
}
|
||||
|
||||
ccl_device_inline float3 mix(const float3 a, const float3 b, float3 t)
|
||||
{
|
||||
return make_float3(mix(a.x, b.x, t.x), mix(a.y, b.y, t.y), mix(a.z, b.z, t.z));
|
||||
}
|
||||
|
||||
ccl_device_inline float3 rcp(const float3 a)
|
||||
{
|
||||
# ifdef __KERNEL_SSE__
|
||||
|
|
|
@ -2,8 +2,27 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
void node_bsdf_conductor(vec4 color,
|
||||
vec4 tint,
|
||||
vec4 fresnel_conductor(float cosi, const vec3 eta, const vec3 k)
|
||||
{
|
||||
const vec4 cosiv4 = vec4(cosi);
|
||||
const vec4 etav4 = vec4(eta, 1.0);
|
||||
const vec4 kv4 = vec4(k, 1.0);
|
||||
|
||||
const vec4 cosi2 = vec4(cosi * cosi);
|
||||
const vec4 one = vec4(1.0);
|
||||
const vec4 tmp_f = (etav4 * etav4) + (kv4 * kv4);
|
||||
|
||||
const vec4 tmp = tmp_f * cosi2;
|
||||
const vec4 Rparl2 = (tmp - (2.0 * etav4 * cosiv4) + one) / (tmp + (2.0 * etav4 * cosiv4) + one);
|
||||
const vec4 Rperp2 = (tmp_f - (2.0 * etav4 * cosiv4) + cosi2) /
|
||||
(tmp_f + (2.0 * etav4 * cosiv4) + cosi2);
|
||||
return (Rparl2 + Rperp2) * 0.5;
|
||||
}
|
||||
|
||||
void node_bsdf_conductor(vec4 base_color,
|
||||
vec4 edge_tint,
|
||||
vec3 eta,
|
||||
vec3 k,
|
||||
float roughness,
|
||||
float anisotropy,
|
||||
float rotation,
|
||||
|
@ -11,11 +30,17 @@ void node_bsdf_conductor(vec4 color,
|
|||
vec3 T,
|
||||
float weight,
|
||||
const float do_multiscatter,
|
||||
const float use_complex_ior,
|
||||
out Closure result)
|
||||
{
|
||||
if (use_complex_ior != 0.0) {
|
||||
base_color = fresnel_conductor(1.0, eta, k);
|
||||
edge_tint = fresnel_conductor(1.0 / 7.0, eta, k);
|
||||
}
|
||||
|
||||
/* Clamp to match Cycles */
|
||||
color = saturate(color);
|
||||
tint = saturate(tint);
|
||||
base_color = saturate(base_color);
|
||||
edge_tint = saturate(edge_tint);
|
||||
roughness = saturate(roughness);
|
||||
/* Not used by EEVEE */
|
||||
/* anisotropy = saturate(anisotropy); */
|
||||
|
@ -27,8 +52,8 @@ void node_bsdf_conductor(vec4 color,
|
|||
ClosureReflection reflection_data;
|
||||
reflection_data.N = N;
|
||||
reflection_data.roughness = roughness;
|
||||
vec3 F0 = color.rgb;
|
||||
vec3 F82 = tint.rgb;
|
||||
vec3 F0 = base_color.rgb;
|
||||
vec3 F82 = edge_tint.rgb;
|
||||
vec3 metallic_brdf;
|
||||
brdf_f82_tint_lut(F0, F82, NV, roughness, do_multiscatter != 0.0, metallic_brdf);
|
||||
reflection_data.color = metallic_brdf;
|
||||
|
|
|
@ -1935,6 +1935,13 @@ enum {
|
|||
CMP_NODE_CHANNEL_MATTE_CS_YCC = 4,
|
||||
};
|
||||
|
||||
/* Conductive fresnel types */
|
||||
enum {
|
||||
SHD_CONDUCTOR = 0,
|
||||
SHD_ARTISTIC_CONDUCTOR = 1,
|
||||
SHD_CONDUCTOR_F82 = 2,
|
||||
};
|
||||
|
||||
/* glossy distributions */
|
||||
enum {
|
||||
SHD_GLOSSY_BECKMANN = 0,
|
||||
|
|
|
@ -3920,7 +3920,7 @@ static const EnumPropertyItem node_ycc_items[] = {
|
|||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem node_conductor_items[] = {
|
||||
static const EnumPropertyItem node_conductor_distrobution_items[] = {
|
||||
{SHD_GLOSSY_BECKMANN, "BECKMANN", 0, "Beckmann", ""},
|
||||
{SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""},
|
||||
{SHD_GLOSSY_MULTI_GGX,
|
||||
|
@ -3932,6 +3932,17 @@ static const EnumPropertyItem node_conductor_items[] = {
|
|||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem node_conductor_fresnel_type_items[] = {
|
||||
{SHD_CONDUCTOR, "CONDUCTOR", 0, "Conductor Fresnel", ""},
|
||||
{SHD_ARTISTIC_CONDUCTOR,
|
||||
"ARTISTIC_CONDUCTOR",
|
||||
0,
|
||||
"Conductor Fresnel - Artistic",
|
||||
"Conductive Fresnel with artist friendly color inputs"},
|
||||
{SHD_CONDUCTOR_F82, "F82", 0, "F82 Tint Fresnel", ""},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem node_glossy_items[] = {
|
||||
{SHD_GLOSSY_BECKMANN, "BECKMANN", 0, "Beckmann", ""},
|
||||
{SHD_GLOSSY_GGX, "GGX", 0, "GGX", ""},
|
||||
|
@ -5377,9 +5388,15 @@ static void def_conductor(StructRNA *srna)
|
|||
|
||||
prop = RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "custom1");
|
||||
RNA_def_property_enum_items(prop, node_conductor_items);
|
||||
RNA_def_property_enum_items(prop, node_conductor_distrobution_items);
|
||||
RNA_def_property_ui_text(prop, "Distribution", "Light scattering distribution on rough surface");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
|
||||
prop = RNA_def_property(srna, "fresnel_type", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "custom2");
|
||||
RNA_def_property_enum_items(prop, node_conductor_fresnel_type_items);
|
||||
RNA_def_property_ui_text(prop, "Fresnel Type", "PLACE HOLDER");
|
||||
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
|
||||
}
|
||||
|
||||
static void def_glossy(StructRNA *srna)
|
||||
|
|
|
@ -11,8 +11,18 @@ namespace blender::nodes::node_shader_bsdf_conductor_cc {
|
|||
|
||||
static void node_declare(NodeDeclarationBuilder &b)
|
||||
{
|
||||
b.add_input<decl::Color>("Color").default_value({0.8f, 0.8f, 0.8f, 1.0f});
|
||||
b.add_input<decl::Color>("Tint").default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
b.add_input<decl::Color>("Base Color").default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
b.add_input<decl::Color>("Edge Tint").default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
||||
b.add_input<decl::Vector>("IOR")
|
||||
.default_value({0.183f, 0.421f, 1.373f})
|
||||
.min(0.0f)
|
||||
.max(100.0f)
|
||||
.description("PLACEHOLDER");
|
||||
b.add_input<decl::Vector>("Extinction Coefficient")
|
||||
.default_value({3.424f, 2.346f, 1.770f})
|
||||
.min(0.0f)
|
||||
.max(100.0f)
|
||||
.description("PLACE HOLDER");
|
||||
b.add_input<decl::Float>("Roughness")
|
||||
.default_value(0.5f)
|
||||
.min(0.0f)
|
||||
|
@ -37,11 +47,13 @@ static void node_declare(NodeDeclarationBuilder &b)
|
|||
static void node_shader_buts_conductor(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
|
||||
{
|
||||
uiItemR(layout, ptr, "distribution", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
|
||||
uiItemR(layout, ptr, "fresnel_type", UI_ITEM_R_SPLIT_EMPTY_NAME, "", ICON_NONE);
|
||||
}
|
||||
|
||||
static void node_shader_init_conductor(bNodeTree * /*ntree*/, bNode *node)
|
||||
{
|
||||
node->custom1 = SHD_GLOSSY_MULTI_GGX;
|
||||
node->custom2 = SHD_ARTISTIC_CONDUCTOR;
|
||||
}
|
||||
|
||||
static int node_shader_gpu_bsdf_conductor(GPUMaterial *mat,
|
||||
|
@ -50,16 +62,37 @@ static int node_shader_gpu_bsdf_conductor(GPUMaterial *mat,
|
|||
GPUNodeStack *in,
|
||||
GPUNodeStack *out)
|
||||
{
|
||||
if (!in[5].link) {
|
||||
GPU_link(mat, "world_normals_get", &in[5].link);
|
||||
if (!in[7].link) {
|
||||
GPU_link(mat, "world_normals_get", &in[7].link);
|
||||
}
|
||||
|
||||
GPU_material_flag_set(mat, GPU_MATFLAG_GLOSSY);
|
||||
|
||||
float use_multi_scatter = (node->custom1 == SHD_GLOSSY_MULTI_GGX) ? 1.0f : 0.0f;
|
||||
float use_complex_ior = (node->custom2 == SHD_CONDUCTOR) ? 1.0f : 0.0f;
|
||||
|
||||
return GPU_stack_link(
|
||||
mat, node, "node_bsdf_conductor", in, out, GPU_constant(&use_multi_scatter));
|
||||
return GPU_stack_link(mat,
|
||||
node,
|
||||
"node_bsdf_conductor",
|
||||
in,
|
||||
out,
|
||||
GPU_constant(&use_multi_scatter),
|
||||
GPU_constant(&use_complex_ior));
|
||||
}
|
||||
|
||||
static void node_shader_update_conductor(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
const int fresnel_method = node->custom2;
|
||||
|
||||
bke::nodeSetSocketAvailability(
|
||||
ntree, nodeFindSocket(node, SOCK_IN, "Base Color"), fresnel_method != SHD_CONDUCTOR);
|
||||
bke::nodeSetSocketAvailability(
|
||||
ntree, nodeFindSocket(node, SOCK_IN, "Edge Tint"), fresnel_method != SHD_CONDUCTOR);
|
||||
bke::nodeSetSocketAvailability(
|
||||
ntree, nodeFindSocket(node, SOCK_IN, "IOR"), fresnel_method == SHD_CONDUCTOR);
|
||||
bke::nodeSetSocketAvailability(ntree,
|
||||
nodeFindSocket(node, SOCK_IN, "Extinction Coefficient"),
|
||||
fresnel_method == SHD_CONDUCTOR);
|
||||
}
|
||||
|
||||
NODE_SHADER_MATERIALX_BEGIN
|
||||
|
@ -70,7 +103,7 @@ NODE_SHADER_MATERIALX_BEGIN
|
|||
}
|
||||
|
||||
NodeItem color = get_input_value("Color", NodeItem::Type::Color3);
|
||||
NodeItem tint = get_input_value("Tint", NodeItem::Type::Color3);
|
||||
NodeItem edge_tint = get_input_value("Edge Tint", NodeItem::Type::Color3);
|
||||
NodeItem roughness = get_input_value("Roughness", NodeItem::Type::Vector2);
|
||||
NodeItem anisotropy = get_input_value("Anisotropy", NodeItem::Type::Color3);
|
||||
NodeItem normal = get_input_link("Normal", NodeItem::Type::Vector3);
|
||||
|
@ -78,7 +111,7 @@ NODE_SHADER_MATERIALX_BEGIN
|
|||
|
||||
NodeItem artistic_ior = create_node("artistic_ior",
|
||||
NodeItem::Type::Multioutput,
|
||||
{{"reflectivity", color}, {"edge_color", tint}});
|
||||
{{"reflectivity", color}, {"edge_color", edge_tint}});
|
||||
NodeItem ior_out = artistic_ior.add_output("ior", NodeItem::Type::Color3);
|
||||
NodeItem extinction_out = artistic_ior.add_output("extinction", NodeItem::Type::Color3);
|
||||
|
||||
|
@ -106,9 +139,10 @@ void register_node_type_sh_bsdf_conductor()
|
|||
ntype.declare = file_ns::node_declare;
|
||||
ntype.add_ui_poll = object_shader_nodes_poll;
|
||||
ntype.draw_buttons = file_ns::node_shader_buts_conductor;
|
||||
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::MIDDLE);
|
||||
blender::bke::node_type_size_preset(&ntype, blender::bke::eNodeSizePreset::LARGE);
|
||||
ntype.initfunc = file_ns::node_shader_init_conductor;
|
||||
ntype.gpu_fn = file_ns::node_shader_gpu_bsdf_conductor;
|
||||
ntype.updatefunc = file_ns::node_shader_update_conductor;
|
||||
ntype.materialx_fn = file_ns::node_shader_materialx;
|
||||
|
||||
nodeRegisterType(&ntype);
|
||||
|
|
Loading…
Reference in New Issue