Я делаю отображение теней для прожекторов в отложенном рендерере OpenGL 4.3.
Я пытался следовать некоторым учебным пособиям по этому вопросу и смоделировал фрагментный шейдер после него, но чего я не понимаю, так это окончательного сравнения для расчета коэффициента тени. Значения, которые я выбираю из карты глубины («unifShadowTexture
»), находятся в диапазоне [0, 1], поскольку они взяты непосредственно из буфера глубины, но как projCoords.z
фиксируется на [0, 1]? Деление на .w
ограничивает его до [0,1]? Проблема, с которой я сталкиваюсь, заключается в том, что большая часть сцены затенена, хотя этого не должно быть, например, первый этаж, на следующем изображении (не обращайте внимания на световые артефакты из-за отсутствия смещения - важным моментом является модели горят, а первый этаж нет):
const std::string gDirLightFragmentShader =
"#version 430 \n \
\n \
layout(std140) uniform; \n \
\n \
uniform UnifDirLight \n \
{ \n \
mat4 mWVPMatrix; \n \
mat4 mVPMatrix; // light view-projection matrix, pre-multiplied by the bias-matrix \n \
vec4 mLightColor; \n \
vec4 mLightDir; \n \
vec4 mGamma; \n \
vec2 mScreenSize; \n \
} UnifDirLightPass; \n \
\n \
layout (binding = 2) uniform sampler2D unifPositionTexture; \n \
layout (binding = 3) uniform sampler2D unifNormalTexture; \n \
layout (binding = 4) uniform sampler2D unifDiffuseTexture; \n \
layout (binding = 5) uniform sampler2D unifShadowTexture; \n \
\n \
out vec4 fragColor; \n \
\n \
void main() \n \
{ \n \
vec2 texcoord = gl_FragCoord.xy / UnifDirLightPass.mScreenSize; \n \
\n \
vec3 worldPos = texture(unifPositionTexture, texcoord).xyz; \n \
vec3 normal = normalize(texture(unifNormalTexture, texcoord).xyz); \n \
vec3 diffuse = texture(unifDiffuseTexture, texcoord).xyz; \n \
\n \
vec4 lightClipPos = UnifDirLightPass.mVPMatrix * vec4(worldPos, 1.0); \n \
vec3 projCoords = lightClipPos.xyz / lightClipPos.w; \n \
\n \
float depthValue = texture(unifShadowTexture, projCoords.xy).x; \n \
float visibilty = 1.0; \n \
if (depthValue < (projCoords.z)) \n \
visibilty = 0.0; \n \
\n \
float angleNormal = clamp(dot(normal, UnifDirLightPass.mLightDir.xyz), 0, 1); \n \
\n \
fragColor = vec4(diffuse, 1.0) * visibilty * angleNormal * UnifDirLightPass.mLightColor; \n \
} \n";