[Bf-blender-cvs] [afda0ed4ea3] principled-v2: Add microfacet-Fresnel-based GGX Glass closure
Lukas Stockner
noreply at git.blender.org
Mon Jul 4 23:56:12 CEST 2022
Commit: afda0ed4ea3456d2e934826d768056100e497f9a
Author: Lukas Stockner
Date: Mon Jul 4 23:31:47 2022 +0200
Branches: principled-v2
https://developer.blender.org/rBafda0ed4ea3456d2e934826d768056100e497f9a
Add microfacet-Fresnel-based GGX Glass closure
===================================================================
M intern/cycles/kernel/CMakeLists.txt
M intern/cycles/kernel/closure/bsdf.h
A intern/cycles/kernel/closure/bsdf_microfacet_glass.h
A intern/cycles/kernel/svm/closure_principled.h
===================================================================
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 7948031ec40..face2b80f44 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -103,6 +103,7 @@ set(SRC_KERNEL_CLOSURE_HEADERS
closure/bsdf_microfacet_beckmann.h
closure/bsdf_microfacet_multi.h
closure/bsdf_microfacet_multi_impl.h
+ closure/bsdf_microfacet_glass.h
closure/bsdf_microfacet_util.h
closure/bsdf_oren_nayar.h
closure/bsdf_phong_ramp.h
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index 76b2e7ab89b..90e39e28334 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -12,6 +12,7 @@
#include "kernel/closure/bsdf_microfacet.h"
#include "kernel/closure/bsdf_microfacet_beckmann.h"
#include "kernel/closure/bsdf_microfacet_multi.h"
+#include "kernel/closure/bsdf_microfacet_glass.h"
#include "kernel/closure/bsdf_reflection.h"
#include "kernel/closure/bsdf_refraction.h"
#include "kernel/closure/bsdf_transparent.h"
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_glass.h b/intern/cycles/kernel/closure/bsdf_microfacet_glass.h
new file mode 100644
index 00000000000..d1e3f178275
--- /dev/null
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_glass.h
@@ -0,0 +1,245 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#pragma once
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device int bsdf_microfacet_multi_ggx_glass_setup(ccl_private MicrofacetBsdf *bsdf,
+ ccl_private const ShaderData *sd,
+ const float3 color)
+{
+ bsdf->extra = NULL;
+
+ bsdf->alpha_x = saturatef(bsdf->alpha_x);
+ bsdf->alpha_y = bsdf->alpha_x;
+
+ bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_ID;
+
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
+}
+
+ccl_device int bsdf_microfacet_multi_ggx_glass_fresnel_setup(ccl_private MicrofacetBsdf *bsdf,
+ ccl_private const ShaderData *sd)
+{
+ bsdf->extra->cspec0 = saturate(bsdf->extra->cspec0);
+
+ bsdf->alpha_x = saturatef(bsdf->alpha_x);
+ bsdf->alpha_y = bsdf->alpha_x;
+
+ bsdf->type = CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID;
+
+ bsdf_microfacet_fresnel_color(sd, bsdf);
+
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG;
+}
+
+ccl_device float3 bsdf_microfacet_ggx_glass_eval_reflect(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
+{
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ float alpha_x = bsdf->alpha_x;
+ float alpha_y = bsdf->alpha_y;
+ kernel_assert(alpha_x * alpha_y > 1e-7f);
+ float3 N = bsdf->N;
+
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
+ if (cosNI <= 0 || cosNO <= 0) {
+ *pdf = 0.0f;
+ return zero_float3();
+ }
+
+ float3 m = normalize(omega_in + I);
+ float alpha2 = alpha_x * alpha_y;
+ float D = microfacet_ggx_D(dot(N, m), alpha2);
+ float lambdaO = microfacet_ggx_lambda(cosNO, alpha2);
+ float lambdaI = microfacet_ggx_lambda(cosNI, alpha2);
+
+ float common = D * 0.25f / cosNO;
+
+ float F = fresnel_dielectric_cos(dot(m, I), bsdf->ior);
+ float out = F * common / (1 + lambdaO + lambdaI);
+ *pdf = common / (1 + lambdaO);
+
+ float3 eval = make_float3(out, out, out);
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID) {
+ eval *= reflection_color(bsdf, omega_in, m);
+ }
+ return eval;
+}
+
+ccl_device float3 bsdf_microfacet_ggx_glass_eval_transmit(ccl_private const ShaderClosure *sc,
+ const float3 I,
+ const float3 omega_in,
+ ccl_private float *pdf)
+{
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ float alpha_x = bsdf->alpha_x;
+ float alpha_y = bsdf->alpha_y;
+ kernel_assert(alpha_x * alpha_y > 1e-7f);
+ float eta = bsdf->ior;
+ float3 N = bsdf->N;
+
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
+ if (cosNO <= 0 || cosNI >= 0) {
+ *pdf = 0.0f;
+ return zero_float3();
+ }
+
+ float3 ht = -(eta * omega_in + I);
+ float3 m = normalize(ht);
+ float cosMO = dot(m, I);
+ float cosMI = dot(m, omega_in);
+
+ float F = fresnel_dielectric_cos(cosMO, eta);
+ if (F == 1.0f) {
+ /* TIR */
+ *pdf = 0.0f;
+ return zero_float3();
+ }
+
+ float alpha2 = alpha_x * alpha_y;
+ float D = microfacet_ggx_D(dot(N, m), alpha2);
+ float lambdaO = microfacet_ggx_lambda(cosNO, alpha2);
+ float lambdaI = microfacet_ggx_lambda(cosNI, alpha2);
+
+ float Ht2 = dot(ht, ht);
+
+ float common = fabsf(cosMI * cosMO) * D * sqr(eta) / (cosNO * Ht2);
+ float out = (1.0f - F) * common / (1 + lambdaO + lambdaI);
+ *pdf = common / (1 + lambdaO);
+
+ float3 eval = make_float3(out, out, out);
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID) {
+ eval *= bsdf->extra->color;
+ }
+ return eval;
+}
+
+ccl_device int bsdf_microfacet_ggx_glass_sample(ccl_private const ShaderClosure *sc,
+ float3 Ng,
+ float3 I,
+ float3 dIdx,
+ float3 dIdy,
+ float randu,
+ float randv,
+ ccl_private float3 *eval,
+ ccl_private float3 *omega_in,
+ ccl_private float3 *domega_in_dx,
+ ccl_private float3 *domega_in_dy,
+ ccl_private float *pdf,
+ ccl_private uint *lcg_state)
+{
+ ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
+ float alpha_x = bsdf->alpha_x;
+ float alpha_y = bsdf->alpha_y;
+ kernel_assert(alpha_x * alpha_y > 1e-7f);
+ float eta = bsdf->ior;
+ float3 N = bsdf->N;
+ int label;
+
+ float cosNO = dot(N, I);
+ if (cosNO <= 0) {
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
+
+ float3 X, Y, Z = N;
+ make_orthonormals(Z, &X, &Y);
+
+ /* importance sampling with distribution of visible normals. vectors are
+ * transformed to local space before and after */
+ float3 local_O = make_float3(dot(X, I), dot(Y, I), cosNO);
+ float3 local_m = microfacet_ggx_sample_vndf(local_O, alpha_x, alpha_y, randu, randv);
+
+ float3 m = X * local_m.x + Y * local_m.y + Z * local_m.z;
+ float cosThetaM = local_m.z;
+
+ float cosMO = dot(m, I);
+ if (cosMO <= 0.0f) {
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
+
+ float3 R, T;
+#ifdef __RAY_DIFFERENTIALS__
+ float3 dRdx, dRdy, dTdx, dTdy;
+#endif
+ bool inside; /* Will never be inside, we already checked cosMO */
+ float fresnel = fresnel_dielectric(eta,
+ m,
+ I,
+ &R,
+ &T,
+#ifdef __RAY_DIFFERENTIALS__
+ dIdx,
+ dIdy,
+ &dRdx,
+ &dRdy,
+ &dTdx,
+ &dTdy,
+#endif
+ &inside);
+
+ float randw = lcg_step_float(lcg_state);
+ bool do_reflect = randw < fresnel;
+
+ /* Common microfacet model terms. */
+ float alpha2 = alpha_x * alpha_y;
+ float D = microfacet_ggx_D(cosThetaM, alpha2);
+ float lambdaO = microfacet_ggx_lambda(cosNO, alpha2);
+
+ float cosNI, common;
+ if (do_reflect) {
+ cosNI = dot(N, R);
+ if (cosNI <= 0.0f || dot(Ng, R) <= 0.0f) {
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
+
+ label = LABEL_REFLECT | LABEL_GLOSSY;
+ *omega_in = R;
+
+#ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = dRdx;
+ *domega_in_dy = dRdy;
+#endif
+
+ common = fresnel * D * 0.25f / cosNO;
+ }
+ else {
+ cosNI = dot(N, T);
+ if (cosNI >= 0.0f || dot(Ng, T) >= 0.0f) {
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
+
+ label = LABEL_TRANSMIT | LABEL_GLOSSY;
+ *omega_in = T;
+#ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = dTdx;
+ *domega_in_dy = dTdy;
+#endif
+
+ float cosMI = dot(m, *omega_in);
+ float Ht2 = sqr(eta * cosMI + cosMO);
+
+ common = (1.0f - fresnel) * D * fabsf(cosMI * cosMO) * sqr(eta) / (cosNO * Ht2);
+ }
+
+ float lambdaI = microfacet_ggx_lambda(cosNI, alpha2);
+ float out = common / (1 + lambdaO + lambdaI);
+ *pdf = common / (1 + lambdaO);
+ *eval = make_float3(out, out, out);
+
+ if (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_GLASS_FRESNEL_ID) {
+ *eval *= (label & LABEL_REFLECT) ? reflection_color(bsdf, *omega_in, m) : bsdf->extra->color;
+ }
+ return label;
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/closure_principled.h b/intern/cycles/kernel/svm/closure_principled.h
new file mode 100644
index 00000000000..50c606ece93
--- /dev/null
+++ b/intern/cycles/kernel/svm/closure_principled.h
@@ -0,0 +1,775 @@
+/* SPDX-License-Identifier: Apache-2.0
+ * Copyright 2011-2022 Blender Foundation */
+
+#pragma once
+
+CCL_NAMESPACE_BEGIN
+
+/* Principled v1 components */
+
+ccl_device_inline void principled_v1_diffuse(ccl_private ShaderData *sd,
+ float3 weight,
+ float3 base_color,
+ float diffuse_weight,
+ float3 N,
+ float roughness)
+{
+ if (dif
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list