three.js是一個可以幫助您使用WebGL API的框架。
對於webgl來說,「mesh」是three.js,它是一系列低級調用,用於設置狀態和發出對GPU的調用。
讓我們以一個球體爲例。隨着three.js所,你會用幾行創建:
var sphereGeometry = new THREE.SphereGeometry(10);
var sphereMaterial = new THREE.MeshBasicMaterial({color:'red'});
var sphereMesh = new THREE.Mesh(sphereGeometry, sphereMaterial);
myScene.add(sphereMesh);
你有你的renderer.render()調用,噗,球體出現在屏幕上。
雖然很多東西發生在引擎蓋下。
第一行創建球體「幾何體」--CPU將會用一堆數學和邏輯來描述一個帶有點和三角形的球體。點是向量,三個浮點組合在一起,三角形是通過indecis(整數組)組合這些點的結構。
某處有一個計算基於三角函數(sin,cos)的向量的循環,另一個計算將得到的向量數組編成三角形(取每個N,N + M,N + 2M,創建一個三角形等等)。
現在這些數字存在於javascript的土地上,它只是一堆浮動物和插入物,以特定的方式聚集在一起來描述立方體,球體和外星人等形狀。
您需要一種方法在屏幕上繪製這個構造 - 一個像素的二維數組。
WebGL實際上對3D知之甚少。它知道如何管理GPU上的內存,如何並行計算事物(或爲您提供工具),它知道如何進行對3D圖形至關重要的數學運算,但同樣的數學算法可用於挖掘比特幣,甚至沒有畫任何東西。
爲了WebGL在屏幕上繪製東西,它首先需要將數據放入適當的緩衝區,它需要有着色器程序,它需要爲特定的調用進行設置(是否會混合 - 透明度在three.js土地,深度測試,模板測試等),那麼它需要知道它實際繪製的是什麼(所以你需要提供步幅,屬性的大小等等,讓它知道'網格'實際存在於內存中的位置),它如何繪製它(三角帶,粉絲,點...)以及如何繪製它 - 哪些着色器將應用於您提供的數據。
所以,你需要一種'教'WebGL做3D的方法。
我認爲最好的方式來熟悉這個概念是看this tutorial,如果有必要重新閱讀,因爲它解釋了發生的事情幾乎在每一個3D對象的角度來看,以往。
綜上所述教程:
- 的立體相機是基本上是兩個4×4矩陣 - 的立體矩陣,即把東西進入的角度來看,和視圖矩陣,即移動整個世界進入相機空間。你製作的每個相機都由這兩個矩陣組成。
- 每個對象都存在於它的對象空間。 TRS矩陣(用three.js項表示的世界矩陣)用於將這個物體轉換爲世界空間。
所以這個東西 - 像「投影矩陣」這樣的概念是教webgl如何繪製視角。
Three.js對此進行了進一步的提煉,並給出了諸如「視野」和「寬高比」而不是左右,頂部的東西。
Three.js還提取變換矩陣(攝像機上的視圖矩陣和每個對象上的世界矩陣),因爲它允許您設置「位置」和「旋轉」,並根據此計算矩陣。由於每個網格必須由頂點着色器和像素着色器處理才能出現在屏幕上,因此每個網格都需要具有所有這些信息。
當爲特定網格發出繪圖調用時,該網格將具有與使用相同相機呈現的任何其他對象相同的透視矩陣和視圖矩陣。他們每個人都有他們自己的世界矩陣 - 將他們圍繞着你的場景移動的數字。
這是單獨的轉換,發生在頂點着色器中。然後柵格化這些結果,然後轉到像素着色器進行處理。
讓我們考慮兩種材料 - 黑色塑料和紅色塑料。它們將具有相同的着色器,也許可以使用THREE.ShaderMaterial編寫的一個着色器,也可以是三個庫中的一個。這是相同的着色器,但它有一個統一的值 - 顏色。這允許你有許多塑料材質的實例,綠色,藍色,粉紅色,但這意味着每一個都需要一個單獨的繪圖調用。
Webgl將不得不發出特定的呼叫以將該制服從紅色變爲黑色,然後準備使用該「材質」來繪製材質。
所以,現在想象一個粒子系統,顯示一個具有獨特顏色的千方塊。如果您將它們作爲單獨的網格對象並通過制服更改顏色,則必須發出一千次繪製調用來繪製它們。
另一方面,如果將頂點顏色分配給每個立方體,則不再依賴於統一體,而是依賴於屬性。現在,如果將所有立方體合併在一起,則可以發出單個繪圖調用,使用相同的着色器處理所有立方體。
您可以通過瀏覽three.js中的webglrenderer以及爲了將您的3d調用轉換爲webgl所需的所有內容來了解爲什麼這會更高效。比一千次更好地完成。
回到這三行,sphereMaterial可以帶一個顏色參數,如果你看看源代碼,這將轉化爲着色器中的統一vec3。但是,您也可以通過渲染頂點顏色並指定想要的顏色來實現同樣的效果。
sphereMesh會將計算後的幾何圖形包裹到三個webglrenderer可以理解的對象中,然後相應地設置webgl。
謝謝,非常好,清楚的解釋! – beirre