斑马线在交通场景里很常见,现实中可以看到斑马线其实比较多是规则的矩形,不过也有不规则的四边形组成的斑马线,比如下图:

从美观角度可能就有了左边平行四边形这种,不过本文主要探讨下怎么在 threejs 中画右边这种垂直于主轴的斑马线(人行方向为主轴)
简版
当然实际上都可以做成矩形,对于智驾算法而言都无所谓,大部分都只 care 最外层的边框,所以只画边框的话,可以直接用多条 Line 来绘制多边形
接口约定
interface CrosswalkData {
contour: THREE.Vector3[]; // 四边形的4个顶点(有序)
position: THREE.Vector3; // 整体位置
rotation: THREE.Euler; // 旋转角度,基于这个确定主轴方向
}
条纹版本
接口沿用上面的接口,这里可以用多个四边形组成条纹,或者自定义 shader 来实现条纹
多个四边形
但是右图这种就不好做了,这里可以借助射线来实现,从主轴一条边开始按间隔算,垂直于主轴放出射线,检测和其他边框的交点,拿到四个点后绘制条纹,以此绘制其他条纹
这种方法也适用于平行路沿的绘制,只要把射线方向改为平行于短边(因为这里条纹方向就是平行于路沿),当然也支持其他不规则四边形斑马线(比如梯形),定一下条纹方向就行了
shader
上面的实现需要引入额外的几何体,以右图的实现为例,基于 rotation 确定条纹方向
- 还可以通过噪声模拟斑马线磨损情况
性能 tips
- LOD 控制。离得远的就没必要画的很清晰了,可以减少条纹密度
// 根据距离动态调整条纹密度
float lod = clamp(length(vWorldPosition - cameraPosition)/100.0, 0.0, 1.0);
float effectiveWidth = mix(uStripeWidth, uStripeWidth * 2.0, lod);