2018年6月21日

WebGL绘制位图时出现黑白边解决方案

作者 admin

最近发现设计给的图片放到cocos工程文件夹下面出现了黑边,后来踩了一些坑总算是找到了一些靠谱的解决办法。

提前预习

在解决问题前 要先补一下相关知识点,“webgl绘制原理”,“图片预乘”,“图像混合模式”。

webgl绘制原理 :https://www.cnblogs.com/wanbo/p/6754066.html

图片预乘是什么意思  https://zhidao.baidu.com/question/2075235815519489868.html

WebGL与OpenGL es、

发现问题:第一反应是寻找问题的原因,发现当我把渲染模式切换为canvas时候 位图是没有黑边的 。一旦开启webgl渲染模式 就出现了黑边,初步怀疑是当webgl渲染图片时候,png图片实色与透明色交接的地方有半透明(小数级别的),gpu渲染时候为了节约开销,把这部分半透明色渲染成了黑色的边缘线,webgl着色器语言走的是OpenGL,恰恰OpenGL es有这个问题 ,于是乎让设计把图片的边缘小数值调整为整数,避免小数,但是还是有问题 。

再一次进入深思,究竟还差什么没有想到,之后我查阅一些资料发现 同样一张图片 放到了  u3d 与 creator下的对比,放到u3d中 图片是没有黑边的,在creator里面再次浮现,看到下面有人谈论到了“图像混合模式”与“图片预乘”这个概念。

cocos2d-x

随后翻了一下 cocos2d的源代码,发现2dx会对没有预乘的图片加载的时候会做一次预乘,然后混合时用one,creator跟2dx不同,creator默认是alpha混合,所以导致很多地方会出现灰色的轮廓,必需手动设置用one才不会有黑边(如果你的图片没有经过预乘处理,那么调整one后会出现白边,方案行不通)。

换句话说2dx更加智能,在图像混合模式中默认对图片进行 WebGL 预乘,如果发现贴图是已经预乘过的,那么 Sprite 就使用 ONE 作为 blend src,否则使用 SRC_ALPHA。

但是这里面还是潜在一个问题的,当用户把这个图片进行替换纹理时候,调整预乘属性,这个智能就出现了”bug”, 这时候你手动修改他的贴图渲染模式后,它会再次自动根据贴图的预乘属性重新设置 Blend function,而不管你是否手动修改过,潜在有不可控的问题。

Creotor

显然在creator里  对贴图进行 webGL 预乘,发现

额 这里默认是src_ALPHA渲染方式,我们把第一行修改为one,

手动设置one的后果就是半透明以及透明像素显示错误,除非手动将图片资源处理成预乘模式,再使用one混合,这个问题比较少见……,在ps cc2017在绘制半透明区域好像是多绘制了一个像素,所以,显示无误(经测试在安卓跟pc是没问题,但是在苹果上还是不行),同样放到flashcc 与 scach这种软件里面导出的图导出还是有黑边。

思考后只能把问题解决办法放到如何给图片加预乘这个上面

图片预乘原理:

在美工导出图片时候 图片经过预乘处理 ,在到creator里面吧混合模式 调整为one , one_MINUS_SRC_ALPHA 就ok了,虽然问题得以解决,但是这样每张图片都要进行设置,这就很尴尬了,