Merge pull request #1349 from marauder2k9-torque/PSSMShadow-Map-bugfix

Fix for bug reported by Rod
This commit is contained in:
Brian Roberts 2025-01-06 10:22:51 -06:00 committed by GitHub
commit 229afa8f5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -135,29 +135,30 @@ void PSSMLightShadowMap::_calcSplitPos(const Frustum& currFrustum)
Box3F PSSMLightShadowMap::_calcClipSpaceAABB(const Frustum& f, const MatrixF& transform, F32 farDist)
{
PROFILE_SCOPE(PSSMLightShadowMap_calcClipSpaceAABB);
// Transform frustum corners to light space.
Point3F transformedPoints[8];
// Calculate frustum center
Point3F center(0, 0, 0);
const Point3F* frustumPoints = f.getPoints();
for (U32 i = 0; i < 8; i++) {
transformedPoints[i] = frustumPoints[i];
transform.mulP(transformedPoints[i]);
for (U32 i = 0; i < 8; i++)
{
const Point3F& pt = frustumPoints[i];
center += pt;
}
center /= 8;
// Compute the AABB for the transformed points.
// Calculate frustum bounding sphere radius
F32 radius = 0.0f;
for (U32 i = 0; i < 8; i++)
radius = getMax(radius, (frustumPoints[i] - center).lenSquared());
radius = mFloor(mSqrt(radius));
// Now build box for sphere
Box3F result;
result.minExtents.set(F32_MAX, F32_MAX, F32_MAX);
result.maxExtents.set(-F32_MAX, -F32_MAX, -F32_MAX);
Point3F radiusBox(radius, radius, radius);
result.minExtents = center - radiusBox;
result.maxExtents = center + radiusBox;
for (U32 i = 0; i < 8; i++) {
result.minExtents.setMin(transformedPoints[i]);
result.maxExtents.setMax(transformedPoints[i]);
}
// Clamp Z to within near and far distances to avoid over-extension.
result.minExtents.z = getMax(result.minExtents.z, 0.0f); // Z must be non-negative in light space.
result.maxExtents.z = getMin(result.maxExtents.z, farDist);
// Transform to light projection space
transform.mul(result);
return result;
}
@ -174,9 +175,10 @@ void PSSMLightShadowMap::_roundProjection(const MatrixF& lightMat, const MatrixF
lightProjection.mul(origin);
origin /= origin.w;
// Convert to texture space (based on shadow map resolution).
F32 texelWidth = mShadowMapTex->getWidth() / (mNumSplits < 4 ? mNumSplits : 2);
Point2F texelScale(texelWidth * 0.5f, mShadowMapTex->getHeight() * 0.5f);
// Convert to shadow map texel space.
const F32 texelWidth = mShadowMapTex->getWidth() / (mNumSplits < 4 ? mNumSplits : 2);
const F32 texelHeight = mShadowMapTex->getHeight();
Point2F texelScale(texelWidth * 0.5f, texelHeight * 0.5f);
// Adjust origin to align to nearest texel.
Point2F originTexelSpace(origin.x * texelScale.x, origin.y * texelScale.y);