原書中第2章很是長,若是整理成一個文檔的話,得看好多天。爲了瀏覽方便,我將其拆分紅若干小節,方便你們學習。javascript
webgl採用HTML5中引入的canvas元素來定義頁面的繪圖區域。若是沒有WegGL,js只能在canvas上繪製二維圖形。html
在這一章中,咱們將經過建立若干個示例程序,一步步的介紹一些核心的webgl函數。java
咱們要開始編寫最短的webgl程序,這個程序的主要功能是使用背景色清空canvas標籤的繪圖區。(這裏的清空,是指用背景色填充的意思)web
html代碼以下;編程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webgl學習</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script src="./index.js"></script>
</body>
</html>
複製代碼
js代碼以下:canvas
// 獲取canvas
var canvas = document.getElementById('canvas')
// 獲取webgl繪圖上下文
var gl = canvas.getContext('webgl')
if (!gl) {
console.log('Failed to get the rendering context')
}
// 指定清空canvas的顏色
gl.clearColor(0.0, 0.0, 0.0, 1.0)
// 清空canvas
gl.clear(gl.COLOR_BUFFER_BIT)
複製代碼
示例程序的執行步驟以下:數組
點擊查看效果瀏覽器
咱們經過getElementById獲取canvas元素bash
var canvas = document.getElementById('canvas')
複製代碼
這裏傳入的參數是‘webgl’而不是‘3d’。咱們之前使用canvas畫2d圖形的時候傳入的是‘2d’。因此這裏要注意下,不要傳錯了。編程語言
var gl = canvas.getContext('webgl')
複製代碼
gl.clearColor(0.0, 0.0, 0.0, 1.0)
複製代碼
gl.clearColor採用RGBA的方式設置背景色:
gl.clearColor(red,green,blue,alpha)
複製代碼
參數 | 含義 |
---|---|
red | 指定紅色值(從0.0到1.0) |
green | 指定綠色值(從0.0到1.0) |
blue | 指定藍色值(從0.0到1.0) |
alpha | 指定透明度(從0.0到1.0) |
返回值 | 無 |
錯誤 | 無 |
若是任何值小於0或者大於1,那麼就會被截斷爲0.0或者1.0
示例程序執行gl.clearColor(0.0, 0.0, 0.0, 1.0)
,背景色就被指定爲了黑色。
咱們通常指定顏色時,顏色的值是0到255之間的,可是因爲webgl是繼承自OpenGL,因此它遵循傳統OpenGL顏色份量的取值範圍。
一旦指定的背景色,背景色就會駐存在WegGL系統中,在下一次調用gl.clearColor以前都不會改變。若是你未來還想用同一個顏色清空繪圖區,就沒必需要再指定一次背景色。
gl.clear(gl.COLOR_BUFFER_BIT);
複製代碼
函數參數是gl.COLOR_BUFFER_BIT
,這是由於WebGL中,gl.clear()方法實際上繼承自OpenGL,它基於多基本緩衝區模型。這比二維繪圖上下文複雜的多。清空繪圖區域,實際上在清空顏色緩衝區,傳遞參數gl.COLOR_BUFFER_BIT就是告訴WebGL清空顏色緩衝區。除了顏色緩衝區,WebGL還有其餘種類的緩衝區,好比深度緩衝區和模板緩衝區。
gl.clear(buffer)
的用法
buffer是指定待清空的顏色緩衝區,位操做符OR(|)可用於指定多個緩衝區
參數 | 含義 |
---|---|
gl.COLOR_BUFFER_BIT | 顏色緩衝區 |
gl.DEPTH_BUFFER_BIT | 深度緩衝區 |
gl.STENCIL_BUFFER_BIT | 指定模板緩衝區 |
返回值 | 無 |
錯誤 | INVALID_VALUE 緩衝區不是以上三種類型 |
以前的章節,咱們學習如何創建一個wegl程序,以及如何使用一些簡單的webgl函數。這一節咱們將進一步在一個示例程序中繪製一個最簡單的圖形,一個點。
注意這裏的html比上一次的html多了一些script。這些script是一些工具函數,避免重複的寫大量的代碼。代碼很簡單,能夠直接打開查看。這裏就不解釋了。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webgl學習</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<!-- 引入幾個webgl幫助函數,這裏的代碼很簡單,你能夠直接點擊查看 -->
<script src="https://mycode04-1252305175.cos.ap-guangzhou.myqcloud.com/webgl-lib/lib/webgl-utils.js"></script>
<script src="https://mycode04-1252305175.cos.ap-guangzhou.myqcloud.com/webgl-lib/lib/webgl-debug.js"></script>
<script src="https://mycode04-1252305175.cos.ap-guangzhou.myqcloud.com/webgl-lib/lib/cuon-utils.js"></script>
<script src="./index.js"></script>
</body>
</html>
複製代碼
javascript代碼:
// 頂點着色器 注意這裏的\n不能省略。不然不符合語法
var VSHADER_SOURCE = ` void main(){\n gl_Position = vec4(0.0,0.0,0.0,1.0);\n gl_PointSize = 10.0;\n }\n `
// 片斷(片元)着色器
var FSHADER_SOURCE = ` void main(){\n gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n }\n `
function main() {
// 獲取canvas
var canvas = document.getElementById('canvas')
// 獲取webgl繪圖上下文
var gl = canvas.getContext('webgl')
if (!gl) {
console.log('Failed to get the rendering context')
retun
}
// 初始化着色器函數
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log("設置着色器失敗")
return
}
// 指定清空canvas的顏色
gl.clearColor(0.0, 0.0, 0.0, 1.0)
// 清空canvas
gl.clear(gl.COLOR_BUFFER_BIT)
// 畫一個點
gl.drawArrays(gl.POINTS, 0, 1)
}
window.onload = function () {
main()
}
複製代碼
要使用webgl進行繪圖必須使用着色器,在代碼中,着色器是以字符串的形式「嵌入」到js中的。
webgl的着色器分兩種
在三維場景中,僅僅用線條和顏色把圖形畫出來是遠遠不夠的,必需要考慮光照上去或者觀察者視角發生變化時,對場景有什麼影響。着色器能夠高度靈活的完成這些工做。提供各類渲染效果。
上述程序執行流程:
initShaders()
,該函數定義在cuon.util.js中,是專爲本書編寫的一個工具函數。其用法說明以下:
initShaders(gl,vshader,fshader) | ||
參數 | 取值 | 含義 |
gl | vshader | 指定頂點着色器程序代碼 |
fshader | 指定片元着色器程序代碼 | |
返回值 | true | 初始化着色器成功 |
fase | 初始化着色器失敗 |
var VSHADER_SOURCE = ` void main(){\n gl_Position = vec4(0.0,0.0,0.0,1.0);\n gl_PointSize = 10.0;\n }\n `
複製代碼
頂點着色器必須和c語言同樣,必須包含一個main函數。main前面的void表示這個函數不會有返回值。
首先將頂點位置賦值給gl_Position變量。
在將頂點尺寸賦值給gl_PointSize。
這兩個變量內置在頂點着色器中,有特殊的含義。以下:
類型和變量名 | 含義 |
---|---|
vec4 gl_Position | 表示頂點的位置 |
float gl_PointSize | 表示頂點的尺寸 |
vec4 表示由4個浮點數組成的矢量。
注意:GLSL ES是一種強類型編程語言,比10是整型,10.0就是浮點數,傳錯類型就會報錯。
gl_Position其類型爲vec4,可是咱們只有3個浮點數(0.0,0.0,0.0),既x、y、z座標值。須要用某種方式把它轉爲vec4類型的變量。好在着色器爲咱們提供了內置函數vec4(),幫助你建立vec4類型的變量。(原書中這一段有錯誤,已糾正)
在賦值gl_Position的矢量中,咱們添加了1.0做爲第4個份量。由4個份量組成的矢量稱爲齊次座標。,由於它可以提升處理三維數據的效率。因此被大量使用。雖然齊次座標是四維的,可是若是最後一個份量爲1.0,那麼齊次座標就能夠表示「前三個份量爲座標值」的那個點。
片元着色器是用來設置顏色的,這裏設置爲紅色。
var FSHADER_SOURCE = ` void main(){\n gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n }\n `
複製代碼
gl_FragColor的用法以下:
類型和變量名 | 含義 |
---|---|
vec4 gl_FragColor | 指定片元顏色(RGBA格式) |
咱們使用drawArrays()進行繪製。
gl.drawArrays(gl.POINTS, 0, 1)
複製代碼
gl.drawArrays(mode,first,count)
參數 | 含義 |
---|---|
mode | 指定繪製的方式,能夠接受如下常量符號: gl.POINTS ,gl.LINES ,gl.LINE_STRIP ,gl.LINE_LOOP ,gl.TRIANGLES ,gl.TRIANGLE_STRIP ,gl.TRIANGLE_FAN |
first | 指定從哪一個點開始繪製 |
count | 指定繪製多少個點 |
錯誤 INVALID_ENUM | 傳入的mode參數不是前述參數之一 |
錯誤 INVALID_VALUE | 參數first或者count爲負數 |
總結:以上咱們簡單介紹了兩個webgl程序,並初步認識了着色器。後續的章節咱們將學習webgl的座標系統和更多着色器的相關知識。欲知後事如何,請動動你的手指,關注下我,我會繼續帶來webgl的分享,哈哈