对几何着色器的最大输出感到困惑

Posted

技术标签:

【中文标题】对几何着色器的最大输出感到困惑【英文标题】:Confusion about maximum output from Geometry Shaders 【发布时间】:2015-03-21 16:06:51 【问题描述】:

OpenGL-Wiki 声明 on the output limitations of geometry shaders:

GL_MAX_GEOMETRY_OUTPUT_VERTICES​定义的第一个限制是可以提供给max_vertices​输出布局限定符的最大数量。

[...]

GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS​ 定义的另一个限制是 [...] 输出值的总数(一个分量,在 GLSL 术语中,是向量的一个分量。所以浮点数是一个分量;一个 vec3​是3个组件)。

这就是我的几何着色器的声明部分的样子:

layout( triangles ) in;
layout( triangle_strip, max_vertices = 300 ) out;
out vec4 var1;

我的顶点格式仅包含 4 个位置浮点数。 所以我相信有来自不同 var1 的 4 个组件加上来自该位置的 4 个组件,即总共 8 个。

我已经为上面提到的常量查询了以下值:

GL_MAX_GEOMETRY_OUTPUT_VERTICES = 36320
GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = 36321

max_vertices 设置为 300,总共将写入 8*300 = 2400 个组件。不用说这个值远低于 36321 以及max_vertices 的 300 远低于 36320。所以一切应该没问题吧?

但是,当我构建着色器时,链接失败:

错误 C6033:达到硬件限制,只能发出 128 个此大小的顶点

有人可以向我解释发生了什么以及为什么这不像我预期的那样工作吗?

【问题讨论】:

【参考方案1】:

我犯了一个非常愚蠢的错误。作为记录,如果其他人遇到同样的问题:查询 GL_MAX_GEOMETRY_OUTPUT_VERTICESGL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 的值必须通过 glGetInteger 完成,而不仅仅是评估这些宏。

【讨论】:

我猜这是一个常见的错误,但这是有道理的,因为没有一个预定义的常量可以包含特定于执行硬件的信息。 像 C++ 这样的语言有实际的enum 类型来消除这个问题。但是 C 语言非常懒散,0x8DE0 (GL_MAX_GEOMETRY_OUTPUT_VERTICES) 就其而言只是一个整数。为了将来参考,如果您看到某些常量的数字在 36xxx 附近徘徊,特别是如果它们是连续的,那么这是一个好兆头,表明您正在使用枚举值而不是查询实现限制;)大多数实现与向量有关的限制是二次方,所以马上 36320 应该看起来很可疑。 @Gigo:我不知道宏扩展为常量,它们也可以扩展为执行查询的函数。这就是我的想法。

以上是关于对几何着色器的最大输出感到困惑的主要内容,如果未能解决你的问题,请参考以下文章

Unity Shader:几何着色器

无法让 openGL 的 glDrawElements 与几何着色器一起使用

GLSL 几何着色器的性能出乎意料地变慢

跨多个着色器的 OpenGL 统一

opengl ---几何着色器

OpenGL 着色器加载失败