问题
用 OpenGL 旋转图片的时候,图片边缘会出现锯齿。
图 1 是没有做抗锯齿的时候,可以明显看到边缘的锯齿。
图 1
思路
首先想到的是 OpenGL 提供的 MSAA,但是 MSAA 占用内存比较多。然后去查了下 skia 的抗锯齿是如何实现的,发现它只是对图片边缘的 1px 做一个 alpha 从 1->0 渐变的遮罩。
如图 2 所示,矩形 abcd 是我们要绘制的区域,根据矩形的坐标向内缩 0.5px 得到矩形 P0_P1_P3_P2,向外扩 0.5px 得到矩形 P4_P5_P7_P6。内矩形里面 alpha 都是 1,外矩形边缘 alpha 都是 0,内矩形和外矩形之间 alpha 从 1->0 渐变。这样我们就对边缘做了一个逐渐消失的效果,从视觉上看,边缘的锯齿就没那么明显了。
图 2
解决
没有抗锯齿
在没有使用抗锯齿时,我们绘制一个矩形,提交的是 cdba 4 个顶点,2 个三角形。
1 2 3 4 5 6 7 8 |
|
对应的绘制命令是
1
|
|
抗锯齿 CoverageAA
在使用 CoverageAA 抗锯齿时,我们绘制一个矩形,提交的是内矩形 P0P1P2P3 和外矩形 P4P5P6P7 的 8 个顶点:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
转换成三角形是 30 个顶点,下面是三角形的 index 数据
1 2 3 4 5 6 7 8 |
|
绘制命令是
1
|
|
结果
图 3 是做完抗锯齿的效果,可以看到边缘的锯齿已经没有了。
图 3
图 4 是图 1 和 图 3 边缘对比的细节,可以看到边缘像素的过渡圆滑了很多。
图 4