将OpenGL彩色喷枪uint8转换为float时,为什么要除以255而不是较快的256? 255的1.0f而非0.996f至关重要吗?

时间:2019-04-04 11:37:07

标签: opengl

我正在研究许多OpenGL开发的渲染代码,这些渲染代码通过例如将COLORREF转换为float[3]float[4]的方法。 rgb[0] = ((float)GetRValue(col)) / 255.0f;,这正在与我敲响性能警报。 255.0f显然可以是整数,但是为什么不使用更快的256除法呢?

我们的首席图形程序员不同意这个建议,因为red = 255转到1.0f之外的任何东西都是“道德上的错误”,但是稍微降低float值的实际后果是什么?到底有什么可识别的?

1 个答案:

答案 0 :(得分:3)

  

为什么不使用256的更快除法?

将整数除以256会更快,但是您不是整数除,是吗?浮点除法通常没有基于这样的特定值的快捷方式。如果必须进行浮点除法,则需要支付浮点除法的费用。

This Godbolt example表明,在优化程度较高的情况下,Clang找不到方法将256.0f除以比255更快的速度。GCC和MSVC确实得到了一个小的优化:它们用乘以编译时计算值1 / 256.0f,这是一个精确的浮点数。但是您可以通过拥有代码explicitly multiply by (1 / 255.0f)来完成同一件事,因此,再次没有优势。

现在,从理论上讲,有更快的方法可以将无符号整数值标准化为浮点型。但是,这些方法通常依赖于浮点值的直接位操作,并且实际上不会比仅进行浮点数学运算要快。您必须在打算使用它们的特定情况下对其进行概要分析,以使其起作用。


  

稍微降低浮点值的实际结果是什么?到底有什么可识别的?

后果可能是任何事情。就现代OpenGL而言,您为OpenGL提供的每个值的含义完全取决于您的代码。确实,您的代码可以加上0.996的除法来重新调整数字,因此没有真正的区别。

编写一段着色器代码很容易,如果您拒绝传递正确标准化的浮点值(执行if(value == 1.0f)的任何事情,如果正确进行标准化就必须为true),该着色器代码会中断。我可以轻松编写不需要的代码。没有普遍的答案;这一切都取决于您在做什么。

兼容性OpenGL本质上是相同的方式:一切都取决于您正在使用做什么。它可能是固定功能的,而不是着色器,但仍有很多空间可以定义该数字的含义。

由于结果的可行性是基于您在简单的normalizeIntegerToFloat函数级别上无法了解的信息,因此您应该为函数的 caller 提供一个选择。提供准确的版本 和有损版本。您绝对不应该将有损版本设置为默认版本。如果该功能的用户发现性能问题,则可以切换到使用有损版本来缓解该问题。