Im having trouble with the process of generating a light view/projection matrix that fits my camera view proejction.. I want to do this to make my directional light shadow map fit better and have a higher resolution (also I can use it for cascaded shadow maps later). I have looked at a number of examples and so on, and put together some code. However it doesn't work as hoped yet...I should note that I have naïve shadow mapping working correctly if I simply calculate the light projection using a standard orthogonal matrix and look at matrix.
here's my working, naïve method for calculating my light view and projection:
float interval = 256.0f;// 2000.0f*(1.0f / 512.0f);// 256.0f;
shadow_view.x = floor(XMVectorGetX(camPosition) / interval)*interval;
shadow_view.y = floor(XMVectorGetY(camPosition) / interval)*interval;
shadow_view.z = floor(XMVectorGetZ(camPosition) / interval)*interval;
shadow_view.pitch = 0.0f;
shadow_view.yaw = -90.0f;
shadow_view.roll = 0.0f;
//hard coded for now..
XMVECTOR lightvec = XMVectorSet(-2000.0f, 2500.0f, -2000.0f,0);
lightvec = XMVector4Normalize(lightvec);
lightvec = XMVectorMultiply(lightvec, XMVectorSet(800.0f, 800.0f, 800.0f, 0));
XMVECTOR shadow_pos = XMVectorSet(shadow_view.x, shadow_view.y, shadow_view.z, 0);
shadow_pos = XMVectorAdd(shadow_pos, lightvec);
XMVECTOR shadow_look = XMVectorSet(shadow_view.x, shadow_view.y, shadow_view.z, 0);
XMVECTOR shadow_up = XMVectorSet(0.0f, 0.0f, 1.0f, 0);
shadow_view.matShadowView = XMMatrixLookAtLH(shadow_pos, shadow_look, shadow_up);
shadow_view.matShadowProj = XMMatrixOrthographicLH(2000.0f, 2000.0f, 1.0f, 2049.0f);
But when I try this following code it just creates giant black area.. not working as hoped:
XMVECTOR vecFrustum[8];
XMMATRIX mat;
mat = XMMatrixInverse(NULL, camView*camProjection);
//create the 8 points of a cube in unit-space
vecFrustum[0] = XMVectorSet(-1.0f, -1.0f, 0.0f, 0.0f);
vecFrustum[1] = XMVectorSet(1.0f, -1.0f, 0.0f, 0.0f);
vecFrustum[2] = XMVectorSet(-1.0f, 1.0f, 0.0f, 0.0f);
vecFrustum[3] = XMVectorSet(1.0f, 1.0f, 0.0f, 0.0f);
vecFrustum[4] = XMVectorSet(-1.0f, -1.0f, 1.0f, 0.0f);
vecFrustum[5] = XMVectorSet(1.0f, -1.0f, 1.0f, 0.0f);
vecFrustum[6] = XMVectorSet(-1.0f, 1.0f, 1.0f, 0.0f);
vecFrustum[7] = XMVectorSet(1.0f, 1.0f, 1.0f, 0.0f);
for (int i = 0; i < 8; i++)
{
XMVector3TransformCoord(vecFrustum[i], mat);
}
XMVECTOR frustumCenter = vecFrustum[0];
for (int i = 1; i < 8; i++)
{
frustumCenter += vecFrustum[i];
}
frustumCenter /= 8;
shadow_pos = frustumCenter;
shadow_pos = XMVectorAdd(shadow_pos, lightvec);
shadow_view.matShadowView = XMMatrixLookAtLH(shadow_pos, frustumCenter, shadow_up);
XMVECTOR transf = XMVector3TransformCoord(vecFrustum[0], shadow_view.matShadowView);
float minZ = XMVectorGetZ(transf);
float maxZ = XMVectorGetZ(transf);
float minX = XMVectorGetX(transf);
float maxX = XMVectorGetX(transf);
float minY = XMVectorGetY(transf);
float maxY = XMVectorGetY(transf);
for (int i = 1; i < 8; i++)
{
transf = XMVector3TransformCoord(vecFrustum[i], shadow_view.matShadowView);
if (XMVectorGetZ(transf) > maxZ) maxZ = XMVectorGetZ(transf);
if (XMVectorGetZ(transf) < minZ) minZ = XMVectorGetZ(transf);
if (XMVectorGetX(transf) > maxX) maxX = XMVectorGetX(transf);
if (XMVectorGetX(transf) < minX) minX = XMVectorGetX(transf);
if (XMVectorGetY(transf) > maxY) maxY = XMVectorGetY(transf);
if (XMVectorGetY(transf) < minY) minY = XMVectorGetY(transf);
}
shadow_view.matShadowProj = XMMatrixOrthographicOffCenterLH(minX, maxX, minY, maxY, minZ, maxZ);