關於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
接下來咱們能夠在片元着色器中進行剔除工做。這裏咱們須要作幾步工做:
這裏咱們須要用到varying變量對vPixelWidth進行差值。最終咱們繪製出round的lineCap效果。