我第一次尝试实现延迟着色,但是在生成缓冲区时遇到了麻烦。我已经开始尝试仅制作位置缓冲区,所以这里是相对代码:
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);
帧缓冲区已成功完成,我们进入主循环:
glBindFramebuffer(GL_FRAMEBUFFER, gBuffer);
glActiveTexture(gPosition);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, 1024, 1024);
mat4 modelMatrix = mat4(1);
glUseProgram(gShader);
glUniformMatrix4fv(mgLoc, 1, GL_FALSE, &modelMatrix[0][0]);
glUniformMatrix4fv(pgLoc, 1, GL_FALSE, &projectionMatrix[0][0]);
glUniformMatrix4fv(vgLoc, 1, GL_FALSE, &viewMatrix[0][0]);
glBindVertexArray(objVAO);
glDrawArrays(GL_TRIANGLES, 0, objVertices.size());
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。现在,它可以完美运行。因此,新的问题是为什么它现在可以正常工作?
答案 0 :(得分:3)
glActiveTexture
不使用纹理名称,而是选择活动纹理 unit (GL_TEXTURE0 + n)–是的,名称具有误导性。
无论如何,似乎您想在渲染之前绑定位置缓冲区纹理。为什么?如果您确实这样做了,则可能会导致反馈循环–请参阅https://www.khronos.org/opengl/wiki/Framebuffer_Object#Feedback_Loops。只要您不从中取样就可以了,但是仅存在反馈循环的可能性可能会使您陷入较慢的代码路径。因此,请不要这样做。您已经将纹理绑定为FBO的附件,就足够了。
就渲染实际位置缓冲区而言:为什么首先要这样做?只需使用深度缓冲区纹理(而不是renderbuffer),并根据单个深度值和取消投影来重建位置即可。