我无法在我的应用程序中获得阴影映射。我尝试渲染一辆四轮摩托车,并在它下面的地板上观察它的影子。 这是我的一些代码。 纹理制作:OpenGL中的阴影映射
// Create a depth texture
glGenTextures(1, &depth_texture);
glBindTexture(GL_TEXTURE_2D, depth_texture);
// Allocate storage for the texture data
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32 ,1600, 900, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
// Set the default filtering modes
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Set up wrapping modes
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);
// Create FBO to render depth into
glGenFramebuffers(1, &depth_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo);
// Attach the depth texture to it
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
depth_texture, 0);
// Disable color rendering as there are no color attachments
glDrawBuffer(GL_NONE);
//check fbo status
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(result != GL_FRAMEBUFFER_COMPLETE)
throw std::runtime_error("shadow mapping framebuffer error");
//bind default framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
渲染到深度纹理:
progShadow.Use();
glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo);
glClear(GL_DEPTH_BUFFER_BIT);
glm::mat4 shadowProjection = glm::frustum(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 100.0f);
glm::mat4 shadowView = glm::lookAt(light.position, glm::vec3(0,0,0), glm::vec3(0,1,0));
glm::mat4 shadowModel(1);
if(g_rotate)
shadowModel = glm::rotate((float)clock()/(float)CLOCKS_PER_SEC, glm::vec3(0,1,0));
glm::mat4 shadowMVP = shadowProjection * shadowView * shadowModel;
progShadow.SetUniform("MVPMatrix", shadowMVP);
quadBike.Draw();
我也用的是我的呈现深度纹理“测试”着色器程序。这是它的样子。
所以我觉得我很好,直到现在。 现在我正常渲染场景。
glBindTexture(GL_TEXTURE_2D, depth_texture);
prog.Use();//main program
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 shadowBias = glm::mat4(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0);
glm::mat4 ShadowBiasMVP = shadowBias * shadowMVP;
prog.SetUniform("ShadowBiasMVP", ShadowBiasMVP);
//draw quadBike and floor
...
我的顶点着色器的相关部分:
#version 430
...
out vec4 shadowCoord;
void main()
{
gl_Position = ProjectionMatrix * CameraMatrix * ModelMatrix * vec4(vertex, 1.0);
shadowCoord = ShadowBiasMVP * vec4(vertex, 1.0);
...
}
我的片段着色器的相关部分:
#version 430
...
uniform sampler2D shadowMap;
in vec4 shadowCoord;
void main()
{
...
float visibility = 1.0;
if (texture(shadowMap, shadowCoord.xy).z < shadowCoord.z)
visibility = 0.0;
...
}
现在的问题是,我得到一个场景是因为如果完全黑暗它全部被阴影覆盖。只有当灯光非常接近四轮摩托车时,才能正常呈现。 (深度纹理在右侧是可见的,因为它是用不同的程序渲染的,我用它来测试)
我在做什么错了?
偏置矩阵的目的是将'xy'(纹理坐标)和z(深度)重新缩放(x ** 0.5 **)和偏移(+ ** 0.5 **)纹理坐标和深度范围[** 0.0 **,** 1.0 **]来自剪辑空间([** - w **,** w **])。为了完成偏倚矩阵应该做的变换,你需要用'w'来划分(现在你的数学只有在'shadowCoord.w'是** 1.0 **时才有效,如果你是使用透视投影)。 –