浮动统一舍入是否存在GLSL问题
Is there GLSL problem with float uniform rounding
我将 Unix 时间从 Java 代码传递到我的着色器:
gl.uniform1f(shader, System.currentTimeMillis());
着色器看起来像(简单的形式,只是为了调查问题):
#ifdef GLES
precision highp float;
#endif
uniform float u_time;
void main() {
int d = 1000;
float result = floor(u_time / d) * d;
if (result > u_time) {
s = 1.0;
} else {
s = 0.5;
}
gl_FragColor = vec4(s, 0, 0, 1.0);
}
我预计 result
永远不会大于 u_time
。令人惊讶的是(着色器产生鲜红色)。
此外,如果将 d
的值替换为 100,例如,它会按预期工作 - 呈现暗红色。
尝试用 float
值 100.0 替换 d
,但没有任何效果。
即使我将表达式中的 u_time
替换为直接浮点常量,例如 1563854457241.0,它也能正常工作 - Java 放入着色器的结果大致相同。
可能是什么问题?我怀疑它与精度有关,但不知道如何解决它。
P.S。毕竟,如果用
替换条件表达式,我得到 TRUE(亮红色)
1000000123.0 * 1000 == 1000000123456.0
努夫说。
在您的着色器代码中,您已经超出了 32 位浮点数的精度限制。
参见 IEEE 754 and GLSL ES -Precision and Precision Qualifiers。
当您使用精度限定符 highp
时,有效位的数量为 23(+1 为符号),因此像 1000000123456.0
这样的数字不能用完整精度表示,因为近似数字小数位数是 7.22.
我将 Unix 时间从 Java 代码传递到我的着色器:
gl.uniform1f(shader, System.currentTimeMillis());
着色器看起来像(简单的形式,只是为了调查问题):
#ifdef GLES
precision highp float;
#endif
uniform float u_time;
void main() {
int d = 1000;
float result = floor(u_time / d) * d;
if (result > u_time) {
s = 1.0;
} else {
s = 0.5;
}
gl_FragColor = vec4(s, 0, 0, 1.0);
}
我预计 result
永远不会大于 u_time
。令人惊讶的是(着色器产生鲜红色)。
此外,如果将 d
的值替换为 100,例如,它会按预期工作 - 呈现暗红色。
尝试用 float
值 100.0 替换 d
,但没有任何效果。
即使我将表达式中的 u_time
替换为直接浮点常量,例如 1563854457241.0,它也能正常工作 - Java 放入着色器的结果大致相同。
可能是什么问题?我怀疑它与精度有关,但不知道如何解决它。
P.S。毕竟,如果用
替换条件表达式,我得到 TRUE(亮红色)1000000123.0 * 1000 == 1000000123456.0
努夫说。
在您的着色器代码中,您已经超出了 32 位浮点数的精度限制。
参见 IEEE 754 and GLSL ES -Precision and Precision Qualifiers。
当您使用精度限定符 highp
时,有效位的数量为 23(+1 为符号),因此像 1000000123456.0
这样的数字不能用完整精度表示,因为近似数字小数位数是 7.22.