Reposting, as previous topic seems to have imploded.
For most of the part, the cascaded shadow mapping works as intended, but at certain angles shadows are cut. I believe it might be because of how I determine what split to use.
I do the split comparison in view space, see below:
#version 420
const float DEPTH_BIAS = 0.00005;
layout(std140) uniform UnifDirLight
{
mat4 mVPMatrix[4];
mat4 mCamViewMatrix;
vec4 mSplitDistance;
vec4 mLightColor;
vec4 mLightDir;
vec4 mGamma;
vec2 mScreenSize;
} UnifDirLightPass;
layout (binding = 2) uniform sampler2D unifPositionTexture;
layout (binding = 3) uniform sampler2D unifNormalTexture;
layout (binding = 4) uniform sampler2D unifDiffuseTexture;
layout (binding = 6) uniform sampler2DArrayShadow unifShadowTexture;
out vec4 fragColor;
void main()
{
vec2 texcoord = gl_FragCoord.xy / UnifDirLightPass.mScreenSize;
vec3 worldPos = texture(unifPositionTexture, texcoord).xyz;
vec3 normal = normalize(texture(unifNormalTexture, texcoord).xyz);
vec3 diffuse = texture(unifDiffuseTexture, texcoord).xyz;
vec4 camPos = UnifDirLightPass.mCamViewMatrix * vec4(worldPos, 1.0); // putting the world position in the main cameras view space
int index = 3;
if (camPos .z > UnifDirLightPass.mSplitDistance.x)
index = 0;
else if (camPos .z > UnifDirLightPass.mSplitDistance.y)
index = 1;
else if (camPos .z > UnifDirLightPass.mSplitDistance.z)
index = 2;
vec4 projCoords = UnifDirLightPass.mVPMatrix[index] * vec4(worldPos, 1.0);
projCoords.w = projCoords.z - DEPTH_BIAS;
projCoords.z = float(index);
float visibilty = texture(unifShadowTexture, projCoords);
float angleNormal = clamp(dot(normal, UnifDirLightPass.mLightDir.xyz), 0, 1);
fragColor = vec4(diffuse, 1.0) * visibilty * angleNormal * UnifDirLightPass.mLightColor;
}
When I calculate the split frustrum I also store the current splits far distance for use in the shader above
CameraFrustrum CalculateCameraFrustrum(const float minDist, const float maxDist, const Vec3& cameraPosition, const Vec3& cameraDirection, Vec4& camFarDist, const Mat4& camView)
{
CameraFrustrum ret = { 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),
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 = glm::perspective(70.0f, 1920.0f / (float)1080.0f, minDist, maxDist);
const Mat4 invMVP = glm::inverse(perspectiveMatrix * camView);
for (Vec4& v : ret)
{
v = invMVP * v;
v /= v.w;
}
camFarDist= ret[4];
camFarDist+= ret[5];
camFarDist+= ret[6];
camFarDist+= ret[7];
camFarDist/= 4;
camFarDist = camView * camFarDist; // putting it in main camera view space
// camFarDist.z is used as this splits far distance for the comparison in the shader
return ret;
}
Does this look correct?