【发布时间】:2013-05-22 20:49:27
【问题描述】:
我目前正在使用 GLSL 330,并且遇到了 mod() 函数的一些奇怪行为。 我在 Windows 8 下使用 Radeon HD 6470M 工作。我无法在使用 Windows 7 和 GeForce GTX 260 的台式电脑上重现此行为。
这是我的测试代码:
float testvalf = -126;
vec2 testval = vec2(-126, -126);
float modtest1 = mod(testvalf, 63.0); //returns 63
float modtest2 = mod(testval.x, 63.0); //returns 63
float modtest3 = mod(-126, 63.0); //returns 0
编辑:
以下是在 IceCools 建议后完成的更多测试结果。
int y = 63;
int inttestval = -126;
ivec2 intvectest(-126, -126);
float floattestval = -125.9;
float modtest4 = mod(inttestval, 63); //returns 63
float modtest5 = mod(intvectest, 63); //returns vec2(63.0, 63.0)
float modtest6 = mod(intvectest.x, 63); //returns 63
float modtest7 = mod(floor(floattestval), 63); //returns 63
float modtest8 = mod(inttestval, y); //returns 63
float modtest9 = mod(-126, y); //returns 63
我更新了驱动程序并再次测试,结果相同。再次无法在桌面上重现。 根据mod 上的 GLSL 文档,可能的参数组合是 (GenType, float) 和 (GenType, GenType) (没有双精度,因为我们小于 4.0)。返回类型也被强制浮动,但这对于这个问题应该无关紧要。
【问题讨论】:
-
你能测试一下 int x = -126/63 是否返回 -3 吗?这听起来很奇怪,但 int 除法并不是那么简单,也许 ATI 实现将其降级为浮点除法,并将结果转换回 int。正如我们在 modtest1 (int)(-126.0/63.0) 看到的那样是 -3
-
我刚刚测试了 -126/63,既通过将它分配给一个变量,也通过测试 if 子句中的返回值。两次结果都是-2。我还测试了 int((-126.0/63.0)) ,它也按预期返回 -2。我的想法慢慢用完了,您的浮点精度错误最符合逻辑,我想不出其他任何可能导致它的原因。
-
似乎除了精度问题之外的其他事情正在发生,因为对于所有可能的精度和所有可能的 x 和 y 值,不变量
!(abs(mod(x, y)) >= abs(y))应该始终为真。打破这打破了图形程序中的mod。 (奇怪的 !...>= 使得它对于 NaN 值也总是正确的)。
标签: opengl glsl modulo opengl-3