Float value issue in GLSL
在编写 Shader 特效的过程中,遇到一个奇怪的问题,表现怪异,逻辑大致如下:
out_color += add_color * factor;
其怪异表现为,即使在确认 factor 为 0(或无限
接近于0.0)时,预期效果应该是无叠加 add_color
的,但是实际会有很小的一条线,
从逻辑分支即:add_color * 0 != 0
这显然是无法理解的。
为解决此问题,进行若干尝试,首先,尝试直接改成 out_color += add_color * 0.0;
这样有效,但于解决实际问题无补。若怀疑 factor 可能非 0,做如下尝试:
factor = step(0.5, factor);
即只要 factor 小于 0.5 就返回 0. 如此尝试后,原问题
仍然出现。此问题大概率与 factor 无关。
继续探究 add_color
的问题,在前阶段计算中,该值可能非常大,于是考虑进行 clamp,
经试验,发现,如下修改可以规避问题出现:add_color = clamp(add_color, 0.0, 100.0);
虽然这样可以解决问题,但是似乎是补救之道,而未解决根源。继续回溯,发现 add_color
的来源是一个除法计算,其中分母可能为 0,当出现除 0 操作时,其结果数值其实应该
是 NA 了,那么后续即使乘 0,也无法保证结果一定是 0 了。
解决方法:在除法计算中为分母增加一个极小 epsilon.
在解决这个问题过程中的意外收获: 将 float 的精度声明从 mediump 改成 highp 也
可以规避这个问题。