几何着色器和深度FBO

时间:2012-07-26 16:31:56

标签: c++ opengl glsl fbo geometry-shader

当涉及几何着色器时,是否有关于渲染到FBO的特殊规则?

上下文: 我正在尝试在场景中实现阴影贴图,其中包括以不同方式呈现的不同类型的对象: 网格,通过VBO和着色器以标准方式呈现 使用顶点和片段着色器渲染的点精灵粒子 四维粒子,以点的形式发送,但在几何着色器中扩展为四边形

我正在以标准方式进行阴影贴图,这涉及创建深度FBO并从灯光的角度渲染对象的深度。网格和点精灵工作正常,但几何着色器四边形粒子的深度不会渲染到FBO。

Here是标准(非FBO)深度缓冲区。注意前景中的大圆形颗粒。

Here向FBO呈现的视图相同。请注意,仅绘制网格和点精灵粒子的深度。

我的FBO设置如下(它基于OpenGL 4着色语言手册第7章):

const bool Renderer::generateShadowMap(FBO & f, string & error) {
  uint depthTexID;
  uint width = f.getWidth();
  uint height = f.getHeight();
  glGenTextures(1, &depthTexID);
  glBindTexture(GL_TEXTURE_2D, depthTexID);
  glTexImage2D( GL_TEXTURE_2D,  0,       GL_DEPTH_COMPONENT,
  width,        height, 0,
  GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
  float border[] = {1.0, 0.0, 0.0, 0.0};
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
  glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE,
    GL_COMPARE_REF_TO_TEXTURE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
  glActiveTexture(GL_TEXTURE1);
  glBindTexture(GL_TEXTURE_2D, depthTexID);
  uint fID;
  glGenFramebuffers(1, &fID);
  glBindFramebuffer(GL_FRAMEBUFFER, fID);
  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,             
    depthTexID, 0);
  glDrawBuffer(GL_NONE);
  if(!checkFBOstatus(error)) {
        cerr << error << endl;
           return false;
  }
  glClearDepth(1.0);
  glClear(GL_DEPTH_BUFFER_BIT);
  glBindFramebuffer(GL_FRAMEBUFFER, 0);
  glActiveTexture(GL_TEXTURE0);
  f.setFBOID(fID);
  f.setTexID(depthTexID);
  return true;
}

应该渲染四边形粒子深度的着色器是:

//VERTEX SHADER
#version 400
in vec3 aPosition;
in float aSize;
out float gSize;
uniform mat4 vWorldView;
void main() {
  gSize = aSize;
  vec4 v4Vertex = vec4(aPosition.xyz, 1.0);
  vec4 transformedVertex = vWorldView * v4Vertex;
   gl_Position = transformedVertex;
}
//GEOMETRY SHADER
#version 400
layout (points) in;
layout (triangle_strip, max_vertices = 4) out;
in float gSize[1];
uniform mat4 vgProjection;
void main() {
 vec4 oPosition;

  float halfSize = gSize[0] * 0.5;
  oPosition = (vec4(-halfSize, -halfSize, 0.0, 0.0) + gl_in[0].gl_Position);
  gl_Position = vgProjection * oPosition;
  EmitVertex();

  oPosition = (vec4(halfSize, -halfSize, 0.0, 0.0) + gl_in[0].gl_Position);
  gl_Position = vgProjection * oPosition;
  EmitVertex();

  oPosition = (vec4(-halfSize, halfSize, 0.0, 0.0) + gl_in[0].gl_Position);
  gl_Position = vgProjection * oPosition;
  EmitVertex();

  oPosition = (vec4(halfSize, halfSize, 0.0, 0.0) + gl_in[0].gl_Position);
  gl_Position = vgProjection * oPosition;
  EmitVertex();

    EndPrimitive();
}
//FRAGMENT SHADER - empty as depth should be written automatically
#version 400
void main() {
}

当然,启用了深度测试。我通过gDebugger运行它,它根本无法检测到任何错误。我已经尝试告诉片段着色器实际绘制的东西,但这也没有区别(noe确实尝试将不同的值写入gl_FragDepth)。

点精灵粒子和四元粒子之间的唯一区别是使用几何着色器。我正在同时渲染两个并使用相同的统一值(相同的转换矩阵),并且我运行gDebugger以确保。

我在带有驱动程序版本8.17.13.142的nVidia GTX 560 Ti计算机上进行了测试(我相信,在撰写本文时是最新版本),另一台使用Radeon Mobility HD 5650进行了测试。我得到了相同的结果在两者上。

我是否犯了任何明显的错误,或者我应该知道一些具体的事情?

0 个答案:

没有答案