我目前正在使用GLSL 330并遇到了mod()函数的一些奇怪行为。 我在Windows 8下使用Radeon HD 6470M工作。我无法在使用Windows 7和GeForce GTX 260的台式PC上重现这种行为。
这是我的测试代码:
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
我更新了我的驱动程序并再次测试,结果相同。再次无法在桌面上重现。 根据{{3}}上的GLSL文档,可能的参数组合是(GenType,float)和(GenType,GenType)(没有double,因为我们<4.0)。返回类型也被强制浮动,但这对于这个问题无关紧要。
答案 0 :(得分:2)
我不知道如果你是按照意图做的,但-126是一个int而不是一个浮点数,而且代码可能没有达到预期的效果。
关于模数的方式: 请注意,调用了两个不同的函数:
前两行:
float mod(float, float);
最后一行:
int mod(int, float);
如果我是对的mod计算如下:
genType mod(genType x, float y){
return x - y*floor(x/y);
}
现在请注意,如果x / y计算-2.0,它将返回0,但如果它的计算结果为-2.00000001,则返回63.0。 int / float和float / float除法之间的差异并非不可能。
所以原因可能只是你正在使用整数和浮点数。
答案 1 :(得分:2)
我想我找到了答案。
我错误的一点是{em> genType 的mangsl关键字并不代表通用类型,就像在c ++模板中一样。
GenType 是 float , vec2 , vec3 和 vec4 的简写(参见link - ctrl + f genType )。
Btw genType 命名就像:
genType - floats
genDType - doubles
genIType - ints
genBType - bools
这意味着genType mod(genType, float)
意味着没有像int mod(int, float)
这样的功能。
上面的所有代码都在调用float mod(float, float)
(幸好有函数参数的隐式类型转换,所以mod(int, int)
也可以工作,但实际上调用了mod(float, float)
。
正如证据:
int x = mod(-126, 63);
Doesn't compile: error C7011: implicit cast from "float" to "int"
它只能起作用,因为它返回float,所以它的工作原理如下:
float x = mod(-126, 63);
因此调用float mod(float, float)
。
所以我们回到原来的问题:
precision highp float;
应该修复它),或者你的GPU对浮点相等性有更严格的限制,或者某些函数返回的准确值不太准确。如果其他所有方法都失败了,请尝试:
#extension BlackMagic : enable
答案 2 :(得分:0)
也许某些驱动程序设置强制默认浮点精度为 mediump 。
如果发生这种情况,您所定义的所有变量都将是 mediump ,但是,代码中输入的数字仍将保持 highp 。 请考虑以下代码:
precision mediump float;
float x = 0.4121551, y = 0.4121552;
x == y; // true
0.4121551 == 0.4121552; // false, as highp they still differ.
因此mod(-126,63.0)
仍然可以精确到足以返回正确的值,因为它使用高精度浮点数,但是如果你给出一个变量(就像所有其他情况一样),它只会是 mediump ,该函数没有足够的精度来计算正确的值,当您查看测试时,就会发生这种情况: