gpt4 book ai didi

java - 无法使用深度附件渲染到 FBO

转载 作者:行者123 更新时间:2023-12-01 13:31:11 29 4
gpt4 key购买 nike

我现在正在尝试实现阴影贴图几天,我想我开始看到手头的真正问题:我有一个附加了深度纹理的 FBO,用于阴影贴图的光 channel ,但是其中没有任何内容被渲染。甚至没有硬编码值。

我已经仔细检查了程序中可视化深度纹理的部分,并且该部分正在使用常规纹理,而且我没有看到场景中出现阴影,所以我认为肯定有问题。

初始化:

    //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*调用中的代码。

初始化:

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;
}

甚至将深度硬编码为0.0f0.5f1.0f也不起作用。

只是为了澄清我的期望是否正确:当我将相机移近屏幕上正在渲染的对象时,深度缓冲区的颜色应该改变吗?那么深度会接近 0.0f,而远离 1.0f?

还有一个说明:我所看到的深度值是一个到处都是白色的矩形。

根据请求,着色器可视化深度纹理数据:

深度盒.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];
}

深度盒.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);
}

最佳答案

这不起作用,您忘记禁用纹理比较。您无法使用 sampler2D 使用除 GL_NONE 之外的 texutre 比较模式对纹理进行采样。 结果将是不确定的。

要读取启用比较的纹理,需要

sampler2DShadow。当你这样做时,前两个纹理坐标正常工作,但第三个是要比较的深度值,并且 texture (...) 的返回是一个浮点值(1.0 表示通过,0.0 表示失败)。如果您有线性滤波器,它可以介于两者之间。

关于java - 无法使用深度附件渲染到 FBO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21562103/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com