一、WebGL 基本認識
WebGL(Web Graphics Library)是一個光柵化引擎洋侨,它可以根據(jù)你的代碼繪制出點毡熏,線和三角形坦敌。它來源于 OpenGL,OpenGL 是使用硬件加速的 GPU 來進行圖形處理的計算機圖形處理庫,而 WebGL 則派生自 OpenGL 的其中一個版本狱窘,使其在 Web 中渲染3D圖形成為可能杜顺。
GLSL ES:OpenGL ES 著色器語言(shading language),是一種運行在 GPU 上的和C或C++類似的強類型語言训柴。WebGL 語言使用三種語言進行開發(fā):HTML哑舒、JavaScript 和 GLSL ES。
1. 兩個實現(xiàn)要點:
(1)Canvas:定義網(wǎng)頁上的繪圖區(qū)域幻馁。
(2)著色器:繪制圖形的基石洗鸵。
要使用 WebGL 進行繪圖,就必須使用著色器仗嗦,WebGL 需要兩種著色器來實現(xiàn)圖形的各種渲染效果:
- 頂點著色器:用來描述頂點特性(如位置膘滨、顏色等)等程序。
- 片元著色器:進行逐片元處理過程如光照的程序稀拐』鸬耍可以將片元理解為像素(圖像的單元)德撬。
在代碼中铲咨,著色器程序是以字符串的形式“嵌入”在 JavaScript 文件中的,在程序真正開始運行前它就已經(jīng)設置好了蜓洪。
WebGL 程序包括運行在瀏覽器中的 JavaScript 和運行在 WebGL 系統(tǒng)的著色器程序這兩個部分纤勒。
2. WebGL 坐標系
注意:WebGL 坐標系與 canvas 繪圖區(qū)的坐標系不同,需要將前者映射到后者隆檀。
具體轉換步驟:
(1)將坐標從瀏覽器客戶區(qū)轉換到 <canvas> 坐標系下摇天,通過 e.target.getBoundingClientRect()
可以獲取 <canvas> 在客戶區(qū)中的坐標;
(2)將 <canvas> 坐標系下的坐標轉換到 WebGL 坐標系統(tǒng)中恐仑。
var x = e.clientX;
var y = e.clientY;
var rect = e.target.getBoundingClientRect();
x = ((x - rect.left) - canvas.width / 2) / (canvas.width / 2);
y = (canvas.height / 2 - (y - rect.top)) / (canvas.height / 2);
3. 著色器變量類型
attribute
變量:屬性泉坐,傳輸與頂點相關的數(shù)據(jù);
uniform
變量:全局變量裳仆,傳輸與所有頂點都相同(或與頂點無關)的數(shù)據(jù)腕让;
varying
變量:可變量,從頂點著色器向片元著色器傳輸數(shù)據(jù)歧斟。
只有頂點著色器才能使用 attribute 變量记某,使用片元著色器時,就需要使用 uniform 變量和 varying 變量构捡。
// Vertex shader program
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'void main() {\n' +
' gl_Position = a_Position;\n' +
' gl_PointSize = 10.0;\n' +
'}\n';
// Fragment shader program
var FSHADER_SOURCE =
'uniform vec4 u_FragColor;\n' +
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' +
'}\n';
function main() {
//...
// Get the storage location of a_Position
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position');
return;
}
// Get the storage location of u_FragColor
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
if (!u_FragColor) {
console.log('Failed to get the storage location of u_FragColor');
return;
}
//...
// Pass the position of a point to a_Position variable
gl.vertexAttrib3f(a_Position, xy[0], xy[1], 0.0);
// Pass the color of a point to u_FragColor variable
gl.uniform4f(u_FragColor, rgba[0], rgba[1], rgba[2], rgba[3]);
//...
}
4. 緩沖區(qū)
二液南、 場景渲染基本內容
1. 3D 幾何圖形(3D geometry):點、線勾徽、面
2. 相機(camera)+ 視角(perspective):正交相機滑凉、透視相機髓废、全景相機耕捞、3D相機
(相機的類型)
3. 紋理(texture)
紋理是一個數(shù)據(jù)序列户辱,可以在著色程序運行中隨意讀取其中的數(shù)據(jù)卢肃。 大多數(shù)情況存放的是圖像數(shù)據(jù),但是紋理僅僅是數(shù)據(jù)序列若未, 你也可以隨意存放除了顏色數(shù)據(jù)以外的其它數(shù)據(jù)朱嘴。
4. 材質(material)
材質與圖形表示方法是相關的,用點表示使用PointsMaterial粗合,用線表示使用LineXXXMaterial萍嬉,用面表示使用MeshXXXMaterial,用精靈表示使用SpriteMaterial等等隙疚。
這樣劃分是因為不同的表示方式所要求的材質有很大不同壤追。比如用線來表示,由于線沒有光照模型供屉,所以行冰,LineXXXMaterial也沒有關照類的屬性。只有面表示的模型才有光照模型伶丐。光照模型有l(wèi)ambert模型和phong模型悼做,對這兩種光線模型,我們只需要知道哗魂,Lambert模型一般用來表示只有漫反射的物體肛走,如塑料,而phong模型用來表示有鏡面反射的物體啡彬,如鏡子。
- MeshBasicMaterial故硅、MeshNormalMaterial庶灿、MeshLambertMaterial、MeshPhongMaterial吃衅、MeshStandardMaterial往踢、MeshDepthMaterial
- LineBasicMaterial、LineDashedMaterial
- PontsMaterial
- SpritMaterial
5. 光照(light)
(1)基本光源類型:
平行光(directional light) :平行光的光線是相互平行的徘层,具有方向峻呕。平行光可以看作是無限遠處的光源發(fā)出的光,類似于自然中的太陽光趣效。因為太陽距離地球很遠瘦癌,所以陽光到達地球時可以認為是平行的。平行光可以用一個方向和一個顏色來定義跷敬;
點光源光(point light):點光源光是從一個點向周圍的所有方向發(fā)出的光讯私,類似于人造燈泡的光。我們需要指定點光源的位置和顏色。光線的方向將根據(jù)點光源的位置和被照射之處的位置計算出來斤寇,因為點光源的光線的方向在場景內的不同位置是不同的桶癣。
環(huán)境光(ambient light):又叫間接光,是指那些經(jīng)光源(點光源或平行光源)發(fā)出后娘锁,被墻壁多次反射牙寞,然后找到物體表面上的光,用于模擬真實世界中的非直射光莫秆。環(huán)境光從各個角度照射物體间雀,其強度都是一致的。它不用指定位置和方向馏锡,只需要指定顏色即可雷蹂。
(2)反射類型:
漫反射:漫反射針對平行光或點光源而言杯道,其反射光在各個方向是均勻的匪煌。如果物體表面像鏡子一樣光滑,那么光線就會以特定的角度反射出去党巾;但是現(xiàn)實中的大部分材質萎庭,比如紙張、巖石齿拂、塑料等驳规,其表面都是粗糙的,在這種情況下反射光就會以不固定的角度反射出去署海。漫反射就是針對后一種情況而建立的理想反射模型吗购。
環(huán)境反射:環(huán)境反射針對環(huán)境光而言的,其方向可以認為就是入射光的反方向砸狞。由于環(huán)境光照射物體的方式就是個方向均勻捻勉、強度相等的,所以反射光也是個方向均勻的刀森。
三踱启、WebVR Tools
Three.js:基于 WebGL,擁有底層API研底,能更深層次地了解 3D 渲染和 WebGL埠偿,☆ star 42808;
A-Frame:基于 Three.js榜晦,開始 WebVR 最簡單的庫冠蒋,社區(qū)很活躍完善,☆ star 8303乾胶;
ReactVR:基于 Three.js浊服,受眾為 React 開發(fā)人員统屈,API 類似于 React Native,☆ star 6147牙躺;
Babylon.js:類似于 Three.js愁憔,為游戲而生,☆ star 7024孽拷。