FBO 和纹理

Posted

技术标签:

【中文标题】FBO 和纹理【英文标题】:FBO and Textures 【发布时间】:2019-02-25 03:52:44 【问题描述】:

我已将两个纹理附加到 FBO。第一个纹理将用于显示深度图。第二个纹理将以正常方式显示对象。

如果我这样做,它会很好地显示深度图。

GLuint atach0 = GL_DEPTH_ATTACHMENT;
glBindFramebuffer(GL_FRAMEBUFFER,fboBuffer);
  glDrawBuffers(1,&atach0);
  glClear(GL_DEPTH_BUFFER_BIT);
  glViewport(0.0,0.0,640,480);
  LProjection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,-500.0f,500.0f);
  LView = glm::lookAt(glm::vec3(0.0f,15.0f,0.000001f),glm::vec3(0.0f,0.0f,0.0f),glm::vec3(0.0f,1.0f,0.0f));
  LViewProjection = LProjection * LView;
  glEnable(GL_DEPTH_TEST);

  ...CUBE3D

glBindFramebuffer(GL_FRAMEBUFFER,0);

glUniform1i(uniforTEX,0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,GL_DEPTH_MAP);

  ...DRAW-DEPTH-MAP!

glBindTexture(GL_TEXTURE_2D,0);

但是如果我这样做,它只会显示一个白屏,并且深度图不再可见。

GLuint atach0 = GL_DEPTH_ATTACHMENT;
glBindFramebuffer(GL_FRAMEBUFFER,fboBuffer);
  glDrawBuffers(1,&atach0);
  glClear(GL_DEPTH_BUFFER_BIT);
  glViewport(auxrecX,auxrecY,auxrcAn,auxrcAl);
  LProjection = glm::ortho(-10.0f,10.0f,-10.0f,10.0f,-500.0f,500.0f);
  LView = glm::lookAt(glm::vec3(0.0f,15.0f,0.000001f),glm::vec3(0.0f,0.0f,0.0f),glm::vec3(0.0f,1.0f,0.0f));
  LViewProjection = LProjection * LView;
  glEnable(GL_DEPTH_TEST);

  ...CUBE3D

glBindFramebuffer(GL_FRAMEBUFFER,0);

GLuint atach1 = GL_COLOR_ATTACHMENT0;
glBindFramebuffer(GL_FRAMEBUFFER,fboBuffer);
  glDrawBuffers(1,&atach1);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glViewport(0,0,640,480);
  Projection = glm::perspective(45.0f,1.333333f,0.01f,1000.0f);
  View = glm::lookAt(glm::vec3(0.0f,0.0f,3.0),glm::vec3(0.0f,0.0f,-15.0f),glm::vec3(0.0f,1.0f,0.0f));
  ViewProjection = Projection * View;
  glEnable(GL_DEPTH_TEST);

  ...CUBE3D

glBindFramebuffer(GL_FRAMEBUFFER,0);   

glUniform1i(uniforTEX,0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,GL_DEPTH_MAP);

  ...DO NOT DRAW NOTHING

glBindTexture(GL_TEXTURE_2D,0);

我需要按这个顺序做。因为第一个“pass”是为了在阴影贴图中使用深度贴图。我做错了什么?

【问题讨论】:

【参考方案1】:

GL_DEPTH_ATTACHMENTglDrawBuffers 无效。 glDrawBuffers 将写入片段着色器数据输出的缓冲区。

当你这样做时

GLuint atach0 = GL_DEPTH_ATTACHMENT;
glBindFramebuffer(GL_FRAMEBUFFER,fboBuffer);

然后你会得到一个GL_INVALID_ENUM 错误。

如果您不想写入深度图,请禁用使用glDepthMask 的深度测试。深度缓冲附件不能打开和关闭,也不能像颜色缓冲一样使用。

进一步

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

在任何情况下都会清除深度缓冲区。

我认为对于如何设置阴影贴图的帧缓冲区存在基本的误解。您只需要一个用于阴影贴图的帧缓冲区。这个帧缓冲区必须只有一个深度缓冲区。

你必须以某种方式这样做:

GLuint fboShadow;      // framebuffer with depth buffer only (shadow map)
GLuint toShadowDepth;  // texture which is the depth buffer of `fboShadow`
glBindFramebuffer(GL_FRAMEBUFFER, fboShadow);
GLuint atach0 = GL_NONE;
glDrawBuffers(1, &atach0);
glClear(GL_DEPTH_BUFFER_BIT);

glEnable(GL_DEPTH_TEST);
glViewport(auxrecX, auxrecY, auxrcAn, auxrcAl);

// draw the shadow map to the depth buffer only

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

glEnable(GL_DEPTH_TEST);
glViewport(0, 0, 640, 480);

glUniform1i(uniforTEX, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, toShadowDepth);

// draw the geometry to the default framebuffer by using the depth map

【讨论】:

我要试试。非常感谢您的回答朋友。

以上是关于FBO 和纹理的主要内容,如果未能解决你的问题,请参考以下文章

在 GLSL 中访问多个 FBO 纹理以创建另一个纹理

从纹理渲染到屏幕外纹理 (FBO)

FBO 用于分离纹理

FBO:渲染到纹理,绘制渲染纹理时纹理映射错误

OpenGL:使用 FBO 和视口偏移问题渲染到纹理

纹理可以绑定到多个 fbo 吗?