如何使用WebGL繪制平面網(wǎng)格線(xiàn)?
時(shí)間:2024-01-16 16:36:01 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)
時(shí)間:2024-01-16 16:36:01 來(lái)源:網(wǎng)站運(yùn)營(yíng)
如何使用WebGL繪制平面網(wǎng)格線(xiàn)?:WebGL本身支持LINES,POINTS和TRIANGLES三類(lèi)光柵化圖元(當(dāng)然還有相應(yīng)的STRIP等形式),只需要在繪制的時(shí)候準(zhǔn)備直線(xiàn)的頂點(diǎn)數(shù)據(jù),在調(diào)用drawElements的時(shí)候傳入gl.LINES讓流水線(xiàn)按照線(xiàn)段的模式去裝配圖元即可(參見(jiàn)這個(gè)API)。其他部分(VS,PS)和繪制三角形一樣。
這個(gè)方法的缺點(diǎn)是有些瀏覽器的WebGL版本不支持線(xiàn)寬的設(shè)定(對(duì)于POINTS類(lèi)型的圖元一般是可以設(shè)置點(diǎn)的大小的),
只支持線(xiàn)寬為1的,沒(méi)有反走樣的線(xiàn)段。
如果想要支持反走樣,并且能夠讓用戶(hù)自定義線(xiàn)段的樣式(比如虛線(xiàn)效果)、寬窄,另外一個(gè)比較麻煩的實(shí)現(xiàn)方法是,用兩個(gè)三角形拼成的四邊形來(lái)表示一條線(xiàn)段:
這個(gè)方法需要注意的是拐點(diǎn)連接處如何拼接,這里有兩篇文章
[1][2]可以去參考。當(dāng)然也可以再額外添加三角形用于生成線(xiàn)段兩端的拐點(diǎn)的圓弧。同時(shí)也可以在Pixel Shader里加入虛線(xiàn)等效果?;谶@個(gè)思路,實(shí)際上你不但可以繪制反走樣的直線(xiàn),還能夠繪制貝塞爾曲線(xiàn)等復(fù)雜的效果,參見(jiàn)GPU Gems里的這篇文章
[3]。理論上,你甚至可以基于這個(gè)思路實(shí)現(xiàn)一個(gè)完整的基于WebGL的SVG渲染器。
如果畫(huà)線(xiàn)的目的不是為了繪制網(wǎng)格,而是用于繪制線(xiàn)框模型的話(huà),一個(gè)比較優(yōu)雅的實(shí)現(xiàn)思路是基于重心坐標(biāo)插值:
具體原理也不再贅述,可以去看這兩篇文章
[4][5]。這個(gè)方法的優(yōu)點(diǎn)是,可以繪制反走樣的線(xiàn)框模型,同時(shí)支持線(xiàn)框內(nèi)部著色,支持具有透視效果的線(xiàn)段(也可以沒(méi)有透視效果)。缺點(diǎn)是這個(gè)方法需要頂點(diǎn)提供額外的用于重心坐標(biāo)插值的幾何數(shù)據(jù),并且如果頂點(diǎn)被多個(gè)三角形共享,必須分裂成多個(gè)頂點(diǎn),否則會(huì)導(dǎo)致重心坐標(biāo)插值出錯(cuò)(如果有Geometry Shader的API則可以通過(guò)Geometry Shader來(lái)分裂頂點(diǎn)生成幾何數(shù)據(jù),WebGL里只能通過(guò)CPU提前處理這部分?jǐn)?shù)據(jù))。另外的一個(gè)缺點(diǎn)是如果某個(gè)邊被兩個(gè)三角形共享,則會(huì)生成雙倍寬度的線(xiàn)段。
參考
- ^https://blog.mapbox.com/drawing-antialiased-lines-with-opengl-8766f34192dc
- ^https://www.cnblogs.com/dojo-lzz/p/9219290.html
- ^https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch25.html
- ^http://codeflow.org/entries/2012/aug/02/easy-wireframe-display-with-barycentric-coordinates/
- ^https://zhuanlan.zhihu.com/p/48499247