I know, there are some similar topics, but I don't understand the solution. I made the CSM based on this paper: http://developer.download.nvidia.com/SDK/10.5/opengl/src/cascaded_shadow_maps/doc/cascaded_shadow_maps.pdf
with some "improvements". Here is the code:
I have a matrix which is used when I create the shadows
float texOffset = 0.5f + (0.5f / (float)shadowSize);
float bias = 0.003f;
textureMat = Matrix(0.5f, 0.0f, 0.0f, 0.0f,
0.0f, -0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
texOffset, texOffset, -bias, 1.0f);
Now, here is the frustum corner's computing:
void Shadow::ComputeFrustumCorners()
{
float& camAspect = scene->camera->aspect;
Vector3& camEye = scene->camera->eyePosition;
Vector3 dir;
dir.x = scene->camera->GetView().m[0][2];
dir.y = scene->camera->GetView().m[1][2];
dir.z = scene->camera->GetView().m[2][2];
Vector3 x;
x.x = scene->camera->GetView().m[0][0];
x.y = scene->camera->GetView().m[1][0];
x.z = scene->camera->GetView().m[2][0];
Vector3 y;
y.x = scene->camera->GetView().m[0][1];
y.y = scene->camera->GetView().m[1][1];
y.z = scene->camera->GetView().m[2][1];
tanHalfFov = tanf(scene->camera->fov * 0.5f);
float nPlaneH = tanHalfFov * nearPlane;
float nPlaneW = nPlaneH * camAspect;
float fPlaneH = tanHalfFov * farPlane;
float fPlaneW = fPlaneH * camAspect;
Vector3 nPlaneX = x * nPlaneW;
Vector3 nPlaneY = y * nPlaneH;
Vector3 fPlaneX = x * fPlaneW;
Vector3 fPlaneY = y * fPlaneH;
nPlaneCenter = camEye + dir * nearPlane;
fPlaneCenter = camEye + dir * farPlane;
frustumCorners[0] = nPlaneCenter - nPlaneX - nPlaneY;
frustumCorners[1] = nPlaneCenter - nPlaneX + nPlaneY;
frustumCorners[2] = nPlaneCenter + nPlaneX + nPlaneY;
frustumCorners[3] = nPlaneCenter + nPlaneX - nPlaneY;
frustumCorners[4] = fPlaneCenter - fPlaneX - fPlaneY;
frustumCorners[5] = fPlaneCenter - fPlaneX + fPlaneY;
frustumCorners[6] = fPlaneCenter + fPlaneX + fPlaneY;
frustumCorners[7] = fPlaneCenter + fPlaneX - fPlaneY;
}
I get the x,y,z axes from the view matrix, so I don't have to compute these values.
And of course the "main part" of CSM; compute the viewproj matrix for the shadow map generation, and the "final matrix" for the "final" shadow rendering. I think I should modify this part to kill the swimming edges.
void Shadow::ComputeMatrices()
{
ComputeFrustumCorners();
view = Matrix::LookAt(Vector3::Zero, light->direction, Vector3::Up);
Vector3 min = Vector3::Max;
Vector3 max = Vector3::Min;
Vector4 transformed;
for (int i = 0; i < NUM_CORNERS; i++)
{
transformed = Vector4::Transform(frustumCorners, view);
transformed /= transformed.w;
if (transformed.x < min.x)
min.x = transformed.x;
if (transformed.y < min.y)
min.y = transformed.y;
if (transformed.z < min.z)
min.z = transformed.z;
if (transformed.x > max.x)
max.x = transformed.x;
if (transformed.y > max.y)
max.y = transformed.y;
if (transformed.z > max.z)
max.z = transformed.z;
}
float scaleX = 2.0f / (max.x - min.x);
float scaleY = 2.0f / (max.y - min.y);
float offsetX = -0.5f * (min.x + max.x) * scaleX;
float offsetY = -0.5f * (min.y + max.y) * scaleY;
cropMat.m[0][0] = scaleX;
cropMat.m[1][1] = scaleY;
cropMat.m[2][2] = 1.0f;
cropMat.m[3][0] = offsetX;
cropMat.m[3][1] = offsetY;
cropMat.m[3][3] = 1.0f;
// INFO: bias
float bias = 10.0f;
min.z -= bias;
max.z += bias;
proj = Matrix::OrthographicOffCenter(-1, 1, -1, 1, min.z, max.z);
viewProj = view * proj * cropMat;
finalMat = viewProj * textureMat;
}
So the problem is that, when I move or rotate the camera (not the light), the shadow edges are swimming / flickering. What is the solution for my code?
Thanks for all replies!