我正在尝试实施阴影贴图几天,我想我开始看到手头上的真正问题:我有一个附有深度纹理的FBO,用于阴影贴图的光通过,但是没有任何东西在里面呈现。甚至没有硬编码的值。
我已经仔细检查了可视化深度纹理的程序部分,并且使用了常规纹理,而且我看到我的场景中没有出现阴影,所以我认为某些内容肯定是错误的。
INIT:
//shadow FBO and texture
depthFBO = new FrameBufferObject().create().bind();
depthTexture = new Texture2D().create().bind()
.storage2D(12, GL_DEPTH_COMPONENT32F, 4096, 4096)
.minFilter(GL_LINEAR)
.magFilter(GL_LINEAR)
.compareMode(GL_COMPARE_REF_TO_TEXTURE)
.compareFunc(GL_LEQUAL);
depthFBO.texture2D(GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, depthTexture, 0)
.checkStatus().unbind();
depthTexture.unbind();
渲染:
depthFBO.bind();
glViewport(0, 0, 4096, 4096);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(4.0f, 4.0f);
glDrawBuffer(GL_NONE);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepthf(1f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Drawable.drawAllLightPass(drawables, lightNormalProgram, lightTessellationProgram);
glDisable(GL_POLYGON_OFFSET_FILL);
depthFBO.unbind();
直接gl*
来电中的代码。
INIT:
int frameBufferObjectId = GL30.glGenFramebuffers();
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferObjectId);
int textureId = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
GL42.glTexStorage2D(GL11.GL_TEXTURE_2D, 12, GL_DEPTH_COMPONENT32F, 4096, 4096);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL14.GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL11.GL_TEXTURE_2D, textureId, 0);
if (GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) != GL30.GL_FRAMEBUFFER_COMPLETE) {
throw new RuntimeException(this + " is not complete.");
}
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
渲染:
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferObjectId);
glViewport(0, 0, 4096, 4096);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(4.0f, 4.0f);
glDrawBuffer(GL_NONE);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepthf(1f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//appropiate calls to glDraw* are being done, this is confirmed to work as it works for displaying data
glDisable(GL_POLYGON_OFFSET_FILL);
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
现在最重要的着色器:
light-normal.vs.glsl
#version 430 core
layout(location = 4) uniform mat4 light_model_matrix;
layout(location = 5) uniform mat4 light_view_matrix;
layout(location = 6) uniform mat4 light_projection_matrix;
layout(location = 0) in vec4 position;
void main(void) {
gl_Position = light_projection_matrix * light_view_matrix * light_model_matrix * position;
}
light-normal.fs.glsl
#version 430 core
layout(location = 0) out float depth;
void main(void) {
depth = gl_FragCoord.z;
}
即使将depth
硬编码到0.0f
,0.5f
或1.0f
也不起作用。
只是为了澄清我的期望是否正确:当我将相机移动到靠近屏幕上呈现的对象时,深度缓冲区的颜色应该改变吗?深度将接近0.0f,然后远离1.0f?
另一个澄清:我所看到的深度值是一个到处都是白色的矩形。
根据要求,着色器可视化深度纹理数据:
depth-box.vs.glsl
#version 430 core
void main(void) {
const vec4 vertices[6] = vec4[](
vec4(-1.0, -1.0, 1.0, 1.0),
vec4(-1.0, 1.0, 1.0, 1.0),
vec4(1.0, 1.0, 1.0, 1.0),
vec4(1.0, 1.0, 1.0, 1.0),
vec4(1.0, -1.0, 1.0, 1.0),
vec4(-1.0, -1.0, 1.0, 1.0)
);
gl_Position = vertices[gl_VertexID];
}
depth-box.fs.glsl
#version 430 core
layout(location = 7) uniform int screen_width;
layout(location = 8) uniform int screen_height;
layout(binding = 0) uniform sampler2D shadow_tex;
out vec4 color;
void main(void) {
vec2 tex_coords = vec2(
(gl_FragCoord.x - 100) / (screen_width / 5),
(gl_FragCoord.y - (screen_height - (screen_height / 5) - 100)) / (screen_height / 5)
);
color = vec4(vec3(texture(shadow_tex, tex_coords).r), 1.0);
}
答案 0 :(得分:1)
这不起作用,你忘了禁用纹理比较。您无法使用GL_NONE
使用sampler2D
以外的texutre比较模式对纹理进行采样。 结果将是未定义的。
sampler2DShadow
。当你这样做时,前两个纹理坐标正常工作,但第三个是要比较的深度值,texture (...)
的返回值是一个浮点值(1.0表示通过,0.0表示失败)。如果你有一个线性过滤器,它可能介于两者之间。