【问题标题】:Shader limitations着色器限制
【发布时间】:2009-11-24 20:38:36
【问题描述】:

我一直在为配备 Radeon HD 3850 的笔记本电脑调整游戏的渲染器。该芯片具有不错的处理能力,但内存带宽有限,因此我一直在尝试将更多着色器工作转移到更少的传球次数。

以前,我使用的是简单的多通道模型:

  • 绑定并清除 FP16 混合缓冲区(带深度缓冲区)
    • 仅深度通道
    • 对于每个灯光,执行一个附加灯光通道
  • 绑定后台缓冲区,使用混合缓冲区作为纹理
    • 色调映射通道

为了提高这种方法的性能,我编写了一个新的渲染路径,用于计算灯光的数量和类型,以动态构建自定义 GLSL 着色器。这些着色器接受所有光照参数作为制服,并在一次通过中完成所有光照。我预计会遇到某种限制,所以我先用一盏灯对其进行了测试。然后三个。然后是 21 个,没有错误或伪像,并且表现出色。这引出了我的实际问题:

制服的最大数量是可取的吗?

这种方法在旧硬件上是否可行,还是制服更受限制?

如果我推得太远,我会在什么时候收到错误?着色器编译?程序链接?使用该程序?

【问题讨论】:

    标签: c++ opengl glsl shader


    【解决方案1】:

    着色器统一通常由硬件作为寄存器实现(或者有时通过将值直接修补到着色器微代码中,例如 nVidia 片段着色器)。因此,该限制高度依赖于实现。

    您可以通过分别查询 GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARBGL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 的顶点和片段着色器来检索最大值。

    【讨论】:

    • 请注意,对于 GL2.0,您保证至少有 512 个顶点制服和 64 个片段制服。
    • 哦,我的 RTFM 失败了。想到更多问题:浮点数和整数是否都消耗一个组件?包装有什么限制吗?四个浮点数与一个 vec4?一个浮点数和一个 vec3?
    • @mvanbem:一件制服至少占用一个 4D 矢量。因此,如果您对统一存储非常严格,请考虑将多个标量打包到一个 4D 向量中。
    【解决方案2】:

    请参阅 4.3.5 Uniform 的 OpenGL® 着色语言 specs

    对于可用于 每种类型的着色器,如果超过,将导致编译时或链接时错误。制服 已声明但未使用的变量不计入此限制。

    它将在链接或编译时失败,但不使用程序。

    【讨论】:

      【解决方案3】:

      有关如何获得 OpenGL 实现支持的最大数量,请参阅 moonshadow 的答案。

      要了解任意 GPU 的实际限制在哪里,我建议查看 GPU 支持的 DX 版本。

      DX9 级硬件:

      • vs2_0 支持 256 vec4。 ps2_0 支持 32 vec4。
      • vs3_0 是 256 vec4,ps3_0 是 224 vec4。

      DX10级硬件:

      vs4_0/ps4_0 是每个常量缓冲区最少 4096 个常量 - 您可以拥有 16 个。

      简而言之,基于 DX10 的任何东西都不太可能用完。

      【讨论】:

        【解决方案4】:

        我猜制服的最大数量是由显存的数量决定的, 因为它只是一个变量。 cpu 上的普通变量也受 RAM 的限制吧?

        【讨论】:

        • 制服有硬件设置的严格限制。现代硬件有非常高的限制,但它们仍然存在。较旧的硬件(2 年以上)的限制可能要低得多。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多