WebGL繪製一個點
- 超文本語言HTML
- 腳本語言Javascript
- Canvas畫布
- 着色器語言GLSL ES
- WebGL API
繪製點像素點的html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用WebGL繪製一個點</title>
</head>
<body>
<!--canvas標籤創建一個寬高均爲500像素,背景爲藍色的矩形畫布-->
<canvas id="webgl" width="500" height="500" style="background-color: blue"></canvas>
<script>
//通過getElementById()方法獲取canvas畫布
var canvas=document.getElementById('webgl');
//通過方法getContext()獲取WebGL上下文
var gl=canvas.getContext('webgl');
//頂點着色器源碼
var vertexShaderSource = '' +
'void main(){' +
//給內置變量gl_PointSize賦值像素大小
' gl_PointSize=50.0;' +
//頂點位置,位於座標原點
' gl_Position =vec4(0.0,0.0,0.0,1.0);' +
'}';
//片元着色器源碼
var fragShaderSource = '' +
'void main(){' +
//定義片元顏色
' gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
'}';
//初始化着色器
var program = initShader(gl,vertexShaderSource,fragShaderSource);
//開始繪製,顯示器顯示結果
gl.drawArrays(gl.POINTS,0,1);
//聲明初始化着色器函數
function initShader(gl,vertexShaderSource,fragmentShaderSource){
//創建頂點着色器對象
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
//創建片元着色器對象
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
//引入頂點、片元着色器源代碼
gl.shaderSource(vertexShader,vertexShaderSource);
gl.shaderSource(fragmentShader,fragmentShaderSource);
//編譯頂點、片元着色器
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
//創建程序對象program
var 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>
演示效果
創建Canvas畫布
Canvas畫布,顯示WebGL的渲染結果,canvas元素和div等元素一樣是HTML的一個元素,只是Canvas畫布具有2D和3D繪圖功能
<!--canvas標籤創建一個寬高均爲500像素,背景爲藍色的矩形畫布-->
<canvas id="webgl" width="500" height="500" style="background-color: blue"></canvas>
通過JavaScript獲取上面創建的Canvas元素返回一個Canvas對象。
//通過getElementById()方法獲取canvas畫布對象
var canvas= document.getElementById('webgl')
canvas對象也可以不通過標籤創建,然後id方式獲取,也可以通過DOM直接創建
//通過getElementById()方法獲取canvas畫布對象
var canvas = document.createElement('canvas');
Canvas對象方法.getContext()
HTML的Canvas元素提供了2D和3D繪圖兩種功能,平時程序員之間交流所說的Canvas一詞就是指Canvas的2D繪圖功能,通過Canvas元素實現的3D繪圖功能,也就是所謂的WebGL,或者說WebGL依賴於Canvas
元素實現。
執行canvas.getContext(‘2d’)返回對象具有一系列繪製二維圖形的方法,比如繪製直線、圓弧等API。
//通過方法getContext()獲取Canvas 2D繪圖上下文
var gl=canvas.getContext('2d');
c.moveTo(0,0);//直線起點座標
c.lineTo(50,50);//直線第2個點座標
c.lineTo(0,100);//直線第3個點座標
c.stroke();//把點連成直線繪製出來
執行canvas.getContext('webgl');
返回對象具有一系列繪製渲染三維場景
的方法,也就是WebGL API
//通過方法getContext()獲取WebGL上下文
var gl=canvas.getContext('webgl');
...
//調用WebGL API繪製渲染方法drawArrays
gl.drawArrays(gl.POINTS,0,1);
着色器語言GLSL ES
//頂點着色器源碼
var vertexShaderSource = '' +
'void main(){' +
//給內置變量gl_PointSize賦值像素大小
' gl_PointSize=20.0;' +
//頂點位置,位於座標原點
' gl_Position =vec4(0.0,0.0,0.0,1.0);' +
'}';
片元着色器定義了點的渲染結果像素的顏色值
//片元着色器源碼
var fragShaderSource = '' +
'void main(){' +
//定義片元顏色
' gl_FragColor = vec4(1.0,0.0,0.0,1.0);' +
'}';
gl_PointSize、gl_Position、gl_FragColor都是內置變量
通過程序可以看出來頂點着色器源碼vertexShaderSource、片元着色器源碼fragShaderSource,都是隻有一個主函數main,也就是入口函數。
給內置變量gl_Position賦值vec4(0.0,0.0,0.0,1.0),也就是設置頂點位置座標,vec4代表的是一種數據類型, 在這裏可以理解爲vec4()是一個可以構造出vec4類型數據的構造函數,前三個參數表示頂點座標值xyz。
給內置變量gl_FragColor賦值vec4(1.0,0.0,0.0,1.0),也就是設置會在屏幕上顯示的像素的顏色,vec4()構造函數 前三個參數,表示顏色RGB值,最後一個參數是透明度A。在WebGL着色器中顏色值使用[0,1]區間表示。
你可以通過改變WebGL着色器代碼內置變量gl_PointSize、gl_Position、gl_FragColor測試WebGL渲染效果的變化。
-
gl_PointSize=50.0改爲gl_PointSize=10.0,觀察屏幕點的大小變化
-
gl_Position =vec4(0.5,0.5,0.0,1.0)改爲gl_Position =vec4(0.5,-0.8,0.0,1.0),觀察屏幕點的位置變化
-
gl_FragColor=vec4(0.0,1.0,1.0,1.0)更改爲gl_FragColor = vec4(0.0,0.0,1.0,1.0)
理解gl_FragColor=vec4(r,g,b,alpha)
WebGL API
WebGL API指的就是gl=canvas.getContext(‘webgl’)返回對象gl的一系列繪製渲染方法,通過WebGL API可以把一個三維場景繪製渲染出來。比如上面代碼中gl.createShader()、gl.shaderSource()、gl.drawArrays()等方法就是WebGl API
初始化着色器函數initShader()
//聲明初始化着色器函數
function initShader(gl,vertexShaderSource,fragmentShaderSource){
//創建頂點着色器對象
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
//創建片元着色器對象
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
//引入頂點、片元着色器源代碼
gl.shaderSource(vertexShader,vertexShaderSource);
gl.shaderSource(fragmentShader,fragmentShaderSource);
//編譯頂點、片元着色器
gl.compileShader(vertexShader);
gl.compileShader(fragmentShader);
//創建程序對象program
var program = gl.createProgram();
//附着頂點着色器和片元着色器到program
gl.attachShader(program,vertexShader);
gl.attachShader(program,fragmentShader);
//鏈接program
gl.linkProgram(program);
//使用program
gl.useProgram(program);
//返回程序program對象
return program;
}
繪製方法gl.drawArrays()
gl.drawArrays()方法的作用就是通知GPU執行着色器代碼,然後根據着色器代碼在Canvas畫布上進行渲染繪製。
着色器代碼放在script標籤中
<!-- 頂點着色器源碼 -->
<script id="vertexShader" type="x-shader/x-vertex">
void main() {
//給內置變量gl_PointSize賦值像素大小
gl_PointSize=20.0;
//頂點位置,位於座標原點
gl_Position =vec4(0.0,0.0,0.0,1.0);
}
</script>
<!-- 片元着色器源碼 -->
<script id="fragmentShader" type="x-shader/x-fragment">
void main() {
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
</script>
//頂點着色器源碼
var vertexShaderSource = document.getElementById('vertexShader').innerText;
//片元着色器源碼
var fragShaderSource = document.getElementById('fragmentShader').innerText;
//初始化着色器
var program = initShader(gl,vertexShaderSource,fragShaderSource);
讀書人借書之道,原文鏈接