我遇到了以下片段着色器的奇怪行为:
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;
}
&#34; testNumber&#34;变量只是我的控制变量来检查传入的统一&#34;行&#34;实际上应该是它应该是什么。
一些统一的&#34;行&#34;,给出了奇怪的行为。下面是一个示例,它设置为9.0(相应地设置了testNumber)。
预期此结果。但是,将行设置为7.0(以及相应的testNumber),它看起来像这样:
显然有些东西不能正常工作。有什么想法吗?我试图将精度设置为lowp,mediump和highp而没有任何差别。
由于
答案 0 :(得分:1)
这很可能是浮点数学不精确的结果,它符合GLSL ES Specification中记录的规则。 highp 限定符保证 mod 运算符的输入和输出是32位IEEE 754浮点数,但计算本身并不能保证产生相同的高精度。特别是,模数运算符在第8.3章中定义为
genType mod(genType x,genType y)
模量。返回x - y * floor(x / y)。
此表达式中的除法运算符 a / b 保证 b 的精度不低于2.5 ULP(参见第4.5.1章),通常是计算为 a *(1 / b),因为倒数和乘法比分数便宜。在您的情况下, 1 / testNumber 是一个编译时常量,可能计算为与 1 / rows 不同(更高)的精度,需要在运行时计算-time。
您可以尝试使用整数数学而不是浮点数,因为整数模数运算符 a%b 不会遇到此类精度问题。