如何在OpenGL ES 2.0着色器中处理NaN或inf

4
3个回答

5
您可以通过一个条件来检查NaN,这个条件只对NaN为真:
bool isNan(float val)
{
  return (val <= 0.0 || 0.0 <= val) ? false : true;
}

isinf 是一个比较难的概念。没有一种机制可以将浮点数转换成整数表示并操作比特位。所以你需要将其与足够大的数字进行比较。


谢谢!为什么这不在官方规范中?有哪些平台不支持这个功能? - rsp1984
2
@RafaelSpring 可能会有。众所周知,大多数GPU硬件在浮点数方面采取了捷径,导致__非__IEEE 754兼容的浮点数。因此,我怀疑您需要的行为是否得到保证。正如Nicol建议的那样,您最好对正常操作期间预期的最小和最大值有一个很好的想法,并检查您的值是否在该范围内。否则,它可能是InfNaN - Nicu Stiurca
即使编译器和/或GPU不符合IEEE-754标准,比较运算符的结果也可能无法保证涉及NaNs。我经历过这样的情况,松散的编译器为 < 生成代码,如果任一参数是 NaN,则始终计算为真。最安全的方法是防止NaNs首先产生。 - Sean

2

WebGL也存在同样的问题。Nicol Bolas的答案对大多数GPU有效,但对某些nVidia GPU无效。我尝试过的所有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;*/
}

0

未经测试,所以不确定这是否可行(由于优化),但它应该适用于正无穷和负无穷。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接