Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Stockner <lukas.stockner@freenet.de>2022-04-30 14:49:45 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2022-04-30 14:49:45 +0300
commitac88123e29d4e07101a4fb33de28429d5e033367 (patch)
tree94608219d46a0194bd42a1cb5dabee4cb3bc1ce7
parent5c92c04518b5dc7c57c3b3a9e81b45879af2e080 (diff)
Fix T96576: Light leaking when using normal maps with Multiscatter GGX
The Multiscatter GGX code was missing the same-side checks for incoming and outgoing directions w.r.t. to shading and geometry normal. Should not be needed for the Glass variant since it intentionally has both reflection and transmission.
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet_multi.h33
1 files changed, 29 insertions, 4 deletions
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
index c646c9ef01d..10027ae9f77 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet_multi.h
@@ -438,11 +438,18 @@ ccl_device float3 bsdf_microfacet_multi_ggx_eval_reflect(ccl_private const Shade
return make_float3(0.0f, 0.0f, 0.0f);
}
+ float3 X, Y, Z;
+ Z = bsdf->N;
+
+ /* Ensure that the both directions are on the outside w.r.t. the shading normal. */
+ if (dot(Z, I) <= 0.0f || dot(Z, omega_in) <= 0.0f) {
+ *pdf = 0.0f;
+ return make_float3(0.0f, 0.0f, 0.0f);
+ }
+
bool use_fresnel = (bsdf->type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_FRESNEL_ID);
bool is_aniso = (bsdf->alpha_x != bsdf->alpha_y);
- float3 X, Y, Z;
- Z = bsdf->N;
if (is_aniso)
make_orthonormals_tangent(Z, bsdf->T, &X, &Y);
else
@@ -487,8 +494,20 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
float3 X, Y, Z;
Z = bsdf->N;
+ /* Ensure that the view direction is on the outside w.r.t. the shading normal. */
+ if (dot(Z, I) <= 0.0f) {
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
+
+ /* Special case: Extremely low roughness.
+ * Don't bother with microfacets, just do specular reflection. */
if (bsdf->alpha_x * bsdf->alpha_y < 1e-7f) {
*omega_in = 2 * dot(Z, I) * Z - I;
+ if (dot(Ng, *omega_in) <= 0.0f) {
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
*pdf = 1e6f;
*eval = make_float3(1e6f, 1e6f, 1e6f);
#ifdef __RAY_DIFFERENTIALS__
@@ -518,14 +537,20 @@ ccl_device int bsdf_microfacet_multi_ggx_sample(KernelGlobals kg,
bsdf->ior,
use_fresnel,
bsdf->extra->cspec0);
+ *omega_in = X * localO.x + Y * localO.y + Z * localO.z;
+
+ /* Ensure that the light direction is on the outside w.r.t. the geometry normal. */
+ if (dot(Ng, *omega_in) <= 0.0f) {
+ *pdf = 0.0f;
+ return LABEL_NONE;
+ }
+
if (is_aniso)
*pdf = mf_ggx_aniso_pdf(localI, localO, make_float2(bsdf->alpha_x, bsdf->alpha_y));
else
*pdf = mf_ggx_pdf(localI, localO, bsdf->alpha_x);
*eval *= *pdf;
- *omega_in = X * localO.x + Y * localO.y + Z * localO.z;
-
#ifdef __RAY_DIFFERENTIALS__
*domega_in_dx = (2 * dot(Z, dIdx)) * Z - dIdx;
*domega_in_dy = (2 * dot(Z, dIdy)) * Z - dIdy;