WebGL
是一門能夠在瀏覽器中渲染 3D/2D 圖形的技術。它提供一套 JavaScript API,使用在 canvas
元素上,從而使得 Web 開發者能夠在瀏覽器中無需藉助插件便可繪製3D圖形。javascript
雖然開發使用的是 JavaScript 接口,但最終調用的是硬件設備底層 OpenGL
庫相關的接口,而且有硬件加速,因此 WebGL 渲染要比通常的 Canvas 2D 渲染性能高不少。html
這裏瞭解一下 OpenGL。根據 MDN 上的描述,OpenGL (Open Graphics Library) 是一套用來渲染2D和3D矢量圖形的跨語言的、跨平臺的應用程序接口(API) 。其實 OpenGL 是一套規範而不是接口,接口的實現要靠各硬件廠商,這裏的硬件廠商主要指 GPU 生產商,由於 OpenGL 庫指令是運行在GPU中的,各個 GPU 廠商若是要支持 OpenGL 的話,就須要按照規範去實現本身的 OpenGL 庫。各個廠家的 OpenGL 庫其實是他們整合本身的圖形知識以及 GPU 硬件指令而實現的,這些實現一般被稱爲「驅動」,負責將 OpenGL 定義的 API 命令翻譯爲 GPU 運行指令,因此使用時只須要安裝顯卡驅動便可。前端
WebGL 根植於 OpenGL,但它們中間還隔着一個 OpenGL ES
。OpenGL ES 是 OpenGL 的子集,專門針對手機/PDA/遊戲主機等嵌入式設備設計的。OpenGL ES 主要直接提供 C 語言的 api,其餘平臺能夠根據習慣加一層包裝,好比安卓提供了 Java 的包裝, IOS 提供了 Objective-C 的包裝。而 WebGL 就是基於 OpenGL ES 2.0 的 JavaScript API,也能夠說是 OpenGL ES 經過增長一個 JavaScript 綁定而實現了 WebGL。java
使用 WebGL 繪圖主要利用 WebGL API 和 canvas 元素,WebGL API 是 JavaScript 語言的,這點對於前端而言不在話下的。前面提到 OpenGL 是運行在 GPU 中的,但不是全部編程語言都能運行在 GPU 上,這就須要用到特殊的編程語言,即 着色器語言
,着色器語言用於計算機圖形編程,運行在GPU中,而平時所說的大多數語言編寫的程序都是運行在 CPU 中的。與 OpenGL API 相配合的是着色器語言 GLSL
,與 OpenGL ES API、WebGL API 相互配合的是着色器語言 GLSL ES
。因此咱們還須要學習 GLSL ES
這門語言。web
可能有人會疑問,說好的使用 JavaScript 開發,怎麼還要學習新編程語言,這個 GLSL ES
也能運行在瀏覽器中嗎?GLSL ES
不能在瀏覽器環境運行,只是咱們會藉助 WebGL API
將編寫好的 GLSL ES 程序傳入底層設備運行,最終藉助系統顯卡來在瀏覽器裏更流暢地展現圖形場景,這樣既達到了高性能,又不須要瀏覽器插件的支持。編程
不少人都聽過 Three.js
的大名,知道它是用來作 3D 圖形的,其實 Three.js
是基於原生 WebGl API
和 着色器
封裝獲得的 3D 引擎,是一個 JavaScript 庫。直接經過原生 WebGL 編寫會比較麻煩,還須要寫 GLSL ES
的程序,因此開發項目通常直接使用 Three.js
引擎。可是若是想深刻 Web3D 應用開發,學習底層 WebGL 和着色器 GLSL 知識仍是頗有必要的。canvas
筆者也是剛瞭解 webgl,這段實踐代碼也是參考網上資料得來,已經加了註釋。直接複製這段 html 代碼在瀏覽器中執行便可,能夠自行修改相關參數,查看顯示效果,具體知識點留待後續文章記錄。api
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebGL 畫一個點</title>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<script> // 獲取畫布 const canvas = document.getElementById('canvas'); // 獲取 webgl 上下文 const gl = canvas.getContext('webgl'); /* 下面兩個着色器源碼以字符串形式存着,供 webgl api 調用 */ //頂點着色器源碼 const vertexShaderSource = '' + 'void main(){' + //給內置變量gl_PointSize賦值像素大小 ' gl_PointSize=20.0;' + //頂點位置,位於座標原點 ' gl_Position =vec4(0.0,0.0,0.0,1.0);' + '}'; //片元着色器源碼 const fragShaderSource = '' + 'void main(){' + //定義片元顏色 ' gl_FragColor = vec4(1.0,0.0,0.0,1.0);' + '}'; //初始化着色器 const program = initShader(gl, vertexShaderSource, fragShaderSource); // 指定將要用來清空繪圖區域的顏色 gl.clearColor(0,1,0,0.5); // 使用以前指定的顏色,清空繪圖區 gl.clear(gl.COLOR_BUFFER_BIT); //開始繪製,顯示器顯示結果 gl.drawArrays(gl.POINTS, 0, 1); //聲明初始化着色器函數 function initShader(gl, vertexShaderSource, fragmentShaderSource) { //建立頂點着色器對象 const vertexShader = gl.createShader(gl.VERTEX_SHADER); //建立片元着色器對象 const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); //引入頂點、片元着色器源代碼 gl.shaderSource(vertexShader, vertexShaderSource); gl.shaderSource(fragmentShader, fragmentShaderSource); //編譯頂點、片元着色器 gl.compileShader(vertexShader); gl.compileShader(fragmentShader); //建立程序對象program const program = gl.createProgram(); //附着頂點着色器和片元着色器到program gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); //連接program gl.linkProgram(program); //使用program gl.useProgram(program); //返回程序program對象 return program; } </script>
</body>
</html>
複製代碼
對於 WebGL,我仍是挺感興趣的,但願後面本身能多寫幾篇記錄。瀏覽器
以上關於 WebGL 的記錄,都是筆者從網上衆多資料中總結而來。若有錯誤,歡迎指出。markdown