У меня есть сцена, состоящая из 2-х сеток (плоскость, куб), свет и камера. Я хочу отображать тени на своей сцене с использованием технологии теневого отображения с помощью шейдеров GLSL и OpenGL.Теневое отображение работает неправильно с использованием GLSL и OpenGL
Вот результат у меня есть (для простоты, мой куб и мой самолет оба в синем цвете и цвете):
Вот инициализация FBO и глубина текстуры:
GLfloat border[] = {1.0f, 1.0f, 1.0f, 1.0f};
glGenTextures(1, &this->m_TextId);
glBindTexture(GL_TEXTURE_2D, this->m_TextId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24,
this->m_Width, this->m_Height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, this->m_TextId, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(result == GL_FRAMEBUFFER_COMPLETE) {
printf("Framebuffer is complete.\n");
} else {
printf("Framebuffer is not complete.\n");
}
Вот содержание моего вершинного шейдера:
#version 400
layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in vec2 VertexTexture;
uniform mat4 MVP;
uniform mat4 ShadowMatrix;
out vec4 ShadowCoords;
void main(void)
{
ShadowCoords = ShadowMatrix * vec4(VertexPosition, 1.0f);
gl_Position = MVP * vec4(VertexPosition, 1.0f);
}
И один из моего пиксельного шейдера:
#version 400
in vec3 Position;
in vec3 Normal;
in vec2 TexCoords;
in vec4 ShadowCoords;
layout (location = 0) out vec4 FragColor;
uniform sampler2DShadow ShadowMap;
void main(void)
{
vec4 ModelColor = vec4(0.0f, 0.0f, 1.0f, 1.0f);
float shadow = textureProj(ShadowMap, ShadowCoords);
FragColor = ModelColor * shadow;
}
Как вы можете видеть, что есть некоторые артефакты на моделях, и я не знаю, как вывести их. Но тень кажется правильной, поэтому переменные, входящие в мои шейдеры, тоже должны быть правильными (я так думаю).
Я попробовал другую технику в пиксельный шейдер, как следующий:
#version 400
in vec3 Position;
in vec3 Normal;
in vec2 TexCoords;
in vec4 ShadowCoords;
layout (location = 0) out vec4 FragColor;
uniform sampler2D ShadowMap;
void main(void)
{
vec4 ModelColor = vec4(0.0f, 0.0f, 1.0f, 1.0f);
vec4 shadowCoordinateWdivide = ShadowCoords/ShadowCoords.w;
shadowCoordinateWdivide.z += 0.0005;
float distanceFromLight = texture2D(ShadowMap,shadowCoordinateWdivide.st).z;
float shadow = 1.0;
if (ShadowCoords.w > 0.0)
shadow = (distanceFromLight < shadowCoordinateWdivide.z) ? 0.5 : 1.0 ;
FragColor = shadow * ModelColor;
}
Вы можете заметить, что я не использую sampler2DShadow но теперь sampler2D. Но, как вы можете увидеть там отображается ни тени:
Кто-нибудь может мне помочь?
Спасибо, что все правильно работают. До свидания. – user1364743