首页 > 解决方案 > 如何在帧缓冲区中的像素旁边写入整数,然后使用写入的整数忽略深度缓冲区

问题描述

我想做的事

我想让一组三角形通过,或者更确切地说忽略深度缓冲区,用于另一组三角形,但前提是它们具有相同的数字。

问题(选读

如果不将大量气泡引入管道,我不知道如何做到这一点。现在我的吞吐量非常高,因为我可以将我的几何图形放到 GPU 上,告诉它渲染,然后忘记它。但是,如果我必须在绘图时不断切换状态,我担心我会降低我的性能。其他完成了我刚才所说的事情(进行大量的绘制调用和状态更改)的人的表现比我差得多。在旧硬件上,这种性能损失也明显更差,我们正在谈论通过状态更改方式进行 50 到 100 倍以上的性能损失。

不幸的是,这种三角形出血场景发生了数千次,因此状态机将被“绘制三角形,深度关闭,绘制渗透的三角形,深度开启,......”淹没,除了 N 次,其中 N 可以变大(N >= 1000)。

想象这一点的一个好方法是拥有一组三角形T_i,以及一组渗出的三角形,B_i其中B_i只有渗出T_ii范围从0...1000+. 请注意,如果我们正在绘图B_100,那么它应该只渗透T_100,而不是T_99or T_101

我的下一个想法是将所有三角形及其整数绘制到一个帧缓冲区(连同整数),然后将三角形的流血绘制到另一个帧缓冲区(也是整数),然后将这些帧缓冲区合并在一起。我认为它们将具有颜色、深度和整数,因此我希望可以将它们合并到片段着色器中。

out vec4 fragColor问题是,我不知道如何在片段着色器的旁边写一个整数。

问题(简而言之)

这给我留下了两个问题:

  1. 如何将整数写入帧缓冲区?我需要写入 4 个单独的纹理帧缓冲区吗?(比如一个颜色/深度帧缓冲区纹理,另一个整数帧缓冲区纹理,然后将其加倍,以便我可以在某个时候将帧缓冲区对合并在一起?)

为了更清楚地说明这一点,算法看起来像

  1. 渲染所有“可以从三角形流血”,上面描述为集合 T_i,将颜色和深度信息写入 FB1,并将整数写入 FB2

  2. 渲染所有“出血”三角形,上面描述为集合 B_i,将颜色和深度写入 FB3,并将整数写入 FB4

  3. 为 FB1、FB2、FB3、FB4 绑定纹理

  4. 通过从适当的纹理中采样 RGBA、深度和整数来渲染每个像素,并将它们写入最终的帧缓冲区

我需要从着色器中的纹理访问颜色和深度。我还需要从其他纹理访问整数。然后我可以进行比较并选择将哪个像素写入默认帧缓冲区。

  1. 这个想法可能吗?我假设如果(1)是,那么答案是肯定的。也许另一个问题可能是是否有更好的方法。我试着考虑用模板缓冲区做这个,但没有运气

标签: opengl

解决方案


你想要的理论上是可能的,但我不能说它的性能。您将在每次程序迭代中读取和写入大量纹理中的大量纹素。

无论如何回答你的问题:

  1. 通过使用glFramebufferTexture2Dwith GL_COLOR_ATTACHMENT0,GL_COLOR_ATTACHMENT1等,帧缓冲区可以具有多个颜色附件。然后每个纹理都可以有自己的内部格式,在您的示例中,您可能需要一个常规的 RGB 纹理作为颜色输出,以及第二个 1 整数纹理。

  2. 您的深度缓冲区很复杂,因为您不想让 OpenGL 正常处理它。如果您想接管深度缓冲区,您可能希望将其附加为另一个浮动纹理,您可以检查或不检查您的屏幕空间片段。

  3. 如果您对着色器有疑问,请记住,您可以将任意数量的纹理绑定为您在代码中编程的输入采样器,并且每个颜色绑定都有自己的输出值(您的着色器按纹素运行,因此您在时间)。确保输出格式正确,即vec3/vec4用于颜色缓冲区、int整数缓冲区和float浮点缓冲区。

并且模板缓冲区不会帮助您在单个(可能是间接的)绘图调用中打开或关闭深度检查。我无法想象你流血的东西是什么意思,但它可能对此有帮助吗?也许?但绝对不是条件深度检查。


推荐阅读