亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

WebGL 單通道wireframe渲染

KoreyLee / 2921人閱讀

摘要:那是因?yàn)?,線條的光柵化過(guò)程和多邊形的光柵化過(guò)程并不是完全一致的。這將會(huì)導(dǎo)致一些本該被隱藏的線段,未被遮擋。原理我們知道,一般對(duì)象都是由三角形組成的。其中涉及到和的相關(guān)介紹,筆者將會(huì)在后續(xù)的文章中介紹。

如果要把一個(gè)對(duì)象的線框繪制出來(lái),一般的方法是先繪制實(shí)體對(duì)象,然后通過(guò)gl.LINES的模式再繪制一遍模型,此時(shí)模型的線框就會(huì)被繪制出來(lái)。

gl.LINES的問(wèn)題

此方法需要繪制兩遍對(duì)象,因此會(huì)造成性能的損失。

使用此種方式繪制線框的時(shí)候,深度值偏移是必要的。那是因?yàn)?,線條的光柵化過(guò)程和多邊形的光柵化過(guò)程并不是完全一致的。這就導(dǎo)致繪制一個(gè)多邊形的邊和繪制多邊形本身,相同位置的片元,其深度值可能并不一樣。

線段和多邊形的光柵化不完全一致,為了避免z-fighting,也需要一個(gè)深度偏移。
但是,添加一個(gè)偏移并不能完美的解決問(wèn)題。 這將會(huì)導(dǎo)致一些本該被隱藏的線段,未被遮擋。

使用gl.LINES的另外一個(gè)問(wèn)題是,在WebGL中,存在一個(gè)bug,就是線寬只能設(shè)置為1。請(qǐng)參考以下文章:

https://www.jianshu.com/p/cee... 繪制Line的bug(一)

因此本文將會(huì)介紹一種方法,可以在一個(gè)pass內(nèi)繪制對(duì)象及其線框。

原理

我們知道,一般對(duì)象都是由三角形組成的。而要顯示的線框,正好是三角形的邊,如果在繪制的時(shí)候,給三角形的邊一個(gè)不同的顏色,便可以實(shí)現(xiàn)在對(duì)象上面繪制線框的效果。
那么現(xiàn)在的問(wèn)題是,如何確定三角形的邊呢?

重心坐標(biāo)系

要確定三角形的變,可以使用重心坐標(biāo)系。有關(guān)重心坐標(biāo)的的說(shuō)明,可以參考:
https://zh.wikipedia.org/wiki...
對(duì)于三角形而言,重心坐標(biāo)可以這樣定義:
三角形所在平面上的任意一點(diǎn)P(笛卡爾坐標(biāo)),可以通過(guò)三角形的三個(gè)頂點(diǎn)A、B、C(笛卡爾坐標(biāo))來(lái)表示:
P = Ax + By + C * Z,其中(x、y、z)便是重心坐標(biāo)。由此可以看出P點(diǎn)其實(shí)是A、B、C點(diǎn)加權(quán)之和。
如下圖所示,A點(diǎn)的重心坐標(biāo)是(1,0,0),B點(diǎn)的重心坐標(biāo)是(0,1,0),C點(diǎn)的重心坐標(biāo)是(0,0,1)

重心坐標(biāo)確定三角形的邊

由上面的講解 和圖片展示可以得知,重心坐標(biāo)(x,y,z)中任何一個(gè)值為0的點(diǎn),都在三角形的邊上。不過(guò)在實(shí)際的圖形渲染中,邊的寬度不可能是0,而應(yīng)該是一個(gè)大于0的值,所以一般可以指定一個(gè)要繪制的線寬width,如果任何一個(gè)點(diǎn)的重心坐標(biāo)(x,y,z)中的人一個(gè)分量的值小于這個(gè)線寬width,可以認(rèn)為在邊上。

代碼實(shí)現(xiàn)

基于上面說(shuō)的原理,首先需要定義頂點(diǎn)的重心坐標(biāo),對(duì)于一個(gè)三角形來(lái)說(shuō),可以把三個(gè)頂點(diǎn)的中心坐標(biāo)分別指定為(1,0,0)、(0,1,0)、(0,1,0)即可。而對(duì)于一個(gè)四邊形,有四個(gè)頂點(diǎn) 0,1,2,3,而繪制的時(shí)候使用索引 0,1,2, 2,1,3來(lái)繪制,此時(shí)可以把重心坐標(biāo)定義如下:

  var barycentric = [
        1,0,0,  0,1,0, 0,0, 1,  1,0,0,
   ];

然后,在著頂點(diǎn)色器中定義對(duì)應(yīng)的attribute變量,由于重心坐標(biāo)最終需要傳遞到片元著色器中,所以還需要對(duì)應(yīng)的varying變量:

      attribute vec3 aBarycentric;
     ...
     varying vec3 vBarycentric;
     void main(){
         ...
         vBarycentric = aBarycentric;
     }

然后,在片元著色器中判斷,如果vBarycentric的任意一個(gè)分量的值小于指定的寬度值,則顏色為指定的線框顏色:

if(any(lessThan(vBarycentric, vec3(0.02)))){
          gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
        }
        else{
            gl_FragColor = color;
        }

通過(guò)上面代碼,最終繪制的立方體效果如下:

去掉鋸齒

從上面的立方體繪制的效果圖可以看出,線框的鋸齒很嚴(yán)重,而且線的寬度不是一致的。這是因?yàn)椋暗呐袛嗍腔谌切伪砻娴?,通過(guò)光柵化之后,由于線條的角度等原因,最終在屏幕上面的寬度就變得不一致了。

