虛擬展廳技術(shù):WebGL完整工作流程以及 Three.js 原理

Jyadmin 提交于 周五, 02/19/2021 - 16:42

?

虛擬展廳技術(shù):WebGL的完整工作流程

1、準(zhǔn)備數(shù)據(jù)階段

在這個(gè)階段,我們需要提供頂點(diǎn)坐標(biāo)、索引(三角形繪制順序)、uv(決定貼圖坐標(biāo))、法線(決定光照效果),以及各種矩陣(比如投影矩陣)。

其中頂點(diǎn)數(shù)據(jù)存儲(chǔ)在緩存區(qū)(因?yàn)閿?shù)量巨大),以修飾符attribute傳遞給頂點(diǎn)著色器;

矩陣則以修飾符uniform傳遞給頂點(diǎn)著色器。

2、生成頂點(diǎn)著色器

根據(jù)我們需要,由Javascript定義一段頂點(diǎn)著色器(opengl es)程序的字符串,生成并且編譯成一段著色器程序傳遞給GPU。

3、圖元裝配

GPU根據(jù)頂點(diǎn)數(shù)量,挨個(gè)執(zhí)行頂點(diǎn)著色器程序,生成頂點(diǎn)最終的坐標(biāo),完成坐標(biāo)轉(zhuǎn)換。

4、生成片元著色器

模型是什么顏色,看起來(lái)是什么質(zhì)地,光照效果,陰影(流程較復(fù)雜,需要先渲染到紋理,可以先不關(guān)注),都在這個(gè)階段處理。

5、光柵化

能過(guò)片元著色器,我們確定好了每個(gè)片元的顏色,以及根據(jù)深度緩存區(qū)判斷哪些片元被擋住了,不需要渲染,最終將片元信息存儲(chǔ)到顏色緩存區(qū),最終完成整個(gè)渲染。

光柵化

虛擬展廳技術(shù):Three.js 原理

three.js參與的流程:

three.js參與的流程

黃色和綠色部分,都是three.js參與的部分,其中黃色是javascript部分,綠色是opengl es部分。

three.js可以實(shí)現(xiàn):

  • 輔助我們導(dǎo)出了模型數(shù)據(jù);

  • 自動(dòng)生成了各種矩陣;

  • 生成了頂點(diǎn)著色器;

  • 輔助我們生成材質(zhì),配置燈光;

  • 根據(jù)我們?cè)O(shè)置的材質(zhì)生成了片元著色器。

  • 而且將webGL基于光柵化的2D API,封裝成了我們?nèi)祟惸芸炊?3D API。

?Three.js頂點(diǎn)處理流程

從WebGL工作原理的章節(jié)中,我們已經(jīng)知道了頂點(diǎn)著色器會(huì)將三維世界坐標(biāo)轉(zhuǎn)換成屏幕坐標(biāo),但實(shí)際上,坐標(biāo)轉(zhuǎn)換不限于投影矩陣。

如下圖:

Three.js頂點(diǎn)處理流程

之前WebGL在圖元裝配之后的結(jié)果,由于我們認(rèn)為模型是固定在坐標(biāo)原點(diǎn),并且相機(jī)在x軸和y軸坐標(biāo)都是0,其實(shí)正常的結(jié)果是這樣的:

WebGL在圖元裝配之后的結(jié)果

模型矩陣

模型矩陣

現(xiàn)在,將模型順時(shí)針旋轉(zhuǎn)Math.PI/6,所有頂點(diǎn)位置肯定都變化了。

box.rotation.y = Math.PI/6;

?但是,如果我們直接將頂點(diǎn)位置用javascript計(jì)算出來(lái),那性能會(huì)很低(頂點(diǎn)通常成千上萬(wàn)),而且,這些數(shù)據(jù)也非常不利于維護(hù)。

視圖矩陣

視圖矩陣

將相機(jī)往上偏移30。

camera.position.y = 30;

?同理,我們用矩陣viewMatrix將移動(dòng)信息記錄下來(lái)。

投影矩陣

投影矩陣

用projectMatrix記錄。

應(yīng)用矩陣

編寫頂點(diǎn)著色器:

gl_Position = position * modelMatrix * viewMatrix * projectionMatrix;

?

這樣,我們就在GPU中,將最終頂點(diǎn)位置計(jì)算出來(lái)了。

實(shí)際上,上面所有步驟,three.js都幫我們完成了。

應(yīng)用矩陣

片元著色器處理流程

片元著色器負(fù)責(zé)處理材質(zhì)、燈光等信息,但具體是怎么處理呢?

如下圖:

片元著色器處理流程

three.js完整運(yùn)行流程

three.js完整運(yùn)行流程

當(dāng)選擇材質(zhì)后,three.js會(huì)根據(jù)所選的材質(zhì),選擇對(duì)應(yīng)的頂點(diǎn)著色器和片元著色器。

three.js中已經(jīng)內(nèi)置了我們常用著色器。

?

?