WebGL學習筆記(一)
目錄
- 繪制二維圖形(2D圖形)
- 經過一下三個步驟
- 簡單js程序代碼
- 簡單html文件代碼
- 繪制實例(一個點)
- 著色器分為以下兩種:
- 1. 頂點著色器
- 2. 片元著色器
- 初始化著色器
- 繪制操作
- 程序的執行流程
- main()函數的執行流程
- 將位置信息從js程序中傳給頂點著色器
- 使用attribute變量
- 使用uniform變量
- 著色器分為以下兩種:
- 響應鼠標點擊事件動態畫點
繪制二維圖形(2D圖形)
經過一下三個步驟
- 獲取
- 向該元素強求二維圖形的“繪圖上下文”;
- 在繪圖上下文上調用相應的繪圖函數,以繪制二維圖形;
簡單js程序代碼
//DrawRectangle.js function(){ //獲取<canvas>元素 var canvas = document.getElementById(‘example‘);//example是在html文件中定義的canvas元素的id; if(!canvas){ console.log(‘Failed to review the <canvas> element‘); return; } //獲取繪制二維圖形的繪圖上下文 var ctx = canvas.getContext(‘2d‘); //繪制藍色矩形 ctx.fillSyle = ‘rgba(0,0,255,1.0)‘;//設置填充顏色為藍色,r:紅;g:綠;b:藍;a:透明度; ctx.fillRect(120,10,150,150);//使用填充顏色填充矩形 }
簡單html文件代碼
<!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>
其中onload="main()"表示在body執行結束之後執行main()函數,而main()函數在HelloCanvas文件中,因此這也是進入HelloCanvas文件的入口;
繪制實例(一個點)
和之前的以RGB的形式指定WebGL的背景色不一樣,這裏不能直接使用先指定繪圖顏色再繪制的方式。WebGL依賴於一種新的方式成為著色器的繪圖機制。
著色器分為以下兩種:
1. 頂點著色器
var VSHADER_SOURCE= ‘void main() {\n‘ + ‘gl_Position = vec4(0.0,0.0,0.0,1.0);\n‘ +//設置坐標 ‘gl_PointSize = 10.0;\n‘ +//設置尺寸 ‘}\n‘;
- gl_position變量必須被賦值,且其數據類型是float型。gl_PointSize並不是必須的,若不賦值,著色器就會為其取默認值1.0。
- vec4表示的是齊次坐標。(x,y,z,w):x y z表示點的位置坐標,w為0時表示向量,w為1時表示點;
2. 片元著色器
var FSHADER_SOURCE=
‘void main() {\n‘ +
‘gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n‘ +//設置顏色
‘}\n‘;
- 片元就類似於屏幕上的一個像素(嚴格說其包括像素的位置、顏色和其他信息)
- gl_FragColor變量是片元著色器唯一的內置變量,控制著像素在屏幕上的最終顏色。
在代碼中,著色器程序是以字符串的形式“嵌入”在javascript文件中,在程序真正開始運行前它就已經設置好了。
初始化著色器
重要: WebGL程序包括運行在瀏覽器中的JavaScript和運行在WebGL系統的著色器程序這兩個部分。
繪制操作
- 使用gl.drawArrays(gl.POINTS,0,1);來繪制各種圖形
- 參數:mode-繪制方式(有gl.POINTS,gl.LINES,gl.TRIANGLES,gl.LINE_LOOP等等),first-指定從哪個頂點開始繪制(整數型),count-指定繪制需要用到多少個頂點(整數型)
- 程序調用gl.drawArray()時,著色器將被執行count次,每次處理一個頂點。一旦頂點著色器執行完後,片元著色器就會開始執行。
程序的執行流程
- 瀏覽器
- 執行加載js程序
- 執行WebGL的相關方法(頂點著色器、片元著色器,分別逐頂點、逐片元操作)
- 渲染到顏色緩沖區->顯示在瀏覽器上。
main()函數的執行流程
- 獲取
- 獲取WebGL繪圖上下文
- 初始化著色器(頂點、片元)
- 設置
- 清除
- 繪圖
將位置信息從js程序中傳給頂點著色器
使用attribute變量:傳輸的是那些與頂點相關的數據
使用uniform變量:傳輸的是那些對於所有頂點都相同的數據
使用attribute變量
在頂點著色器中,聲明attribute變量;
var VSHADER_SOURCE= ‘attribute vec4 a_Position;\n‘ + ‘void main() {\n‘ + ‘gl_Position = a_Position;\n‘ +//設置坐標 ‘gl_PointSize = 10.0;\n‘ +//設置尺寸 ‘}\n‘;
attribute:存儲限定符;
vec4:類型(數組)
a_Position:變量名
將attribute變量賦值給gl_Position變量;
//獲取attribute變量的存儲位置 var a_Position = gl.getAttributeLocation(gl.program,‘a_Position‘); if(a_Position < 0) { console.log(‘Failed to get the storage location of a_Position‘); return; }
gl.program:程序對象(包括頂點著色器好片元著色器)
a_Position:想要獲取處處地址的attribute變量的名稱
向attribute變量傳輸數據;
//將頂點位置傳輸給attribute變量 gl.vertexAttrib3f(a_Position,0.0,0.0,0.0);
a_Position:attribute變量的存儲地址
後三個參數:x、y、z坐標值
省略了w透明度分量,函數會默認將第四個分量設置為1.0。
使用uniform變量
改變點的顏色可以使用uniform變量實現
在片元著色器中準備uniform變量;
var FSHADER_SOURCE= ‘precision mediump float;\n‘ + ‘uniform vec4 u_FragColor;\n‘ +//uniform變量 ‘void main() {\n‘ + ‘gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n‘ +//設置顏色 ‘}\n‘;
- 用這個uniform變量想gl_FragColor賦值;
//獲取attribute變量的存儲位置 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; }
將顏色數據從javascript傳給uniform變量;
gl.uniform4f(u_FragColor,rgba[0],rgba[1],rgba[2],rgba[3]);
響應鼠標點擊事件動態畫點
- 在main()函數裏面註冊鼠標點擊事件相應函數(匿名函數)。
//註冊鼠標點擊事件響應函數
canvas.onmousedown = function(ev) { click(ev,gl,canvas,a_Position); };
- click函數完成了什麽
- 獲取鼠標點擊的位置並存儲在一個數組中;
- 清空
- 格局數組的每個元素,在響應的位置繪制點;
- 不能直接使用鼠標點擊位置原因
- 鼠標點擊位置是在“瀏覽器客戶區”中的坐標,而不是在
將坐標從瀏覽器客戶區坐標系下轉換到canvas坐標系下
var x = ev.clientX; var y = ev.clientY; var rect = ev.target.getBoundingClientRect();
將坐標從canvas坐標系下轉換到WebGL下x = ((x - rect.left) - canvas.width/2)/(canvas.width/2);//<canvas>的中心點坐標是(canvas.height/2, canvas.width/2); y = (canvas.height/2 - (y - rect.top))/(canvas.height/2);
WebGL學習筆記(一)