WebGL绘制有端头的线

  关于WebGL绘制线原理不明白的小伙伴,能够看看我以前的文章WebGL绘制有宽度的线。这一篇咱们主要来介绍端头的绘制,先看效果图。html

  端头通常被称为lineCap,主要有如下三种形式:web

  butt最简单等于没有端头,square通常是多出lineWidth/2的长度,round是一个以lineWidth/2为半径的圆。通常状况下绘制lineCap的思路都是添加额外的三角形,如一些开元库或者mapbox的方法,通常来讲mapbox的方法已经能够了,可是我仍是感受顶点太多,甚至对square的状况都不肯意在增长两个顶点。canvas

  方法老是本身去探索的,在绘制宽度线中,我已经总结了本身的一套理论,将线距离映射成uv坐标的思路来绘制一些线的效果,那么在这里仍然沿着这种思路去思考。post

  对于square来讲只要在绘制顶点的时候,在线的开头和结尾分别作必定的偏移便可。对于round咱们能够在suqare的基础上,在片元着色器中作一些判断,距离中心点距离大于lineWidth/2的像素所有抛弃掉。webgl

  

  因此对于线起点和终点处顶点的位置在上一篇文章的基础上,作了沿着线方向的偏移spa

 

  这样的话咱们就能绘制出square类型的lineCap。可是对于round仅仅这样作还不行,还须要在片元着色器中根据中心点作一次剔除。那么问题来了,通过偏移后如何知道圆心点的位置,在来根据像素距离来进行剔除。这时候就轮到上篇文章利用纹理坐标来表示线长度的思路了,上一篇中咱们把路线长度映射成从0-1的uv坐标,那么对于端头来讲,咱们能够把超出的那一半线宽的像素映射成纹理坐标,能够想象这部分长度对于起点来讲等于负的线长度,对应的纹理坐标就是负的纹理坐标;对于终点来讲多出的这部分像素等于增长了的线长度,那么对应纹理坐标就是超过1的部分。那么接下来的问题就是如何把线上的像素长度对应于线的长度等于把像素与3d世界中的单位进行映射。3d

  若是对投影矩阵不是很了解的同窗,最好看看个人这篇文章webgl开发第一道坎——矩阵与坐标变换,这里咱们须要用到投影矩阵的中的元素code

  resolution.x表明canvas显示元素的宽度,这里恐怕有些地方不太好理解。n实际上是表明相机的近平面,咱们先假设为1;那么pixelWidthRatio表示像素与3d单位的一个比值的一半。后面咱们先暂时也假设finalPosition.w的值也为一,那么最终vPixelWidth的值表示每像素表明多少3d单位。可是因为视锥体的投影变换并非线性的,因此这样获得的vPixelWidth并不适用视锥体中的全部地方。这时候咱们回来看pixelWidthRatio有一个分母n表明近平面,finalPosition.w表明投影后的点距离相机坐标中的z值距离。w/n这里是想用线性来补充一部分非线性变换带来的影响,让vPixelWidth表示每像素表明多少3d单位这个结果尽可能的准确。实际效果也确实能够达到预期。htm

 

  如今咱们能够将端头多出的一半线宽的像素距离转化成线的距离,同时在转化成纹理单位。blog

 

  接下来咱们能够在片元着色器中进行剔除工做。这里咱们须要作几步工做:

  1. 纹理坐标转换成线的距离长度
  2. 线的距离长度转换成像素单位
  3. 对大于lineWidth/2长度的像素进行剔除
 

  这里咱们须要用到varying变量对vPixelWidth进行差值。最终咱们绘制出round的lineCap效果。

相关文章
相关标签/搜索