在OpenGL着色器中检测NaN的最佳方法

时间:2012-02-25 18:40:04

标签: opengl glsl nan

今天早上我遇到了一个似乎是一个神秘的小虫,我很幸运能够很快找到解决方案。

我用计数器除以产生片段着色器的平均值,当然当计数器为零时,得到的颜色值变为NaN。

在混合期间,NVidia会优雅地将NaN视为0值,但英特尔不会并且似乎级联NaN,从而导致黑色碎片。

所以这个bug一直存在,直到我在Intel机器上测试代码。

我想知道我能做些什么来“捕获”无效的值。看起来,就像在常规编程中一样,唯一可靠的方法(即使那时它也不会感到防弹)处理这个问题的方法是在划分数字时仔细考虑所有可能的情况。

检测NaN的标准方法是查看数字是否与自身不相等。我是否可以构建一个调试着色器来检查每个片段以查看它是否与自身不相等,如果满足该条件,则设置一个闪烁的,显眼的颜色? GLSL是否允许我以这种方式检测NaN,或者只要值无效,我是否会遇到未定义的行为?

2 个答案:

答案 0 :(得分:18)

  

我用计数器除以产生片段着色器的平均值,当然当计数器为零时,得到的颜色值变为NaN。

这不是浮动的工作方式。除以零后,得到 INF ,而不是NaN。除非分子也为零,否则你会得到NaN。

在任何情况下,GLSL都提供isinfisnan功能,这些功能可以按照他们的说法进行。

答案 1 :(得分:5)

缺少isnan是WebGL和Opengl ES 2.0的问题。 Polyfill适用于我有机会尝试的所有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;*/
}