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
path: root/intern
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 /intern
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.
Diffstat (limited to 'intern')
-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;