WebGL程式設計指南(1)簡介
書本原始碼 https://download.csdn.net/download/qfire/10371055
2009年,Khronos建立了WebGL工作小組,開始基於OpenGL ES著手建立WebGL規範,並於2011年釋出了WebGL規範的第1個版本。本書主要基於第1版的WebGL規範編寫,後續更新目前都是以草案的形式釋出,如有需要,也可參考。www.khronos.org/registry/webgl/specs/1.0/
1.1 WebGL程式的結構
1.2 Canvas是什麼?
在HTML5出現之前,如果你想在網頁上顯示影像,只能使用HTML提供的原生方案<img>標籤。用這個標籤顯示影像雖然簡單,但只能顯示靜態的圖片,不能進行實時繪製和渲染。因此,後來出現了一些第三方解決方案,如Flash Player等。HTML5的出現改變了一切,它引入了<canvas>標籤,允許JavaScript動態繪製圖形。
例項
清空
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Clear canvas</title>
</head>
<body onload="main()">
<canvas id="webgl" width="400" height="400">
Please use the browser supporting "canvas"
</canvas>
<script src="../lib/webgl-utils.js"></script>
<script src="../lib/webgl-debug.js"></script>
<script src="../lib/cuon-utils.js"></script>
<script src="HelloCanvas.js"></script>
</body>
</html>
function main() {
var canvas = document.getElementById('webgl');
var gl = getWebGLContext(canvas);
if (!gl) {
console.log("Failed to get the rendering context for WebGL");
return;
}
//RGBA
gl.clearColor(0.0, 0.0, 0.0, 1.0);
//清空
gl.clear(gl.COLOR_BUFFER_BIT);
//繪製點
//gl.drawColor(1.0, 0.0, 0.0, 1.0);
gl.drawPoint(0, 0, 0, 10); //點的位置和大小
}
繪製一個10個畫素大的紅色的點,WebGL處理的是三維圖形,所以我們有必要為這個點指定三維座標。
WebGL依賴於一種新的稱為著色器的繪圖機制。著色器提供了靈魂且強大的繪製二維或三維圖形的方法,所有WebGL程式必須使用它。著色器不僅強大,而且更復雜,僅僅通過一條簡單的繪圖命令是不能操作它的。
//頂點著色器程式
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() {
var canvas = document.getElementById('webgl');
var gl = getWebGLContext(canvas);
if (!gl) {
console.log("Failed to get the rendering context for WebGL");
return;
}
// 初始化著色器
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to initialize shaders.');
return ;
}
//RGBA
gl.clearColor(0.0, 0.0, 0.0, 1.0);
//清空
gl.clear(gl.COLOR_BUFFER_BIT);
//繪製點
gl.drawArrays(gl.POINTS, 0, 1); //點的位置和大小
}
WebGL需要兩種著色器。
- 頂點著色器(Vertex shader):頂點著色器是用來描述頂點特性(如位置、顏色等)的程式。
- 片元著色器(Fragment shader):進行逐片元處理過程如光照的程式。片元是一個WebGL術語,你可以將其理解為畫素。
vec4(x, y, z, w);齊次座標(x, y, z, w)等價於三維座標(x/w, y/w, z/w),齊次座標的存在,使得用矩陣乘法來描述頂點變換成為可能,三維圖形系統在計算過程中,通常使用齊次座標來表示頂點的三維座標。
gl.drawArrays()可以用來繪製各種圖形
1.3 WebGL座標系統
' gl_Position = vec4(0.5, 0.5, 0.0, 1.0); \n' + //設定座標
' gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n' + //設定顏色
注:WebGL不需要交換顏色緩衝區
1.4 繪製一點例項
將位置資訊從JavaScript程式中傳給頂點著色器。有兩種方式可以做到:attribute變數和uniform變數。attribute變數傳輸的是那些與頂點相關的資料,而uniform變數傳輸的是那些對於所有頂點都相同(或與頂點無關)的資料。
//頂點著色器程式
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'void main() {\n' +
' gl_Position = a_Position; \n' + //設定座標
' gl_PointSize = 10.0; \n' + //設定尺寸
'}\n';
//片元著色器程式
var FSHADER_SOURCE =
'void main() {\n' +
' gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n' + //設定顏色
'}\n';
function main() {
var canvas = document.getElementById('webgl');
var gl = getWebGLContext(canvas);
if (!gl) {
console.log("Failed to get the rendering context for WebGL");
return;
}
// 初始化著色器
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to initialize shaders.');
return ;
}
//獲取attribute變數的儲存位置
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;
}
gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);
//RGBA
gl.clearColor(0.0, 0.0, 0.0, 1.0);
//清空
gl.clear(gl.COLOR_BUFFER_BIT);
//繪製點
gl.drawArrays(gl.POINTS, 0, 1); //點的位置和大小
}
//頂點著色器程式
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'void main() {\n' +
' gl_Position = a_Position; \n' + //設定座標
' gl_PointSize = 10.0; \n' + //設定尺寸
'}\n';
//片元著色器程式
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' + //uniform變數
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' + //設定顏色
'}\n';
function main() {
var canvas = document.getElementById('webgl');
var gl = getWebGLContext(canvas);
if (!gl) {
console.log("Failed to get the rendering context for WebGL");
return;
}
// 初始化著色器
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to initialize shaders.');
return ;
}
//獲取attribute變數的儲存位置
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;
}
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
if (u_FragColor < 0) {
console.log("failed to get the storage location of u_FragColor");
return;
}
//註冊滑鼠
canvas.onmousedown = function(ev) { click(ev, gl, canvas, a_Position, u_FragColor)};
gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);
//RGBA
gl.clearColor(0.0, 0.0, 0.0, 1.0);
//清空
gl.clear(gl.COLOR_BUFFER_BIT);
//繪製點
//gl.drawArrays(gl.POINTS, 0, 1); //點的位置和大小
}
var g_points = []; //
var g_colors = [];
function click(ev, gl, canvas, a_Position, u_FragColor) {
var x = ev.clientX;
var y = ev.clientY;
var rect = ev.target.getBoundingClientRect();
x = ((x-rect.left) - canvas.width/2)/(canvas.width/2);
y = (canvas.height/2 - (y-rect.top))/(canvas.height/2);
//將座標儲存到g_points陣列中
g_points.push([x, y]);
//將點的顏色儲存到g_colors陣列中
if (x >= 0.0 && y >= 0.0) { //第一象限
g_colors.push([1.0, 0.0, 0.0, 1.0]); //紅色
} else if (x < 0.0 && y < 0.0) { // 第三象限
g_colors.push([0.0, 1.0, 0.0, 1.0]); //綠色
} else {
g_colors.push([1.0, 1.0, 1.0, 1.0]); //白色
}
//清空
gl.clear(gl.COLOR_BUFFER_BIT);
var len = g_points.length;
for (var i=0; i<len; i++) {
var xy = g_points[i];
var rgba = g_colors[i];
//將點的位置傳輸到a_Position變數中
gl.vertexAttrib3f(a_Position, xy[0], xy[1], 0.0);
//將點的顏色傳輸到u_FragColor變數中
gl.uniform4f(u_FragColor, rgba[0], rgba[1], rgba[2], rgba[3]);
//繪製點
gl.drawArrays(gl.POINTS, 0, 1);
}
}
相關文章
- WebGL程式設計指南(6)光照Web程式設計
- HTML5與WebGL程式設計(1):介紹HTMLWeb程式設計
- WebGL程式設計指南(7)層次模型Web程式設計模型
- WebGL程式設計指南(8)高階技術Web程式設計
- WebGL程式設計指南(5)進入三維世界Web程式設計
- WebGL程式設計指南(4)顏色與紋理Web程式設計
- Quartz 2D程式設計指南 (一) —— 簡介(一)quartz程式設計
- shell程式設計—簡介(一)程式設計
- WebGL程式設計指南(3)高階變換與動畫基礎Web程式設計動畫
- Scala 簡介 [摘自 Scala程式設計 ]程式設計
- SpringBoo+HTMX程式設計簡介Spring程式設計
- Day43--GUI程式設計簡介GUI程式設計
- Windows 程式設計簡介從C/C++到Windows程式設計Windows程式設計C++
- 01 Python3程式設計之程式設計語法簡介Python程式設計
- 最爛的1%程式設計師生存指南程式設計師
- WebGL程式設計指南(2)繪製和變換三角形Web程式設計
- 併發程式設計基礎——JMM簡介程式設計
- 響應式程式設計簡介之:Reactor程式設計React
- Objective-C 執行時程式設計指南-介紹Object程式設計
- ModbusTCP協議簡介與程式設計流程圖TCP協議程式設計流程圖
- Rust語言非同步程式設計簡介 - ShakaibRust非同步程式設計AI
- 非同步程式設計測試Awaitlity簡介| Baeldung非同步程式設計AI
- [譯]AppExtension程式設計指南:擴充套件基礎1APP程式設計套件
- 簡明高效的 Java 併發程式設計學習指南Java程式設計
- 區塊鏈上程式設計:DApp 開發簡介區塊鏈程式設計APP
- 好程式設計師Python培訓分享numpy簡介程式設計師Python
- SAP OData程式設計指南程式設計
- Core Text 程式設計指南程式設計
- Spark—GraphX程式設計指南Spark程式設計
- java設計模式一一設計模式的簡介和介紹Java設計模式
- 前端中的簡單程式設計題-字串(1)前端程式設計字串
- 23種設計模式簡介設計模式
- Yii2設計模式——設計模式簡介設計模式
- 002 Rust 非同步程式設計,async await 簡單介紹Rust非同步程式設計AI
- 簡單介紹python程式設計之檔案讀寫Python程式設計
- 第二章:C#非同步程式設計簡介C#非同步程式設計
- HTML5與WebGL程式設計(2):Three.jsHTMLWeb程式設計JS
- 學廢了系列 - WebGIS vs WebGL圖形程式設計Web程式設計