使用fwidth方法

要線寬的判斷基于屏幕,需要使用到一個(gè)方法fwidth。該方法需要WebGL 引入一個(gè)擴(kuò)展之后才能使用。該擴(kuò)展是:OES_standard_derivatives。
首先使用WebGL的getExtension方法獲取該擴(kuò)展,代碼如下:

gl.getExtension("OES_standard_derivatives");

然后在shader中啟用這個(gè)擴(kuò)展,代碼如下:

#extension GL_OES_standard_derivatives : enable

然后通過(guò)fwidth函數(shù),把vBarycentric的值縮放到 vBarycentric在屏幕變化的范圍之內(nèi),代碼如下:

 vec3 d = fwidth(vBarycentric);
 vec3 a3 = smoothstep(vec3(0.0), d*2.0, vBarycentric);

fwidth表示一個(gè)變量在屏幕空間的x軸變化dFdx + y軸變化dFdx之和。 其中涉及到dFdx、dFdy和fwidth的相關(guān)介紹,筆者將會(huì)在后續(xù)的文章中介紹。
在獲取了基于屏幕像素空間的的重心坐標(biāo)a3之后,變可以通過(guò)通過(guò)該變量來(lái)進(jìn)行判斷,并繪制出指定寬度的線框:

gl_FragColor.rgb = mix(vec3(0.0,0.0,0.0), vec3(1.0), min(min(a3.x, a3.y), a3.z));

通過(guò)改良之后的繪制效果如下,可以看出明細(xì)效果改進(jìn)了很多:

四邊形線框

前面我們看到的都是三角形的線框,有的時(shí)候,我們希望獲取四邊形的線框,應(yīng)該怎么處理呢? 其實(shí)此時(shí),只需要調(diào)整下頂點(diǎn)的重心坐標(biāo)即可,在前文中,一個(gè)四邊形的四個(gè)頂點(diǎn)的重心坐標(biāo)如下:

  var barycentric = [
        1,0,0,  0,1,0, 0,0, 1,  1,0,0,
   ];

如果把四邊形的四個(gè)頂點(diǎn)的重心坐標(biāo)調(diào)整如下:

  var barycentric = [
       1,0,0,  1,1,0, 0,0, 1,  0,0,0,  //前
    ];

便可以達(dá)到效果,最終繪制的效果如下圖所示:

后記

英偉達(dá)也提出過(guò)繪制線框的解決方案,參考下面鏈接:
https://developer.download.nvidia.com/SDK/10/direct3d/Source/SolidWireframe/Doc/SolidWireframe.pdf
不過(guò)該方案是基于Geometry Shader技術(shù)來(lái)實(shí)現(xiàn)的,而該技術(shù)在WebGL并未實(shí)現(xiàn),所以該方案不能很好的移植到到WebGL。

如果獲取完整源代碼,請(qǐng)關(guān)注公眾號(hào)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/97119.html

相關(guān)文章

  • WebGL 著色器偏導(dǎo)數(shù)dFdx和dFdy介紹

    摘要:偏導(dǎo)數(shù)函數(shù)可以用于片元著色器中的任何變量。偏導(dǎo)數(shù)和用于計(jì)算紋理的一些列的子圖,每個(gè)子圖都比前一個(gè)的尺寸縮小了倍。在紋理取樣過(guò)程中使用偏導(dǎo)數(shù)來(lái)選擇最佳的級(jí)數(shù)。 本文適合對(duì)webgl、計(jì)算機(jī)圖形學(xué)、前端可視化感興趣的讀者。 偏導(dǎo)數(shù)函數(shù)(HLSL中的ddx和ddy,GLSL中的dFdx和dFdy)是片元著色器中的一個(gè)用于計(jì)算任何變量基于屏幕空間坐標(biāo)的變化率的指令(函數(shù))。在WebGL中,使用...

    Hanks10100 評(píng)論0 收藏0
  • three.js 入門詳解(一)

    摘要:一般說(shuō)來(lái),對(duì)于制圖建模軟通常使正交投影,這樣不會(huì)因?yàn)橥队岸淖兾矬w比例而對(duì)于其他大多數(shù)應(yīng)用,通常使用透視投影,因?yàn)檫@更接近人眼的觀察效果。 showImg(https://segmentfault.com/img/remote/1460000012581680?w=1920&h=1080); 1. 概述 1.1 什么是WebGL? WebGL是在瀏覽器中實(shí)現(xiàn)三維效果的一套規(guī)范 想要使用...

    Jacendfeng 評(píng)論0 收藏0
  • WebGL立體視覺(jué)呈現(xiàn)

    摘要:導(dǎo)言立體視覺(jué)技術(shù)前幾年研究極為廣泛,研究生期間也以此為課題,主要學(xué)習(xí)并研究特征提取和圖像匹配方向目前火遍全球的虛擬現(xiàn)實(shí)技術(shù),也屬于立體視覺(jué)領(lǐng)域的研究范疇。 導(dǎo)言 立體視覺(jué)技術(shù)前幾年研究極為廣泛,研究生期間也以此為課題,主要學(xué)習(xí)并研究特征提取和圖像匹配方向;目前火遍全球的虛擬現(xiàn)實(shí)技術(shù),也屬于立體視覺(jué)領(lǐng)域的研究范疇。 立體視覺(jué)技術(shù)可研究?jī)?nèi)容很多,實(shí)現(xiàn)一整套立體視覺(jué)呈現(xiàn)步驟如下: 攝像機(jī)標(biāo)...

    xeblog 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<