[Bf-blender-cvs] [552abb838c7] principled-v2: Replace metallic Fresnel with F82 model
Lukas Stockner
noreply at git.blender.org
Sun Jul 24 03:54:26 CEST 2022
Commit: 552abb838c76d44a0d7d1226b59a1ab381e88386
Author: Lukas Stockner
Date: Sun Jul 24 03:40:57 2022 +0200
Branches: principled-v2
https://developer.blender.org/rB552abb838c76d44a0d7d1226b59a1ab381e88386
Replace metallic Fresnel with F82 model
===================================================================
M intern/cycles/app/cycles_precompute.cpp
M intern/cycles/kernel/closure/bsdf_microfacet.h
M intern/cycles/kernel/closure/bsdf_microfacet_util.h
M intern/cycles/kernel/closure/bsdf_util.h
M intern/cycles/kernel/svm/closure_principled.h
M intern/cycles/scene/shader_nodes.cpp
M intern/cycles/scene/shader_nodes.h
M source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
M source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc
===================================================================
diff --git a/intern/cycles/app/cycles_precompute.cpp b/intern/cycles/app/cycles_precompute.cpp
index 4ce62d2298a..26be3f16f3a 100644
--- a/intern/cycles/app/cycles_precompute.cpp
+++ b/intern/cycles/app/cycles_precompute.cpp
@@ -242,8 +242,7 @@ static float precompute_ggx_dielectric_E(float rough, float mu, float eta, float
bsdf.ior = eta;
bsdf.extra = (MicrofacetExtra *)&extra;
bsdf.T = make_float3(1.0f, 0.0f, 0.0f);
- extra.metal_base = extra.metal_edge = zero_float3();
- extra.metal_falloff = 0.0f;
+ extra.metallic = extra.metal_base = extra.metal_edge_factor = zero_float3();
/* Dependency warning - this relies on the ggx_E and ggx_E_avg lookup tables! */
float E = microfacet_ggx_E(mu, rough), E_avg = microfacet_ggx_E_avg(rough);
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index 5c7e70181d7..4fe36b5f235 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -19,8 +19,8 @@ typedef struct MicrofacetExtra {
typedef struct MicrofacetExtrav2 {
/* Metallic fresnel control */
- float3 metal_base, metal_edge;
- float metal_falloff;
+ float3 metal_base, metal_edge_factor;
+ float3 metallic;
float dielectric;
} MicrofacetExtrav2;
@@ -66,8 +66,8 @@ ccl_device_forceinline float3 reflection_color(ccl_private const MicrofacetBsdf
/* Metallic Fresnel: Kinda Schlick-Fresnel-like with configurable F0 and F90
* as well as falloff control. F90=white and falloff=0.2 gives classic Schlick Fresnel.
* Metallic factor and albedo scaling is baked into the F0 and F90 parameters. */
- float metallicBlend = powf(1.0f - cosHL, extra->metal_falloff);
- float3 metallic = mix(extra->metal_base, extra->metal_edge, metallicBlend);
+ float3 metallic = extra->metallic *
+ fresnel_metallic(extra->metal_base, extra->metal_edge_factor, cosHL);
/* Dielectric Fresnel, just basic IOR control. */
float dielectric = extra->dielectric * fresnel_dielectric_cos(cosHL, bsdf->ior);
@@ -187,18 +187,13 @@ ccl_device int bsdf_microfacet_ggx_fresnel_v2_setup(KernelGlobals kg,
MicrofacetExtrav2 *extra = (MicrofacetExtrav2 *)bsdf->extra;
if (metallic > 0.0f) {
- extra->metal_base = saturate(extra->metal_base);
- extra->metal_edge = saturate(extra->metal_edge);
- extra->metal_falloff = 1.0f / clamp(extra->metal_falloff, 1e-3f, 1.0f);
- float3 metal_Fss = metallic_Fss(extra->metal_base, extra->metal_edge, extra->metal_falloff);
- float3 metal_scale = microfacet_ggx_albedo_scaling(kg, bsdf, sd, metal_Fss);
- extra->metal_base *= metallic * metal_scale;
- extra->metal_edge *= metallic * metal_scale;
+ float3 metal_Fss = fresnel_metallic_Fss(extra->metal_base, extra->metal_edge_factor);
+ extra->metallic = metallic * microfacet_ggx_albedo_scaling(kg, bsdf, sd, metal_Fss);
}
else {
- extra->metal_falloff = 0.0f;
+ extra->metallic = zero_float3();
extra->metal_base = zero_float3();
- extra->metal_edge = zero_float3();
+ extra->metal_edge_factor = zero_float3();
}
if (dielectric > 0.0f) {
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_util.h b/intern/cycles/kernel/closure/bsdf_microfacet_util.h
index a1399bff5fe..a5c77763133 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_util.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_util.h
@@ -131,16 +131,14 @@ ccl_device_forceinline float clearcoat_E(KernelGlobals kg, float mu, float rough
return table * fresnel_dielectric_cos(mu, 1.5f);
}
-ccl_device_inline float3 metallic_Fss(float3 F0, float3 F90, float falloff)
+ccl_device_inline float3 fresnel_metallic_Fss(float3 F0, float3 B)
{
- /* Fss for mix(F0, F90, (1-cosNI)^falloff) */
- return mix(F0, F90, 2.0f / (sqr(falloff) + 3 * falloff + 2));
+ return saturate(mix(F0, one_float3(), 1.0f / 21.0f) - B * (1.0f / 126.0f));
}
ccl_device_inline float3 schlick_fresnel_Fss(float3 F0)
{
- /* TODO validate using multiGGX code */
- return (one_float3() + 20.0f * saturate(F0)) * (1.0f / 21.0f);
+ return saturate(mix(F0, one_float3(), 1.0f / 21.0f));
}
/* TODO Imageworks source */
diff --git a/intern/cycles/kernel/closure/bsdf_util.h b/intern/cycles/kernel/closure/bsdf_util.h
index 47ace534440..39ac4161c6e 100644
--- a/intern/cycles/kernel/closure/bsdf_util.h
+++ b/intern/cycles/kernel/closure/bsdf_util.h
@@ -109,6 +109,32 @@ ccl_device float schlick_fresnel(float u)
return m2 * m2 * m; // pow(m, 5)
}
+/* Metallic Fresnel term with edge color control.
+ * Based on Schlick Fresnel, but with an optional F82 input that adds the dip at
+ * near-grazing angles that is characteristic for conductors.
+ *
+ * Source:
+ * https://substance3d.adobe.com/documentation/s3d/files/225969599/225969601/1/1647019577092/Adobe+Standard+Material+-+Technical+Documentation.pdf
+ */
+ccl_device float3 metallic_edge_factor(float3 F0, float3 F82)
+{
+ if (F82 == one_float3()) {
+ return zero_float3();
+ }
+
+ /* Precompute the B factor of the F82 model, which scales an additional term around cosI == 1/7. */
+ const float f = 6.0f / 7.0f; /* 1 - cosI_max */
+ const float f5 = sqr(sqr(f)) * f;
+ return (7.0f / (f5 * f)) * mix(F0, one_float3(), f5) * (one_float3() - F82);
+}
+
+ccl_device float3 fresnel_metallic(float3 F0, float3 B, float cosi)
+{
+ float s = saturatef(1.0f - cosi);
+ float s5 = sqr(sqr(s)) * s;
+ return saturate(mix(F0, one_float3(), s5) - B * cosi * s5 * s);
+}
+
/* Calculate the fresnel color which is a blend between white and the F0 color */
ccl_device_forceinline float3 interpolate_fresnel_color(float3 L, float3 H, float ior, float3 F0)
{
diff --git a/intern/cycles/kernel/svm/closure_principled.h b/intern/cycles/kernel/svm/closure_principled.h
index d352cac2fcc..c4a74a4da13 100644
--- a/intern/cycles/kernel/svm/closure_principled.h
+++ b/intern/cycles/kernel/svm/closure_principled.h
@@ -613,9 +613,9 @@ ccl_device_inline float principled_v2_specular(KernelGlobals kg,
return 0.0f;
}
- uint falloff_offset, edge_offset, dummy;
+ uint edge_offset, dummy;
uint aniso_offset, rotation_offset, tangent_offset;
- svm_unpack_node_uchar4(data1, &falloff_offset, &edge_offset, &dummy, &dummy);
+ svm_unpack_node_uchar4(data1, &dummy, &edge_offset, &dummy, &dummy);
svm_unpack_node_uchar4(data2, &aniso_offset, &rotation_offset, &tangent_offset, &dummy);
/* This function handles two specular components:
@@ -632,6 +632,7 @@ ccl_device_inline float principled_v2_specular(KernelGlobals kg,
T = stack_load_float3(stack, tangent_offset);
T = rotate_around_axis(T, N, stack_load_float(stack, rotation_offset) * M_2PI_F);
}
+ float3 edge_color = stack_load_float3(stack, edge_offset);
ccl_private MicrofacetBsdf *bsdf = (ccl_private MicrofacetBsdf *)bsdf_alloc(
sd, sizeof(MicrofacetBsdf), weight);
@@ -653,8 +654,7 @@ ccl_device_inline float principled_v2_specular(KernelGlobals kg,
bsdf->alpha_y = sqr(roughness) * aspect;
extra->metal_base = base_color;
- extra->metal_edge = stack_load_float3(stack, edge_offset);
- extra->metal_falloff = stack_load_float(stack, falloff_offset);
+ extra->metal_edge_factor = metallic_edge_factor(base_color, edge_color);
float dielectric = (1.0f - metallic) * (1.0f - transmission);
sd->flag |= bsdf_microfacet_ggx_fresnel_v2_setup(kg, bsdf, sd, metallic, dielectric);
diff --git a/intern/cycles/scene/shader_nodes.cpp b/intern/cycles/scene/shader_nodes.cpp
index f8412a430d1..3a11b9301e2 100644
--- a/intern/cycles/scene/shader_nodes.cpp
+++ b/intern/cycles/scene/shader_nodes.cpp
@@ -2744,7 +2744,6 @@ NODE_DEFINE(PrincipledBsdfNode)
SOCKET_IN_COLOR(base_color, "Base Color", make_float3(0.8f, 0.8f, 0.8f));
SOCKET_IN_COLOR(subsurface_color, "Subsurface Color", make_float3(0.8f, 0.8f, 0.8f));
SOCKET_IN_FLOAT(metallic, "Metallic", 0.0f);
- SOCKET_IN_FLOAT(metallic_falloff, "Metallic Falloff", 0.2f);
SOCKET_IN_COLOR(metallic_edge, "Metallic Edge", make_float3(1.0f, 1.0f, 1.0f));
SOCKET_IN_FLOAT(subsurface, "Subsurface", 0.0f);
SOCKET_IN_FLOAT(subsurface_scale, "Subsurface Scale", 0.0f);
@@ -2930,7 +2929,7 @@ void PrincipledBsdfNode::compile_v2(SVMCompiler &compiler)
compiler.stack_assign(input("Subsurface Anisotropy")),
compiler.stack_assign(input("Subsurface Radius")),
subsurface_method);
- uint metallic = compiler.encode_uchar4(compiler.stack_assign(input("Metallic Falloff")),
+ uint metallic = compiler.encode_uchar4(SVM_STACK_INVALID,
compiler.stack_assign(input("Metallic Edge")),
SVM_STACK_INVALID,
distribution);
diff --git a/intern/cycles/scene/shader_nodes.h b/intern/cycles/scene/shader_nodes.h
index 37823fb199b..bec1a70f4b5 100644
--- a/intern/cycles/scene/shader_nodes.h
+++ b/intern/cycles/scene/shader_nodes.h
@@ -536,7 +536,6 @@ class PrincipledBsdfNode : public BsdfBaseNode {
NODE_SOCKET_API(float, subsurface_ior)
NODE_SOCKET_API(float, subsurface_anisotropy)
NODE_SOCKET_API(float, metallic)
- NODE_SOCKET_API(float, metallic_falloff)
NODE_SOCKET_API(float3, metallic_edge)
NODE_SOCKET_API(float, subsurface)
NODE_SOCKET_API(float, subsurface_scale)
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
index 8b4936b6fb3..3e3af51c15a 100644
--- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
+++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl
@@ -22,7 +22,6 @@ void node_bsdf_principled(vec4 base_color,
float subsurface_anisotropy,
float metallic,
vec4 metallic_edge, //todo
- float metallic_falloff, //todo
float specular,
float specular_tint,
float roughness,
diff --git a/source/blender/nodes/shader/nodes/no
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list