【问题标题】:Why does "discard" only slightly but "gl_FragDepthEXT" significantly reduce performance?为什么“丢弃”只是轻微但“gl_FragDepthEXT”会显着降低性能?
【发布时间】:2015-09-20 12:02:29
【问题描述】:

根据我目前所读到的内容,在片段着色器中使用丢弃或更改深度值将禁用早期深度测试,从而降低着色器性能。

现在我有一个应用,使用丢弃只会产生很小的影响,但更改深度值会严重降低性能: http://potree.org/demo/experimental/early_depth/examples/philly.html (如果对您来说太快,请增加点大小并放大)

  • 将质量设置为“圆圈”将调用丢弃,以便将点渲染为圆圈。
  • 将质量设置为“插值”将更改片段深度值。

我得到了这些结果:

  • 正方形:55fps
  • 圈数:52fps
  • 插值:30fps

当使用插值时,会发生一些额外的事情,但我已经检查过它是“gl_FragDepthEXT = ...”,任何类型的值都会影响性能。

【问题讨论】:

    标签: opengl-es webgl


    【解决方案1】:

    规范基本上说深度测试发生在片段着色器处理之后。但是,规范明确指出,如果结果不受影响,则允许实现以任何顺序执行操作。

    所以,gl_fragDepthEXT,通常最好先在前面绘制不透明的东西,然后再在后面绘制,因为 GPU 可以在运行片段着色器之前进行深度测试。如果深度测试失败,则不必运行片段着色器。设置gl_fragDepthEXT 会改变这一点,因为它在运行片段着色器之前无法进行深度测试,因为通过设置gl_fragDepthEXT 你已经告诉它你将决定深度值。

    换句话说,当您不使用gl_FragDepthEXT 时,许多像素永远不必运行它们的片段着色器,因为早期的深度测试会将它们排除在外。在另一种情况下,您使用gl_FragDepthEXT 每个像素都必须运行片段着色器,因为在您告诉它您正在计算的深度值之前,GPU 无法进行深度测试。

    至于discard,我个人从未见过需要更多时间。也许与什么相比,时间更长?如果您有一个分支if (cond) discard;,那么您至少需要将它与具有类似分支if (cond) color = red; 或类似分支的着色器进行比较

    【讨论】:

    • 实际上,根据 GPU 架构,discard 也可能会阻止使用 early-z。在某些情况下,z 缓冲的读取-比较-更新周期被实现为单个原子条件内存更新。在这种情况下,早期的测试包括更新 z 缓冲区,以后不再可能丢弃片段。
    猜你喜欢
    • 2014-03-11
    • 1970-01-01
    • 2017-07-07
    • 1970-01-01
    • 2011-12-15
    • 2020-01-31
    • 1970-01-01
    • 2012-10-02
    • 1970-01-01
    相关资源
    最近更新 更多