近日在自己的游戏中,有一个用到调色盘的需求,也就是用同一张图片,通过替换指定的一些颜色来制作出多种所属方的效果。
于是我编写了一个shader实现这个功能。思路就是判断当前点的颜色是否等于要被替换的颜色,如果是的话,就渲染成替换后的颜色。
在我的pc上,这个shader工作的毫无问题;但是在手机上,却没有发生颜色的替换。我想到这要么是数据精度的问题,要么是纹理的像素格式不是RGBA8888,导致shader中color1.rgb == color2.rgb这个用来"判断颜色是否为要被替换的颜色"的环节出了问题。
既然不能准确地判断相等,但却可以退而求其次;只要两个颜色的相似程度非常之高,那么也可以判定它们相等。
GLSL中提供distance函数,判断两个vec的距离。而GLSL中是用vec4来表示颜色的,因此,distance函数可以用来计算两个颜色的相似程度,结果越大,两个颜色间的差异越大,结果越小,两个颜色间的差异越小。
所以color1.rgb == color2.rgb这样的条件可以更换成distance(color1.rgb, color2.rgb) < 0.05这种条件,这样就容忍了精度的问题。在手机上调试,果然实现颜色替换了,而且并没有肉眼易识别的误差。
你可以用点乘的方式,dot(color1.rgb,color2.rgb) >0.9
最近由 hont 修改于:2018-08-19 07:52:05完全相等结果是1,其他情况小于1.
@hont:感谢你的建议
RGB值的曼哈顿距离很难反映出两个颜色在人眼感知中是否差异巨大。对HSL/HSV值选取分量权重可能效果更佳。
https://stackoverflow.com/questions/15095909/from-rgb-to-hsv-in-opengl-glsl
@Justus:谢谢你的建议,我会做出修改的