У меня проблемы с получением правильной координаты текстуры для выборки моей карты теней. Глядя на мой код, проблема заключается в неправильных матрицах. Это фрагментный шейдер для прохода рендеринга, где я делаю тени:
in vec2 st;
uniform sampler2D colorTexture;
uniform sampler2D normalTexture;
uniform sampler2D depthTexture;
uniform sampler2D shadowmapTexture;
uniform mat4 invProj;
uniform mat4 lightProj;
uniform vec3 lightPosition;
out vec3 color;
void main () {
vec3 clipSpaceCoords;
clipSpaceCoords.xy = st.xy * 2.0 - 1.0;
clipSpaceCoords.z = texture(depthTexture, st).x * 2.0 - 1.0;
vec4 position = invProj * vec4(clipSpaceCoords,1.0);
position.xyz /= position.w;
//At this point, position.xyz seems to be what it should be, the world space coordinates of the pixel. I know this because it works for lighting calculations.
vec4 lightSpace = lightProj * vec4(position.xyz,1.0);
//This line above is where I think things go wrong.
lightSpace.xyz /= lightSpace.w;
lightSpace.xyz = lightSpace.xyz * 0.5 + 0.5;
float lightDepth = texture(shadowmapTexture, lightSpace.xy).x;
//Right here lightDepth seems to be incorrect. The only explanation I can think of for this is if there is a problem in the above calculations leading to lightSpace.xy.
float shadowFactor = 1.0;
if(lightSpace.z > lightDepth+0.0005) {
shadowFactor = 0.2;
}
color = vec3(lightDepth);
}
Я удалил весь код, не относящийся к теням, из этого шейдера (освещение и т. Д.). Вот код, который я использую для визуализации финального прохода:
glCullFace(GL_BACK);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
postShader->UseShader();
postShader->SetUniform1I("colorTexture", 0);
postShader->SetUniform1I("normalTexture", 1);
postShader->SetUniform1I("depthTexture", 2);
postShader->SetUniform1I("shadowmapTexture", 3);
//glm::vec3 cp = camera->GetPosition();
postShader->SetUniform4FV("invProj", glm::inverse(camera->GetCombinedProjectionView()));
postShader->SetUniform4FV("lightProj", lights[0].camera->GetCombinedProjectionView());
//Again, if I had to guess, these two lines above would be part of the problem.
postShader->SetUniform3F("lightPosition", lights[0].x, lights[0].y, lights[0].z);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, frameBuffer->GetColor());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, frameBuffer->GetNormals());
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, frameBuffer->GetDepth());
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, lights[0].shadowmap->GetDepth());
this->BindPPQuad();
glDrawArrays(GL_TRIANGLES, 0, 6);
В случае, если это имеет отношение к моей проблеме, вот как я генерирую прикрепления кадрового буфера глубины для карт глубины и теней:
void FrameBuffer::Init(int textureWidth, int textureHeight) {
glGenFramebuffers(1, &fbo);
glGenTextures(1, &depth);
glBindTexture(GL_TEXTURE_2D, depth);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, textureWidth, textureHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
Где проблема в моей математике или моем коде, и что я могу сделать, чтобы исправить это?
После некоторых экспериментов я обнаружил, что моя проблема не в моих матрицах, а в моих пережатиях. Кажется, что я получаю странные значения, когда я использую GL_CLAMP или GL_CLAMP_TO_EDGE, но я получаю почти правильные значения, когда я использую GL_CLAMP_TO_BORDER. Есть еще проблемы, но они, кажется, не связаны с матрицей, как я думал.
Других решений пока нет …