WebGL Float 模数行为
WebGL Float modulus behaviour
我遇到以下片段着色器的奇怪行为:
varying vec3 worldSpaceCoords;
uniform float rows;
void main() {
float testNumber = 7.0;
vec4 outputColor = vec4(0.0,0.0,0.0,1.0);
if(rows == testNumber) {
if(worldSpaceCoords.x < 0.5) {
outputColor.x = mod(floor(testNumber * worldSpaceCoords.y), rows ) / rows;
} else {
outputColor.x = mod(floor(testNumber * worldSpaceCoords.y), testNumber ) / testNumber;
}
} else {
outputColor = vec4(1.0,1.0,1.0,1.0);
}
gl_FragColor = outputColor;
}
"testNumber" 变量只是我的控制变量,用于检查传入的制服 "rows" 实际上是它应该是什么。
制服的一些号码 "rows",给出了一个奇怪的行为。下面是一个设置为 9.0 的示例(相应地设置了 testNumber)。
这个结果是意料之中的。但是,将行设置为 7.0(并相应地设置 testNumber),它看起来像这样:
显然有些东西没有正常工作。任何想法为什么?我试过将精度设置为 lowp、mediump 和 highp 没有任何区别。
谢谢
这可能是不精确的浮点数学的结果,它遵循 GLSL ES Specification 中记录的规则。 highp 限定符保证 mod 运算符的输入和输出是 32 位 IEEE 754 浮点数,但是计算本身不能保证产生相同的高精度。特别是,modulus 运算符在第 8.3 章中定义为
genType mod (genType x, genType y)
Modulus. Returns x – y * floor (x/y).
这个表达式中的除法运算符a/b保证精度不低于2.5 ULP for b (参见第 4.5.1 章)并且通常计算为 a*(1/b),因为倒数和乘法比除法便宜。在您的情况下,1/testNumber 是一个编译时常量,可能计算为与 1/rows 不同(更高)的精度,后者需要在 运行 时计算。
您可以尝试使用整数数学而不是浮点数,因为整数 modulus 运算符 a%b 不会遇到此类精度问题。
我遇到以下片段着色器的奇怪行为:
varying vec3 worldSpaceCoords;
uniform float rows;
void main() {
float testNumber = 7.0;
vec4 outputColor = vec4(0.0,0.0,0.0,1.0);
if(rows == testNumber) {
if(worldSpaceCoords.x < 0.5) {
outputColor.x = mod(floor(testNumber * worldSpaceCoords.y), rows ) / rows;
} else {
outputColor.x = mod(floor(testNumber * worldSpaceCoords.y), testNumber ) / testNumber;
}
} else {
outputColor = vec4(1.0,1.0,1.0,1.0);
}
gl_FragColor = outputColor;
}
"testNumber" 变量只是我的控制变量,用于检查传入的制服 "rows" 实际上是它应该是什么。
制服的一些号码 "rows",给出了一个奇怪的行为。下面是一个设置为 9.0 的示例(相应地设置了 testNumber)。
这个结果是意料之中的。但是,将行设置为 7.0(并相应地设置 testNumber),它看起来像这样:
显然有些东西没有正常工作。任何想法为什么?我试过将精度设置为 lowp、mediump 和 highp 没有任何区别。
谢谢
这可能是不精确的浮点数学的结果,它遵循 GLSL ES Specification 中记录的规则。 highp 限定符保证 mod 运算符的输入和输出是 32 位 IEEE 754 浮点数,但是计算本身不能保证产生相同的高精度。特别是,modulus 运算符在第 8.3 章中定义为
genType mod (genType x, genType y)
Modulus. Returns x – y * floor (x/y).
这个表达式中的除法运算符a/b保证精度不低于2.5 ULP for b (参见第 4.5.1 章)并且通常计算为 a*(1/b),因为倒数和乘法比除法便宜。在您的情况下,1/testNumber 是一个编译时常量,可能计算为与 1/rows 不同(更高)的精度,后者需要在 运行 时计算。
您可以尝试使用整数数学而不是浮点数,因为整数 modulus 运算符 a%b 不会遇到此类精度问题。