绘制线主要是考虑圆形接头和抗锯齿。
方法1:使用CPU预先剖分
我是这么剖分成三角形的:
我使用两个边线的交点来求A点坐标。不是交点的另一边使用圆弧来连接。
方法2:使用GPU绘制
将折线划分为线段,每个线段在顶点着色器中向外偏移。
使用片段着色器来判断是否丢弃来达到圆头。最开始我试图传参考点的坐标给片段着色器,但因为插值的原因,不得不额外增加顶点。
后来经过优化,使用如下的uv坐标传递给片段着色器,来判断圆头和参考点的距离。这样一个线段只需要4个顶点。
方法3:分离圆头方法
有一种简单方法是把绘制线段和绘制圆头分开。在圆头处绘制一个圆形,然后再上面覆盖绘制上线条。这种方法没法支持半透明。优点是实现非常简单。
方法4:法线方法
网上有这种通过法向量的方法来做的。
但是这个方向长度为宽度一半的位置不是正确的,会导致转弯处线宽变窄。我试图纠正转弯处变窄的问题,但是我发现再非常锐的夹角的地方,偏移会无限长,只能截取到一个最大的偏移值。
由于简单,可以再GPU中实现。如果线的形状点比较密集的话效果还不错。
CPU方法和GPU方法比较
- CPU是在世界空间中处理的,侧面看就有问题。可以很好的实现抗锯齿。支持半透明。
- GPU实现一直保持像素宽度。由于每个线段有重叠,所以不支持半透明。
虚线绘制
每个点记录距离折线起点的路径距离。片段着色器会对这个距离进行插值,刚好是我们想要的距离。然后将这个距离余处以虚线大小,适当discard片段。得到虚线效果。