From 57aa99e964078a97d7bf070f79ca265ca971b61b Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Fri, 10 Nov 2023 12:57:23 -0800 Subject: [PATCH] Fix (again) the shadow transform - we were not using the correct field in ShadowMapManager - we were not computing the transform correctly, it should applied after the local transform, not before. FIXES=[299310624] --- filament/src/ShadowMap.cpp | 2 +- filament/src/ShadowMapManager.cpp | 2 +- filament/src/details/Scene.cpp | 14 ++++++-------- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/filament/src/ShadowMap.cpp b/filament/src/ShadowMap.cpp index 3bc93e90b6..e4d7f67be0 100644 --- a/filament/src/ShadowMap.cpp +++ b/filament/src/ShadowMap.cpp @@ -115,7 +115,6 @@ ShadowMap::ShaderParameters ShadowMap::updateDirectional(FEngine& engine, FLightManager::Instance const li = lightData.elementAt(index); FLightManager::ShadowParams const params = lcm.getShadowParams(li); - // We can't use LISPSM in stable mode const auto direction = lightData.elementAt(index); auto [Mv, znear, zfar, lsClippedShadowVolume, vertexCount, visibleShadows] = @@ -140,6 +139,7 @@ ShadowMap::ShaderParameters ShadowMap::updateDirectional(FEngine& engine, */ mat4f W, Wp, L; + // We can't use LISPSM in stable mode const bool useLispsm = params.options.lispsm && !params.options.stable; if (useLispsm) { // Orient the shadow map in the direction of the view vector by constructing a diff --git a/filament/src/ShadowMapManager.cpp b/filament/src/ShadowMapManager.cpp index c24e18b430..8f34fd5e5d 100644 --- a/filament/src/ShadowMapManager.cpp +++ b/filament/src/ShadowMapManager.cpp @@ -522,7 +522,7 @@ ShadowMapManager::ShadowTechnique ShadowMapManager::updateCascadeShadowMaps(FEng // entire camera frustum, as if we only had a single cascade. ShadowMap& shadowMap = cascadedShadowMaps[0]; - const auto direction = options.transform * lightData.elementAt(0); + const auto direction = lightData.elementAt(0); // We compute the directional light's model matrix using the origin's as the light position. // The choice of the light's origin initially doesn't matter for a directional light. diff --git a/filament/src/details/Scene.cpp b/filament/src/details/Scene.cpp index 2d2a99746b..942fb1e24f 100644 --- a/filament/src/details/Scene.cpp +++ b/filament/src/details/Scene.cpp @@ -267,16 +267,16 @@ void FScene::prepare(utils::JobSystem& js, // in the code below, we only transform directions, so the translation of the // world transform is irrelevant, and we don't need to use getWorldTransformAccurate() + mat3 const worldDirectionTransform = + mat3::getTransformForNormals(tcm.getWorldTransformAccurate(ti).upperLeft()); FLightManager::ShadowParams const params = lcm.getShadowParams(li); - float3 const localDirection = lcm.getLocalDirection(li); - float3 const shadowLocalDirection = params.options.transform * localDirection; - mat3 const worldDirectionTransform = tcm.getWorldTransformAccurate(ti).upperLeft(); - mat3 const shaderWorldTransform = worldTransform.upperLeft() * worldDirectionTransform; + float3 const localDirection = worldDirectionTransform * lcm.getLocalDirection(li); + double3 const shadowLocalDirection = params.options.transform * localDirection; // using mat3::getTransformForNormals handles non-uniform scaling // note: in the common case of the rigid-body transform, getTransformForNormals() returns // identity. - mat3 const worlTransformNormals = mat3::getTransformForNormals(shaderWorldTransform); + mat3 const worlTransformNormals = mat3::getTransformForNormals(worldTransform.upperLeft()); double3 const d = worlTransformNormals * localDirection; double3 const s = worlTransformNormals * shadowLocalDirection; @@ -290,10 +290,8 @@ void FScene::prepare(utils::JobSystem& js, // is pointing down, which is a common case for lights. See ShadowMap.cpp. return transpose(mat3::lookTo(direction, double3{ 1, 0, 0 })); }; - double3 const worldDirection = - mat3::getTransformForNormals(worldDirectionTransform) * shadowLocalDirection; double3 const worldOrigin = transpose(worldTransform.upperLeft()) * worldTransform[3].xyz; - mat3 const Mv = getMv(worldDirection); + mat3 const Mv = getMv(shadowLocalDirection); double2 const lsReferencePoint = (Mv * worldOrigin).xy; constexpr float inf = std::numeric_limits::infinity();