由于OpenGL Core Profile与大多数平台上WebGL渲染器的限制,无法直接绘制带宽度的线。
这里以线AB举例,实现思路主要是通过AB两点延伸出C~J八个点,再通过绘制三角形面的方式绘制出宽线。
说一下其中几个点的个人理解:
1.偏移方向确定后,计算偏移值。
// adjust for linewidth
offset *= linewidth;
// adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ...
offset /= resolution.y;
//此时offset是ndc空间下的偏移量,而linewidth的单位是像素,需要进行准换
//换一种更容易理解的写法
float lineWidthNDC = linewidth / resolution.y;
offset *= lineWidthNDC;
2.实现CDGH和EFIJ区域圆角绘制,保证多段线绘制时,拐点处顺滑。
if ( abs( vUv.y ) > 1.0 ) {
float a = vUv.x;
float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0;
float len2 = a * a + b * b;
if ( len2 > 1.0 ) discard;
}
3.虚线效果,直接上图。其中 vLineDistance=像素点距起始点的距离;distace=mod( vLineDistance + dashOffset, dashSize + gapSize )
// 丢弃CDGH和EFIJ区域
if ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard;
// 丢弃间隙区域
if ( mod( vLineDistance + dashOffset, dashSize + gapSize ) > dashSize ) discard;
案例及源码见three官网,点击查看.