3

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

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

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

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

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

我的 FBO 设置如下(它基于 OpenGL 4 Shading Language Cookbook 的第 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 运行它,它根本无法检测到任何错误。我已经尝试告诉片段着色器实际绘制东西,但这也没有什么区别(没有尝试将不同的值写入 gl_FragDepth)。

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

我已经在一台装有驱动程序版本 8.17.13.142 的 nVidia GTX 560 Ti 和另一台装有 Radeon Mobility HD 5650 的计算机上对此进行了测试。我在两者上都得到了相同的结果。

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

4

0 回答 0