如何在 OpenGL 中处理每个三角形的多个变量?

Chr*_*own 4 opengl shader glsl

我正在使用 OpenGL,并且对需要将其传递给片段着色器的每个三角形(或在我的情况下,四边形)传递值的标准方法并不完全满意,即将它们分配给图元的每个顶点并传递它们通过顶点着色器可能会在片段着色器中进行不必要的插值(除非使用“平面”指令)(换句话说,每个片段都不变)。

是否有某种方法可以存储需要在片段着色器中访问的值 PER 三角形(或四边形),这样您就不需要每个顶点的冗余副本?是这样,这种方式是否比数据移动代码 CPU 端的 3 倍(或 4 倍)可能的开销更好?

我知道使用几何着色器将值传播到新顶点,但我听说几何着色器在非最新硬件上非常慢。是这种情况吗?

der*_*ass 6

OpenGL 片段语言支持gl_PrimitiveID输入变量,它将是当前处理片段的图元索引(每个绘制调用从 0 开始)。这可以用作某些数据存储的索引,其中包含每个原始数据。

根据每个基元所需的数据量以及基元总数,可以使用不同的选项。对于少量基元,您可以只设置一个统一数组并对其进行索引。

对于相当多的基元,我建议使用纹理缓冲区对象 (TBO)。这基本上是一个普通的缓冲区对象,可以通过texelFetchGLSL 操作在随机位置以只读方式访问它。请注意,TBO 并不是真正的纹理,它们仅重用现有的纹理对象接口。在内部,它仍然是从缓冲区对象中获取数据,并且非常高效,没有纹理管道的开销。

这种方法的唯一问题是您无法轻松混合不同的数据类型。您必须为 TBO 定义基本数据类型,并且每次获取都会以该格式获取数据。如果您只需要每个基元一些浮点数/向量,这根本不是问题。例如,如果您需要一些整数和每个基元的一些浮点数,您可以使用不同的 TBO,每种类型一个,或者使用现代 GLSL (>=3.30),您可以为 TBO 使用整数类型并将整数位重新解释为浮点数指向intBitsToFloat(),这样您也可以绕过该限制。