【问题标题】:WebGL shaders: maximum number of varying variablesWebGL 着色器:可变变量的最大数量
【发布时间】:2014-10-31 20:06:49
【问题描述】:

来自OpenGL ES spec 第 2.10.4 节(着色器变量:可变变量):

可用于处理不同变量的插值器数量由实现相关的常量MAX_VARYING_VECTORS给出。

这个值表示可以插值的四元素浮点向量的个数;声明为矩阵或数组的变量将使用多个插值器。

链接程序时,顶点着色器写入或片段着色器读取的任何可变变量都将计入此限制。

着色器访问超过MAX_VARYING_VECTORS 的变量变量的程序可能无法链接

在我机器上的 Chrome 中,gl.getParameter(gl.MAX_VARYING_VECTORS) 返回 15,这意味着我可以在着色器中使用 15 个 vec4 变量。

我已经通过一些测试验证了这一点。 15 vec4 变量工作正常,但尝试使用 16 时,程序无法链接,gl.getProgramInfoLog() 返回 "Varyings over maximum register limit"

但是vec3vec2float 类型可以使用多少种变量?

OpenGL ES 规范似乎暗示了这一点,但没有明确说明:

任何可变变量...都将计入此限制。

着色器访问超过MAX_VARYING_VECTORS值得变量的程序可能无法链接

我做了两个猜测:

  1. 变化的floats 的最大数量由下式给出:
    MAX_VARYING_VECTORS * 4
    (每个 vec4 向量 4 个 floats)
  2. 如果(例如)MAX_VARYING_VECTORS8,则可以安全地使用以下各项,而不会导致任何链接错误:
    • 8 vec4 变化
    • 10 vec3 变化
    • 16 vec2 变化
    • 32 float 变化
    • 3 vec4、3 vec3、3 vec2 和 5 float 变化
    • 1 vec4 可变长度数组 8
    • 1 vec3 可变长度数组 10
    • 1 vec2 可变长度数组16
    • 1 float 可变长度数组 32
    • vec4/vec3/vec2/float 变量或数组的任何其他组合,最多使用 32 个floats

所以我的MAX_VARYING_VECTORS 值为15,我想我最多可以使用60 个floats。 我的测试似乎证实了这一点。 例如,30 个 vec2 变量在我的机器上工作正常,但 31 会导致 "Varyings over maximum register limit" 链接错误。

所以我的问题是:

  • 我的两个猜测是否正确?
  • 如果MAX_VARYING_VECTORS8,那么使用16 个vec2 变量是否安全?这可以保证始终有效吗?

【问题讨论】:

    标签: opengl-es opengl-es-2.0 webgl


    【解决方案1】:

    来自 WebGL 规范

    6.24 制服和服装的包装限制

    OpenGL ES 着色语言,版本 1.00 [GLES20GLSL],附录 A,第 7 节“变化和均匀的计数”定义了一种保守算法,用于计算着色器中所有均匀和变化变量所需的存储空间。 GLSL ES 规范要求,如果附录 A 中定义的打包算法成功,则着色器必须在目标平台上成功编译。 WebGL API 进一步要求,如果打包算法对于着色器的统一变量或程序的可变变量失败,则编译或链接必须失败。

    所以是的,如果您阅读算法,如果 MAX_VARYING_VECTORS 为 8,您可以使用 16 vec2s。但是,您不能使用 10 vec3s。你只能使用 8 个vec3s

    还有数组限制。例如,如果 MAX_VARYING_VECTORS 为 8,则 floats 的数组不能大于 8,vec2 的数组也不能大于 8。

    【讨论】:

    • 非常感谢。打包算法的描述很有帮助,尤其是:“目标架构由寄存器网格组成,MAX_VARYING_VECTORS 行乘 4 列用于不同的变量。每个寄存器可以包含一个float 值。没有拆分变量是允许的。向量总是在一行中占用寄存器。” 这解释了为什么不允许使用 10 个vec3s。 “数组的元素必须在不同的行中。” 所以一个数组不能有超过MAX_VARYING_VECTORS 个元素。
    • 这一点似乎也很重要:"如果在片段着色器中引用(在预处理之后),则内置特殊变量(gl_FragCoordgl_FrontFacing 和 @987654336 @) 在计算变量的存储需求时包括在内。”
    • @TachyonVortex 我知道这是一个有点旧的帖子,但似乎数组限制并不总是适用。在我的 Mac 机器上的 Firefox 上,gl.getParameter(gl.MAX_VARYING_VECTORS) 返回 16,但我可以使用 32 个元素的 vec2 数组。然而,在Chrome上,我的MAX_VARYING_VECTORS是31,浏览器拒绝链接程序,说Varyings over maximum register limit。我需要一个包含大约 50 个元素的不同 vec2 数组,我想知道如何实现。
    • 这看起来像是 Firefox 36 中的一个错误。The conformance test 在我的 Mac 上对我来说失败了。检查FirefoxNightly (FF 39) 似乎已修复。也许您应该尝试一下,看看您的程序是否开始具有与 Chrome 相同的行为。至于需要 50 个 vec2,听起来你是 S.O.L.如果MAX_VARYING_VECTORS 是 16,那么您可能拥有的最多 vec2 是 32。
    • 奇怪的是,我的程序在 firefox 和 nightly 中仍然可以使用 50 个 vec2。对我来说万岁,但在一致性方面不是很好。
    猜你喜欢
    • 1970-01-01
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多