I code ommidirectional shadow mapping by c++ directx 11. I took algorithm from book: "HLSL Development Cookbook" by Doron Feinstein. But if my screen resolution and all dependences are different with resolution of shadow map, the shadows are in wrong place and projected incorectly. How I can fix it?
XMMATRIX* PointLight::GetCubeViewProjection()
{
XMMATRIX lightProjection, positionMatrix, spotView, toShadow;
RebuildWorldMatrixPosition();
XMFLOAT3 worldPosition = this->GetWorldPosition();
positionMatrix = XMMatrixTranslation(-worldPosition.x, -worldPosition.y, -worldPosition.z);
lightProjection = XMMatrixPerspectiveFovLH(XM_PIDIV2, 1.0f, SHADOW_NEAR_PLANE, m_radius);
// Cube +X
spotView = XMMatrixRotationY(XM_PI + XM_PIDIV2);
toShadow = positionMatrix * spotView * lightProjection;
m_cubeViewProjection[0] = XMMatrixTranspose(toShadow);
// Cube -X
spotView = XMMatrixRotationY(XM_PIDIV2);
toShadow = positionMatrix * spotView * lightProjection;
m_cubeViewProjection[1] = XMMatrixTranspose(toShadow);
// Cube +Y
spotView = XMMatrixRotationX(XM_PIDIV2);
toShadow = positionMatrix * spotView * lightProjection;
m_cubeViewProjection[2] = XMMatrixTranspose(toShadow);
// Cube -Y
spotView = XMMatrixRotationX(XM_PI + XM_PIDIV2);
toShadow = positionMatrix * spotView * lightProjection;
m_cubeViewProjection[3] = XMMatrixTranspose(toShadow);
// Cube +Z
toShadow = positionMatrix * lightProjection;
m_cubeViewProjection[4] = XMMatrixTranspose(toShadow);
// Cube -Z
spotView = XMMatrixRotationY(XM_PI);
toShadow = positionMatrix * spotView * lightProjection;
m_cubeViewProjection[5] = XMMatrixTranspose(toShadow);
return m_cubeViewProjection;
}
cbuffer WorldMatrixBuffer : register( b0 )
{
matrix worldMatrix;
};
//vertex shadow gen shader
float4 PointShadowGenVS(float4 Pos : POSITION) : SV_Position
{
Pos.w = 1.0f;
return mul(Pos, worldMatrix);
}
//geometry shadow gen shader
cbuffer ShadowMapCubeViewProj : register( b0 )
{
float4x4 cubeViewProj[6] : packoffset(c0);
};
struct GS_OUTPUT
{
float4 Pos: SV_POSITION;
uint RTIndex : SV_RenderTargetArrayIndex;
};
[maxvertexcount(18)]
void PointShadowGenGS(triangle float4 InPos[3] : SV_Position, inout TriangleStream<GS_OUTPUT> OutStream)
{
for (int iFace = 0; iFace < 6; ++iFace)
{
GS_OUTPUT output;
output.RTIndex = iFace;
for (int v = 0; v < 3; ++v)
{
output.Pos = mul(InPos[v], cubeViewProj[iFace]);
OutStream.Append(output);
}
OutStream.RestartStrip();
}
}
//point light pixel shader
float PointShadowPCF(float3 toPixel)
{
float3 toPixelAbs = abs(toPixel);
float z = max(toPixelAbs.x, max(toPixelAbs.y, toPixelAbs.z));
float depth = (lightPerspectiveValues.x * z + lightPerspectiveValues.y) / z;
return pointShadowMapTexture.SampleCmpLevelZero(PCFSampler, toPixel, depth).x;
}
float shadowAttenuation = PointShadowPCF(worldPosition - lightPosition);