Bootstrap

webGL=>着色器的变量声明、设置、预定变量等

目录

简介

变量特点

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)

;