gpt4 book ai didi

c - OpenGL - 帧缓冲区深度纹理不同于颜色深度纹理

转载 作者:太空狗 更新时间:2023-10-29 16:09:14 26 4
gpt4 key购买 nike

我在 OpenGL 中进行阴影贴图 - 因此我创建了一个帧缓冲区对象,我在其中从光线的角度渲染场景的深度。

glBindRenderbuffer(GL_RENDERBUFFER, color_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color_buffer);

glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth_buffer);

glGenTextures(1, &color_texture);
glBindTexture(GL_TEXTURE_2D, color_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color_texture, 0);

glGenTextures(1, &depth_texture);
glBindTexture(GL_TEXTURE_2D, depth_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
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_texture, 0);

然后,这会正常地从光线透视图渲染场景,正如您所期望的那样。唯一的补充是我使用自定义着色器将场景的深度也渲染到“color_texture”。

varying vec4 screen_position;

void main()
{
screen_position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = screen_position;
}

--------------

varying vec4 screen_position;

void main()
{
float depth = screen_position.z / screen_position.w;
gl_FragColor = vec4(depth, depth, depth, 1.0);
}

我可以使用全屏四边形将这两个纹理“color_texture”和“depth_texture”写入屏幕。两者确实都是深度图并且看起来正确。现在来看奇怪的一点。

当实际渲染对象上的阴影时,采样“color_texture”深度效果很好,但当我切换到采样“depth_texture”时,深度因比例和常数而不同。

当我向这个采样深度添加一些软糖因子数字时,我可以让它工作,但这真的很困难,而且感觉很糟糕。

我真的不知道哪里出了问题,从技术上讲,这两个纹理在采样时应该是相同的。由于 RGB 的准确性,我无法继续使用“color_texture”。我真的需要切换,但我一辈子都弄不明白为什么深度纹理会给出不同的值。

我之前编写过多次阴影贴图,这对我来说并不是一个新概念。

任何人都可以阐明这一点吗?

最佳答案

您的着色器存在一些问题。首先,screen_position 不是屏幕位置;那是裁剪空间的顶点位置。屏幕空间将相对于您的显示器,因此如果您四处移动窗口,屏幕空间就会发生变化。你永远不会得到任何东西的屏幕空间位置; OpenGL 仅下降到窗口空间(相对于窗口的位置)。

第二,这个:

float depth = screen_position.z / screen_position.w;

不计算深度。它计算标准化设备坐标 (NDC) 空间 Z 位置,范围从 [-1, 1]。深度是一个窗口空间值,它是在 NDC 空间值通过视口(viewport)变换(由 glViewport 和 glDepthRange 指定)进行变换之后得到的。此转换将深度置于 [0, 1] 范围内。

最重要的第三点,你是手动完成这一切;让 GLSL 为你做:

void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}

--------------

void main()
{
gl_FragColor = vec4(gl_FragCoord.zzz, 1.0);
}

看到了吗?好多了。

现在:

When it comes to actually rendering the shadows on objects sampling the "color_texture" depth works fine, but when I switch to sampling "depth_texture", the depth is different by some scale and some constant.

当然可以。那是因为您认为深度是 NDC Z 值。 OpenGL 将实际的窗口空间 Z 值写入深度。所以你需要使用窗口空间。 OpenGL 足以提供一些 uniforms to your fragment shader使这更容易。您可以使用这些制服将 NDC 空间 Z 值转换为窗口空间 Z 值。

关于c - OpenGL - 帧缓冲区深度纹理不同于颜色深度纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6768602/

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