CSM shadow errors when models are split
Posted
by
KaiserJohaan
on Game Development
See other posts from Game Development
or by KaiserJohaan
Published on 2014-08-21T21:47:22Z
Indexed on
2014/08/23
22:36 UTC
Read the original article
Hit count: 357
I'm getting closer to fixing CSM, but there seems to be one more issue at hand.
At certain angles, the models will be caught/split between two shadow map cascades, like below.
first depth split
second depth split - here you can see the model is caught between the splits
How does one fix this? Increase the overlapping boundaries between the splits? Or is the frustrum erronous?
CameraFrustrum CalculateCameraFrustrum(const float fovDegrees, const float aspectRatio, const float minDist, const float maxDist, const Mat4& cameraViewMatrix, Mat4& outFrustrumMat)
{
CameraFrustrum ret = { Vec4(1.0f, -1.0f, 0.0f, 1.0f), Vec4(1.0f, 1.0f, 0.0f, 1.0f), Vec4(-1.0f, 1.0f, 0.0f, 1.0f), Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
Vec4(1.0f, -1.0f, 1.0f, 1.0f), Vec4(1.0f, 1.0f, 1.0f, 1.0f), Vec4(-1.0f, 1.0f, 1.0f, 1.0f), Vec4(-1.0f, -1.0f, 1.0f, 1.0f), };
const Mat4 perspectiveMatrix = PerspectiveMatrixFov(fovDegrees, aspectRatio, minDist, maxDist);
const Mat4 invMVP = glm::inverse(perspectiveMatrix * cameraViewMatrix);
outFrustrumMat = invMVP;
for (Vec4& corner : ret)
{
corner = invMVP * corner;
corner /= corner.w;
}
return ret;
}
Mat4 CreateDirLightVPMatrix(const CameraFrustrum& cameraFrustrum, const Vec3& lightDir)
{
Mat4 lightViewMatrix = glm::lookAt(Vec3(0.0f), -glm::normalize(lightDir), Vec3(0.0f, -1.0f, 0.0f));
Vec4 transf = lightViewMatrix * cameraFrustrum[0];
float maxZ = transf.z, minZ = transf.z;
float maxX = transf.x, minX = transf.x;
float maxY = transf.y, minY = transf.y;
for (uint32_t i = 1; i < 8; i++)
{
transf = lightViewMatrix * cameraFrustrum[i];
if (transf.z > maxZ) maxZ = transf.z;
if (transf.z < minZ) minZ = transf.z;
if (transf.x > maxX) maxX = transf.x;
if (transf.x < minX) minX = transf.x;
if (transf.y > maxY) maxY = transf.y;
if (transf.y < minY) minY = transf.y;
}
Mat4 viewMatrix(lightViewMatrix);
viewMatrix[3][0] = -(minX + maxX) * 0.5f;
viewMatrix[3][1] = -(minY + maxY) * 0.5f;
viewMatrix[3][2] = -(minZ + maxZ) * 0.5f;
viewMatrix[0][3] = 0.0f;
viewMatrix[1][3] = 0.0f;
viewMatrix[2][3] = 0.0f;
viewMatrix[3][3] = 1.0f;
Vec3 halfExtents((maxX - minX) * 0.5, (maxY - minY) * 0.5, (maxZ - minZ) * 0.5);
return OrthographicMatrix(-halfExtents.x, halfExtents.x, halfExtents.y, -halfExtents.y, halfExtents.z, -halfExtents.z) * viewMatrix;
}
© Game Development or respective owner