WebGL繪製有端頭的線

2022-01-11 01:52:45 字數 1469 閱讀 9400

關於webgl繪製線原理不明白的小夥伴,可以看看我之前的文章webgl繪製有寬度的線。這一篇我們主要來介紹端頭的繪製,先看效果圖。

端頭一般被稱為linecap,主要有以下三種形式:

butt最簡單等於沒有端頭,square一般是多出linewidth/2的長度,round是乙個以linewidth/2為半徑的圓。一般情況下繪製linecap的思路都是新增額外的三角形,如一些開元庫或者mapbox的方法,一般來說mapbox的方法已經可以了,但是我還是感覺頂點太多,甚至對square的情況都不願意在增加兩個頂點。

方法總是自己去探索的,在繪製寬度線中,我已經總結了自己的一套理論,將線距離對映成uv座標的思路來繪製一些線的效果,那麼在這裡仍然沿著這種思路去思考。

如果對投影矩陣不是很了解的同學,最好看看我的這篇文章webgl開發第一道坎——矩陣與座標變換,這裡我們需要用到投影矩陣的中的元素

resolution.x代表canvas顯示元素的寬度,這裡恐怕有些地方不太好理解。n其實是代表相機的近平面,我們先假設為1;那麼pixelwidthratio表示畫素與3d單位的乙個比值的一半。後面我們先暫時也假設finalposition.w的值也為一,那麼最終vpixelwidth的值表示每畫素代表多少3d單位。但是由於視錐體的投影變換並不是線性的,所以這樣得到的vpixelwidth並不適用視錐體中的所有地方。這時候我們回來看pixelwidthratio有乙個分母n代表近平面,finalposition.w代表投影後的點距離相機座標中的z值距離。w/n這裡是想用線性來補充一部分非線性變換帶來的影響,讓vpixelwidth表示每畫素代表多少3d單位這個結果盡量的準確。實際效果也確實可以達到預期。

現在我們可以將端頭多出的一半線寬的畫素距離轉化成線的距離,同時在轉化成紋理單位。

接下來我們可以在片元著色器中進行剔除工作。這裡我們需要做幾步工作:

紋理座標轉換成線的距離長度

線的距離長度轉換成畫素單位

對大於linewidth/2長度的畫素進行剔除

這裡我們需要用到varying變數對vpixelwidth進行差值。最終我們繪製出round的linecap效果。

WebGL繪製有端頭的線

關於webgl繪製線原理不明白的小夥伴,可以看看我之前的文章webgl繪製有寬度的線。這一篇我們主要來介紹端頭的繪製,先看效果圖。端頭一般被稱為linecap,主要有以下三種形式 butt最簡單等於沒有端頭,square一般是多出linewidth 2的長度,round是乙個以linewidth 2...

WebGL 繪製Line的bug 三

之前鋪墊了許多,今天可以來分享點純乾貨了。bk.line3d function points,colors bk.line3d.prototype.computedata function if i 0 var idx 3 i var i2 i 2 offset i2 0 5 offset i2 1...

WebGL 繪製Line的bug 三

bk.line3d function points,colors elseelse else if aposition apositionnext else vec2 dira normalize currscreen prevscreen vec2 dirb normalize nextscree...