Opengl 为延迟渲染制作位置缓冲区-生成纹理中的噪波
我第一次尝试实现延迟着色,但在生成缓冲区时遇到了问题。我已经开始尝试只制作位置缓冲区,因此以下是相关代码:Opengl 为延迟渲染制作位置缓冲区-生成纹理中的噪波,opengl,framebuffer,deferred-rendering,deferred-shading,Opengl,Framebuffer,Deferred Rendering,Deferred Shading,我第一次尝试实现延迟着色,但在生成缓冲区时遇到了问题。我已经开始尝试只制作位置缓冲区,因此以下是相关代码: glGenFramebuffers(1, &gBuffer); glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); glGenTextures(1, &gPosition); glBindTexture(GL_TEXTURE_2D, gPosition); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F
glGenFramebuffers(1, &gBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glGenTextures(1, &gPosition);
glBindTexture(GL_TEXTURE_2D, gPosition);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, 1024, 1024, 0, GL_RGB, GL_FLOAT,
NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0);
unsigned int rbo;
glGenRenderbuffers(1, &rbo);
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1024, 1024);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
std::cout << "ERROR::FRAMEBUFFER:: Framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
这是片段着色器:
layout (location=0) out vec3 gPosition;
in vec3 vertex_world;
out vec4 FragColor;
void main()
{
FragColor=vec4(vertex_world,1.0);
}
位置缓冲似乎很好:
但是,如果您查看我的着色器,我没有为gPosition指定值。看起来缓冲区只是获取输出的fragColor
这是我计划做的,但它给了我错误的结果:
layout (location=0) out vec3 gPosition;
in vec3 vertex_world;
void main()
{
gPosition=vertex_world;
}`
它确实会将某些内容传递到位置缓冲区,但您会发现这非常奇怪:
有什么不对劲吗
编辑/解决
事实证明,我必须在片段着色器中将gPosition定义为vec4。它现在工作得很好。因此,新的问题是为什么它现在起作用了
glActiveTexture
不采用纹理名称,而是选择活动纹理单元(GL_TEXTURE0+n)–是的,名称有误导性
无论如何,似乎要在渲染之前绑定位置缓冲区纹理。为什么?如果你真的这样做了,你可能会得到一个反馈循环——请参阅。只要不从中采样,您就可以了,但仅仅是有一个反馈循环的可能性就可能使您进入一个较慢的代码路径。所以尽量不要这样做。您已将纹理绑定为FBO的附件,这就足够了
就渲染实际位置缓冲区而言:首先为什么要这样做?只需使用深度缓冲纹理(而不是renderbuffer)并根据单个深度值重建位置并取消投影。正如您可能注意到的,我不知道我在做什么。至少我第一次写这篇文章的时候没有。我严格遵循教程,在某个时候,我开始四处移动,希望它能起作用。你的评论很有帮助。我想我找到了引起麻烦的原因,但我不明白为什么会这样。在第二种情况下,我不得不将输出定义为vec4。你知道为什么会有这么大的不同吗?作为旁注:在g缓冲区中存储位置完全是对内存带宽的浪费。所需要的只是一个深度缓冲区(您无论如何都要使用它),然后您可以从深度和2D屏幕空间位置在任何相关空间中重建3D位置。
layout (location=0) out vec3 gPosition;
in vec3 vertex_world;
void main()
{
gPosition=vertex_world;
}`