介紹:定義存儲的變量是什麼類型,常用的有attribute、uniform
1、attribute
傳輸與頂點相關的數據。
定義方式:<存儲限定符><數據類型><變量名稱>
attribute vec4 a_Position
/**
* 頂點着色器
* gl_Position 常量 代表是位置 vec4 一個函數 返回一個vec4類型的數據
* g1_PointSize 常量 代表是尺寸 float類型
* @type {string}
*/
const VSHADER_SOURCE =
'attribute vec4 a_Position;' + // 定義a_Position 頂點位置信息
'attribute vec4 a_PointSize;' + // 定義a_Position 頂點位置信息
'void main() { ' +
'gl_Position = a_Position;' +
'gl_PointSize = a_PointSize;' +
'}';
javaScript獲取變量:g1.get
2、uniform
傳輸與頂掉無關或者對所有頂點都相同的數據。
/**
* 片元着色器
* gl_FragColor 常量 代表顏色 類型爲vec4
* @type {string}
*/
const FSHADER_SOURCE =
'precision mediump float;' + // uniform變量可以指定任意類型的數據 因此需使用精度限定詞指定精度 attribute只能指定float
'uniform vec4 u_FragColor;' + // 定義a_FragColor 顏色信息
'void main() {' +
'gl_FragColor = u_FragColor;' +
'}';
3、varying (待學習)
4、demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webGl qualifier</title>
<style>
body {
margin: 0px;
}
</style>
</head>
<body onload="main()">
<canvas id="webGl" width="900px" height="900px" style="width: 900px;height: 900px;"></canvas>
<script>
/**
* 頂點着色器
* gl_Position 常量 代表是位置 vec4 一個函數 返回一個vec4類型的數據
* g1_PointSize 常量 代表是尺寸 float類型
* @type {string}
*/
const VSHADER_SOURCE =
'attribute vec4 a_Position;' + // 定義a_Position 頂點位置信息
'attribute float a_PointSize;' + // 定義a_Position 頂點位置信息
'void main() { ' +
'gl_Position = a_Position;' +
'gl_PointSize = a_PointSize;' +
'}';
/**
* 片元着色器
* gl_FragColor 常量 代表顏色 類型爲vec4
* @type {string}
*/
const FSHADER_SOURCE =
'precision mediump float;' + // uniform變量可以指定任意類型的數據 因此需使用精度限定詞指定精度 attribute只能指定float
'uniform vec4 u_FragColor;' + // 定義a_FragColor 顏色信息
'void main() {' +
'gl_FragColor = u_FragColor;' +
'}';
function main() {
const canvas = document.getElementById('webGl');
// Get the rendering context for WebGL
const gl = canvas.getContext('experimental-webgl ') || canvas.getContext('webgl');
if (!gl) {
console.log('不支持webGl 請使用谷歌瀏覽器查看!');
return;
}
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('着色器初始化失敗!');
return;
}
// 獲取位置信息
const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
// 獲取大小信息
const a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
// 獲取顏色信息
const a_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
// 將位置信息傳遞給着色器
gl.vertexAttrib3f(a_Position, 0.1, 0.1, 0.1);
// 將大小信息傳遞給着色器
gl.vertexAttrib1f(a_PointSize, 100.0);
// 將顏色信息傳遞給着色器
gl.uniform4f(a_FragColor, 0.1, 0.1, 0.1, 1.0);
// 清理顏色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清空canvas
gl.clear(gl.COLOR_BUFFER_BIT);
// 繪製一個點
gl.drawArrays(gl.POINTS, 0, 1);
}
/**
* 初始化着色器
* @param gl
* @param vshader
* @param fshader
* @returns {*}
*/
function initShaders(gl, vshader, fshader) {
const program = createProgram(gl, vshader, fshader);
if (!program) {
console.log('創建WebGLProgram程序失敗');
return false;
}
// 方法將定義好的WebGLProgram 對象添加到當前的渲染狀態中。
gl.useProgram(program);
gl.program = program;
return true;
}
/**
* 創建着色器程序 WebGLProgram
* @param gl
* @param vshader
* @param fshader
* @returns {*}
*/
function createProgram(gl, vshader, fshader) {
// 創建着色器對象
const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader);
const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader);
if (!vertexShader || !fragmentShader) {
return null;
}
// 創建一個着色器程序對象
const program = gl.createProgram();
if (!program) {
return null;
}
// 負責往 着色器程序對象(WebGLProgram) 添加一個片段或者頂點着色器。
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
// 鏈接給定的WebGLProgram,從而完成爲程序的片元和頂點着色器準備GPU代碼的過程。
gl.linkProgram(program);
// Check the result of linking
const linked = gl.getProgramParameter(program, gl.LINK_STATUS);
if (!linked) {
const error = gl.getProgramInfoLog(program);
console.log('鏈接程序失敗: ' + error);
gl.deleteProgram(program);
gl.deleteShader(fragmentShader);
gl.deleteShader(vertexShader);
return null;
}
return program;
}
/**
* 加載着色器
* @param gl
* @param type
* @param source
* @returns {*}
*/
function loadShader(gl, type, source) {
// 創建着色器對象
const shader = gl.createShader(type);
if (shader == null) {
console.log('unable to create shader');
return null;
}
/**
* 設置着色器程序
* shader着色器對象
* source 包含GLSL程序代碼的字符串。
*/
gl.shaderSource(shader, source);
// 編譯一個GLSL着色器,使其成爲爲二進制數據,然後就可以被WebGLProgram對象所使用.
gl.compileShader(shader);
// 返回給定的着色器信息
const compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (!compiled) {
const error = gl.getShaderInfoLog(shader);
console.log('編譯着色器失敗: ' + error);
gl.deleteShader(shader);
return null;
}
return shader;
}
</script>
</body>
</html>