【问题标题】:How to deal with NaN or inf in OpenGL ES 2.0 shaders如何在 OpenGL ES 2.0 着色器中处理 NaN 或 inf
【发布时间】:2016-12-08 16:52:35
【问题描述】:

这是基于以下问题:Best way to detect NaN's in OpenGL shaders

标准 GLSL 定义了 isnan() 和 isinf() 函数用于检测。 OpenGL ES 2.0 着色语言没有。尽管如此,我该如何处理 NaN 和 Inf?

【问题讨论】:

    标签: android iphone opengl-es opengl-es-2.0 gpgpu


    【解决方案1】:

    您可以通过仅适用于 NaN 的条件检查 NaN:

    bool isNan(float val)
    {
      return (val <= 0.0 || 0.0 <= val) ? false : true;
    }
    

    isinf 有点困难。没有将浮点数转换为其整数表示并使用位的机制。所以你必须将它与一个适当大的数字进行比较。

    【讨论】:

    • 谢谢!为什么官方规范中没有这个?有没有这不起作用的平台?
    • @RafaelSpring 可能有。众所周知,大多数 GPU 硬件都采用 w.r.t 的捷径。导致 non- 符合 IEEE 754 的浮点数的浮点数。因此,我怀疑您要求的行为是否得到保证。因此,正如 Nicol 建议的那样,您最好的选择可能是对正常操作期间预期的最小值和最大值有一个很好的了解,并检查您的值是否在该范围内。否则,它可能是InfNaN
    • @SchighSchagh 如果编译器和/或 GPU 不符合 IEEE-754 标准,则在涉及 NaN 的情况下,甚至可能无法保证比较运算符的结果。我遇到过松懈的编译器为&lt; 生成代码的情况,如果任一参数为NaN,则该代码始终评估为真。最安全的方法是从一开始就防止生成 NaN。
    【解决方案2】:

    WebGL 也有同样的问题。 Nicol Bolas 的答案适用于大多数 GPU,但不适用于某些 nVidias。此版本适用于我有机会尝试的所有 GPU:

    bool isNan( float val )
    {
      return ( val < 0.0 || 0.0 < val || val == 0.0 ) ? false : true;
      // important: some nVidias failed to cope with version below.
      // Probably wrong optimization.
      /*return ( val <= 0.0 || 0.0 <= val ) ? false : true;*/
    }
    

    【讨论】:

      【解决方案3】:

      未经测试,因此不确定这是否可行(由于优化),但它应该适用于 Inf 和 -Inf。

        bool isinf(float val) {
          return (val != 0.0 && val * 2.0 == val) ? true : false;
        }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-10
        相关资源
        最近更新 更多