圖解WebGL和Three.js工作原理和流程
本篇文章給大家分享的內容是圖解WebGL和Three.js運作原理和流程,有著一定的參考價值,有需要的朋友可以參考一下
一、我們講什麼?
我們講兩個東西:
1、WebGL背後的工作原理是什麼?
2、以Three.js為例,講述框架在背後扮演什麼樣的角色?
二、我們為什麼要了解原理?
我們假定你對WebGL已經有一定了解,或者用Three.js做了一些東西,這個時候,你可能碰到了這樣一些問題:
1、很多東西還是做不出來,甚至沒有任何想法;
2、碰到bug無法解決,甚至沒有方向;
3、效能出現問題,完全不知道如何優化。
這個時候,我們需要了解更多。
三、先了解一個基礎概念
1、什麼是矩陣?
簡單說來,矩陣用於座標變換,如下圖:
2、那它具體是怎麼變換的呢,如下圖:
3、舉個實例,將座標平移2,如下圖:
#
如果這時候,你還是沒有理解,沒有關係,你只需要知道,矩陣用於座標變換。
四、WebGL的工作原理
4.1、WebGL API
在了解新技術之前,我們都會先看看它的開發文件或者API。
查看Canvas的繪圖API,我們會發現它能畫直線、長方形、圓、弧線、貝塞爾曲線。
於是,我們看了看WebGL繪圖API,發現:
它只能會點、線、三角形?一定是我看錯了。
沒有,你沒看錯。
就算是這樣一個複雜的模型,也是一個個三角形畫出來的。
4.2、WebGL繪製流程
簡單說來,WebGL繪製過程包含以下三個步驟:
1、取得頂點座標
2、圖元組裝(即畫出一個三角形)
3、光柵化(產生片元,即一個個像素點)
接下來,我們逐步解說每個步驟。
4.2.1、取得頂點座標
頂點座標從何而來呢?一個立方體還好說,如果是機器人呢?
沒錯,我們不會一個一個寫這些座標。
往往它來自三維軟體匯出,或是框架生成,如下圖:
寫入快取區是啥?
沒錯,為了簡化流程,之前我沒有介紹。
由於頂點資料往往成千上萬,在取得到頂點座標後,我們通常會將它儲存在顯存,也就是快取區內,方便GPU更快讀取。
4.2.2、圖元組裝
我們已經知道,圖元組裝就是由頂點產生一個個圖元(即三角形)。那這個過程是自動完成的嗎?答案是並非完全如此。
為了讓我們有更高的可控性,也就是自由控制頂點位置,WebGL把這個權力交給了我們,這就是可程式渲染管線(不用理解)。
WebGL要我們先處理頂點,那要怎麼處理呢?我們先看下圖:
我們引入了一個新的名詞,叫做“頂點著色器”,它由opengl es編寫,由javascript以字串的形式定義並傳遞給GPU生成。
例如如下就是一段頂點著色器程式碼:
##1234 | #
1 2 3 4 5 | attribute vec4 position; uniform mat4 matrix; void main() { gl_Position = position * matrix; } 登入後複製 |
这就是应用了矩阵matrix,将三维世界坐标转换成屏幕坐标,这个矩阵叫投影矩阵,由javascript传入,至于这个matrix怎么生成,我们暂且不讨论。
4.2.3、光栅化
和图元装配类似,光栅化也是可控的。
在图元生成完毕之后,我们需要给模型“上色”,而完成这部分工作的,则是运行在GPU的“片元着色器”来完成。
它同样是一段opengl es程序,模型看起来是什么质地(颜色、漫反射贴图等)、灯光等由片元着色器来计算。
如下是一段简单的片元着色器代码:
1 2 3 4 | precision mediump float; void main(void) { gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); } 登入後複製 |
gl_FragColor即輸出的顏色值。
4.2.3.1、片元著色器處理流程
片元著色器具體是如何控制顏色產生的呢?
如上圖,頂點著色器是有多少頂點,運行了多少次,而片元著色器則是,產生多少片元(像素),運行多少次。
4.3、WebGL的完整工作流程
至此,實質上,WebGL經歷瞭如下處理流程:
1、準備資料階段
在這個階段,我們需要提供頂點座標、索引(三角形繪製順序)、uv(決定貼圖座標)、法線(決定光照效果),以及各種矩陣(例如投影矩陣)。
其中頂點資料儲存在快取區(因為數量龐大),以修飾符attribute傳遞給頂點著色器;
矩陣則以修飾符uniform傳遞給頂點著色器。
2、產生頂點著色器
根據我們需要,由Javascript定義一段頂點著色器(opengl es)程式的字串,產生並且編譯成一段著色器程式傳遞給GPU。
3、圖元組裝
GPU根據頂點數量,挨個執行頂點著色器程序,產生頂點最終的座標,完成座標轉換。
4、生成片元著色器
模型是什麼顏色,看起來是什麼質地,光照效果,陰影(流程較複雜,需要先渲染到紋理,可以先不關注) ,都在這個階段處理。
5、光柵化
能過片元著色器,我們確定好了每個片元的顏色,以及根據深度緩存區判斷哪些片元被擋住了,不需要渲染,最終將片元資訊儲存到顏色快取區,最終完成整個渲染。
五、Three.js究竟做了什麼?
我們知道,three.js幫我們完成了很多事情,但是它具體做了什麼呢,他在整個流程中,扮演了什麼角色呢?
我們先簡單看一下,three.js參與的流程:
黃色和綠色部分,都是three.js參與的部分,其中黃色是javascript部分,綠色是opengl es部分。
我們發現,能做的,three.js基本上都幫我們做了。
辅助我们导出了模型数据;
自动生成了各种矩阵;
生成了顶点着色器;
辅助我们生成材质,配置灯光;
根据我们设置的材质生成了片元着色器。
而且将webGL基于光栅化的2D API,封装成了我们人类能看懂的 3D API。
5.1、Three.js顶点处理流程
从WebGL工作原理的章节中,我们已经知道了顶点着色器会将三维世界坐标转换成屏幕坐标,但实际上,坐标转换不限于投影矩阵。
如下图:
之前WebGL在图元装配之后的结果,由于我们认为模型是固定在坐标原点,并且相机在x轴和y轴坐标都是0,其实正常的结果是这样的:
5.1.1、模型矩阵
现在,我们将模型顺时针旋转Math.PI/6,所有顶点位置肯定都变化了。
1 | box.rotation.y = Math.PI/6; 登入後複製 |
但是,如果我们直接将顶点位置用javascript计算出来,那性能会很低(顶点通常成千上万),而且,这些数据也非常不利于维护。
所以,我们用矩阵modelMatrix将这个旋转信息记录下来。
5.1.2、视图矩阵
然后,我们将相机往上偏移30。
1 | camera.position.y = 30; 登入後複製 |
同理,我们用矩阵viewMatrix将移动信息记录下来。
5.1.3、投影矩阵
这是我们之前介绍过的了,我们用projectMatrix记录。
5.1.4、应用矩阵
然后,我们编写顶点着色器:
1 | gl_Position = position * modelMatrix * viewMatrix * projectionMatrix; 登入後複製 |
這樣,我們就在GPU中,將最終頂點位置計算出來了。
實際上,上面所有步驟,three.js都幫我們完成了。
5.2、片元著色器處理流程
我們已經知道片元著色器負責處理材質、燈光等訊息,但具體是怎麼處理呢?
如下圖:
5.3、three.js完整運作流程:
three.js中已經內建了我們常用著色器。
以上是圖解WebGL和Three.js工作原理和流程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數
