目录
简介
变量特点
1. Attribute 变量
2. Uniform 变量
3. Varying 变量
4. Const 变量
5. 预定义变量
示例:
1. 顶点着色器示例
2. 片元着色器示例:
设置attribute示例
设置uniform示例
完整代码示例:
简介
着色器中变量声明: attribute、varing、uniform。设置attribute、uniform。预定义变量。const变量。
变量特点
1. Attribute 变量
用于接收顶点数据,只能在顶点着色器中声明和使用。
attribute vec3 a_position;
2. Uniform 变量
用于在 JavaScript 代码中设置并在着色器程序中保持不变的值,可以在顶点着色器和片元着色器中声明和使用。但是必现要保证变量名唯一,即顶点着色器和片元着色器的uniform变量不能相同。
uniform mat4 u_modelMatrix;
3. Varying 变量
用于在顶点着色器和片元着色器之间传递数据,顶点着色器中声明的 varying 变量的值会被插值后传递给片元着色器。
varying vec4 v_color;
4. Const 变量
在着色器中声明的常量值,在整个着色器程序中保持不变。
const float PI = 3.14159265359;
5. 预定义变量
WebGL 中内置了一些预定义的特殊变量,如 gl_Position(顶点着色器中)和 gl_FragColor(片元着色器中),它们分别用于设置顶点位置和片元颜色。
示例:
1. 顶点着色器示例
// 编译顶点着色器
var vertexShaderSource = `attribute vec3 a_position;attribute vec4 a_color;attribute vec2 a_texcoord;uniform mat4 u_modelMatrix;uniform mat4 u_viewMatrix;uniform mat4 u_projectionMatrix;varying vec4 v_color;varying vec2 v_texcoord;void main() {gl_Position = u_projectionMatrix * u_viewMatrix * u_modelMatrix * vec4(a_position, 1.0);v_color = a_color;v_texcoord = a_texcoord;}
`;
2. 片元着色器示例:
// 编译片元着色器
var fragmentShaderSource = `precision mediump float;varying vec4 v_color;varying vec2 v_texcoord;void main() {gl_FragColor = v_color;}
`;
设置attribute示例
// 设置顶点属性
var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
var colorAttributeLocation = gl.getAttribLocation(program, "a_color");
var texcoordAttributeLocation = gl.getAttribLocation(program, "a_texcoord");
gl.enableVertexAttribArray(positionAttributeLocation);
gl.enableVertexAttribArray(colorAttributeLocation);
gl.enableVertexAttribArray(texcoordAttributeLocation);
设置uniform示例
// 计算模型、视图和投影矩阵
var modelMatrix = mat4.create(); // 模型矩阵
var viewMatrix = mat4.create(); // 视图矩阵
var projectionMatrix = mat4.create(); // 投影矩阵// 设置模型矩阵
mat4.translate(modelMatrix, modelMatrix, [0.0, 0.0, -5.0]);// 设置视图矩阵
mat4.lookAt(viewMatrix, [0, 0, 5], [0, 0, 0], [0, 1, 0]);// 设置投影矩阵
mat4.perspective(projectionMatrix, Math.PI / 4, canvas.width / canvas.height, 0.1, 100);// 将模型、视图和投影矩阵传递给顶点着色器
var modelMatrixUniformLocation = gl.getUniformLocation(program, "u_modelMatrix");
gl.uniformMatrix4fv(modelMatrixUniformLocation, false, modelMatrix);var viewMatrixUniformLocation = gl.getUniformLocation(program, "u_viewMatrix");
gl.uniformMatrix4fv(viewMatrixUniformLocation, false, viewMatrix);var projectionMatrixUniformLocation = gl.getUniformLocation(program, "u_projectionMatrix");
gl.uniformMatrix4fv(projectionMatrixUniformLocation, false, projectionMatrix);
完整代码示例:
// 获取 WebGL 上下文
var canvas = document.getElementById("webgl-canvas");
var gl = canvas.getContext("webgl");// 编译顶点着色器
var vertexShaderSource = `attribute vec3 a_position;attribute vec4 a_color;attribute vec2 a_texcoord;uniform mat4 u_modelMatrix;uniform mat4 u_viewMatrix;uniform mat4 u_projectionMatrix;varying vec4 v_color;varying vec2 v_texcoord;void main() {gl_Position = u_projectionMatrix * u_viewMatrix * u_modelMatrix * vec4(a_position, 1.0);v_color = a_color;v_texcoord = a_texcoord;}
`;
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexShaderSource);
gl.compileShader(vertexShader);// 编译片元着色器
var fragmentShaderSource = `precision mediump float;varying vec4 v_color;varying vec2 v_texcoord;void main() {gl_FragColor = v_color;}
`;
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentShaderSource);
gl.compileShader(fragmentShader);// 创建着色器程序并链接
var program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
gl.useProgram(program);// 设置顶点属性
var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
var colorAttributeLocation = gl.getAttribLocation(program, "a_color");
var texcoordAttributeLocation = gl.getAttribLocation(program, "a_texcoord");
gl.enableVertexAttribArray(positionAttributeLocation);
gl.enableVertexAttribArray(colorAttributeLocation);
gl.enableVertexAttribArray(texcoordAttributeLocation);// 计算模型、视图和投影矩阵
var modelMatrix = mat4.create(); // 模型矩阵
var viewMatrix = mat4.create(); // 视图矩阵
var projectionMatrix = mat4.create(); // 投影矩阵// 设置模型矩阵
mat4.translate(modelMatrix, modelMatrix, [0.0, 0.0, -5.0]);// 设置视图矩阵
mat4.lookAt(viewMatrix, [0, 0, 5], [0, 0, 0], [0, 1, 0]);// 设置投影矩阵
mat4.perspective(projectionMatrix, Math.PI / 4, canvas.width / canvas.height, 0.1, 100);// 将模型、视图和投影矩阵传递给顶点着色器
var modelMatrixUniformLocation = gl.getUniformLocation(program, "u_modelMatrix");
gl.uniformMatrix4fv(modelMatrixUniformLocation, false, modelMatrix);var viewMatrixUniformLocation = gl.getUniformLocation(program, "u_viewMatrix");
gl.uniformMatrix4fv(viewMatrixUniformLocation, false, viewMatrix);var projectionMatrixUniformLocation = gl.getUniformLocation(program, "u_projectionMatrix");
gl.uniformMatrix4fv(projectionMatrixUniformLocation, false, projectionMatrix);// 顶点数据
var vertices = [-0.5, -0.5, 0.0, // 顶点位置1.0, 0.0, 0.0, 1.0, // 顶点颜色,红色0.0, 0.0, // 顶点纹理坐标0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, // 顶点颜色,绿色1.0, 0.0, 0.0, 0.5, 0.0,0.0, 0.0, 1.0, 1.0, // 顶点颜色,蓝色0.5, 1.0
];
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);// 将顶点位置属性绑定到缓冲区
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 8 * Float32Array.BYTES_PER_ELEMENT, 0);
gl.vertexAttribPointer(colorAttributeLocation, 4, gl.FLOAT, false, 8 * Float32Array.BYTES_PER_ELEMENT, 3 * Float32Array.BYTES_PER_ELEMENT);
gl.vertexAttribPointer(texcoordAttributeLocation, 2, gl.FLOAT, false, 8 * Float32Array.BYTES_PER_ELEMENT, 7 * Float32Array.BYTES_PER_ELEMENT)