具有模板缓冲区FBO的延迟渲染器

时间:2015-09-09 19:59:27

标签: c++ opengl

在我的延迟渲染器中,我为几何传递创建了一个FBO,我将深度+模板缓冲区存储到具有以下参数的纹理中:

  • 附件:$('.ui.modal.success').on('show.bs.modal', function(){ var $this = $(this); $this.data('hideInterval', setTimeout(function(){ $this.modal('hide'); }, 2000)); });
  • 格式:GL_DEPTH_STENCIL_ATTACHMENT
  • 内部格式:GL_DEPTH_STENCIL
  • 数据类型:GL_DEPTH32F_STENCIL8

我可以使用深度和模板成功填充此纹理。

我现在面临的问题是如何使用我的几何传递中创建的模板缓冲区,以便在其他地方使用它,就像我进行定向光传递时,我只想处理由几何通道上可见的几何体。

那么,如何在几何传递期间使用存储的模板缓冲区以供进一步使用?

1 个答案:

答案 0 :(得分:0)

当然,您总是可以使用模板缓冲区进行模板测试。为了说明如何在基本级别上使用模板测试,以下是对两个过程中绘制的示例的关键调用,在第二遍中,我们将排除第一遍中未覆盖的所有像素:

  • 清除帧缓冲区时,请确保包含用于清除模板缓冲区的位:

    glClear(... | GL_STENCIL_BUFFER_BIT);
    
  • 启用模板测试:

    glEnable(GL_STENCIL_TEST);
    
  • 设置模板函数/操作,将模板缓冲区中的值设置为1,用于所有渲染像素:

    glStencilFunc(GL_ALWAYS, 1, 1);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    

    GL_ALWAYS指定所有像素都通过模板测试(即没有像素被拒绝)。 GL_REPLACE指定模板缓冲区中的值由所有渲染像素的参考值(glStencilFunc()的第二个参数)替换。

  • 绘制第一遍的几何体。

  • 将模板功能/操作更改为仅渲染模板缓冲区中的值为1的像素:

    glStencilFunc(GL_EQUAL, 1, 1);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    

    GL_EQUAL指定仅模板缓冲区值等于参考值1的位置处的像素通过模板测试,并且拒绝所有其他像素。 GL_KEEP指定在此过程中不修改模板缓冲区中的当前值。

  • 绘制第二遍的几何体。

但是,当我阅读你的问题时,你正在寻找不同的东西。您希望在稍后的渲染过程中从一个渲染过程中对模板缓冲区进行采样,类似于对深度纹理进行采样的方式。

OpenGL 4.3及更高版本支持此功能。使用texId深度/模板纹理的名称,关键部分是此纹理参数设置:

glBindTexture(GL_TEXTURE_2D, texId);
glTexParamteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);

这指定深度/模板纹理的模板部分应该用于采样。模板纹理仅支持最近的采样,因此请确保您还具有以下值:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

毫不奇怪,基于值的性质,模板纹理被视为无符号整数纹理。这意味着着色器代码中的采样器类型需要为usampler2D

uniform usampler2D MyStencilTexture;

当您对纹理进行采样时,结果也将是unsigned类型:

uvec4 stencilValue = texture(MyStencilTexture, textureCoordinates);

模板值将在stencilValue.r