示例代码

创建日期:2024-06-21
更新日期:2025-01-12

效果图

1705737159101-822.png

顶点着色器

attribute vec4 aPosition;
attribute vec4 aColor;
uniform mat4 uMvpMatrix;
varying vec4 vColor;

void main() {
   gl_Position = uMvpMatrix * aPosition;
  vColor = aColor;
}

片源着色器

precision mediump float;
varying vec4 vColor;
void main() {
  gl_FragColor = vColor;
}

获取WebGL上下文

var canvas = document.getElementById('mycanvas');
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;

// 获取WebGL上下文
var gl = canvas.getContext('webgl');

创建着色器程序

// 编译顶点着色器和片源着色器程序并连接
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, document.getElementById('shader-vs').innerHTML);
gl.compileShader(vertexShader);

var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, document.getElementById('shader-fs').innerHTML);
gl.compileShader(fragmentShader);

var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);

var aPosition = gl.getAttribLocation(shaderProgram, 'aPosition');
var aColor = gl.getAttribLocation(shaderProgram, 'aColor');
var uMvpMatrix = gl.getUniformLocation(shaderProgram, 'uMvpMatrix');

进行矩阵运算

// 这里使用gl-matrix.js进行矩阵运算。
// 计算MVP矩阵并传给着色器
// Model Matrix: 模型矩阵           模型平移旋转缩放
// View Matrix: 视图矩阵            世界坐标系 → 相机坐标系
// Projection Matrix: 投影矩阵      相机坐标系 → 屏幕坐标系
var pmat = mat4.create();
mat4.perspective(pmat, Math.PI * 30 / 180, gl.drawingBufferWidth / gl.drawingBufferHeight, 1, 100);
var vmat = mat4.create();
mat4.lookAt(vmat, vec3.fromValues(3, 3, 7), vec3.fromValues(0, 0, 0), vec3.fromValues(0, 1, 0));
var vpmat = mat4.create();
mat4.mul(vpmat, pmat, vmat);
gl.uniformMatrix4fv(uMvpMatrix, false, vpmat);

把顶点数据传递给着色器

// 把顶点数据传给着色器
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
  1.0, 1.0, 1.0, 1.0, 1.0, 1.0,  // v0 White
  -1.0, 1.0, 1.0, 1.0, 0.0, 1.0,  // v1 Magenta
  -1.0, -1.0, 1.0, 1.0, 0.0, 0.0,  // v2 Red
  1.0, -1.0, 1.0, 1.0, 1.0, 0.0,  // v3 Yellow
  1.0, -1.0, -1.0, 0.0, 1.0, 0.0,  // v4 Green
  1.0, 1.0, -1.0, 0.0, 1.0, 1.0,  // v5 Cyan
  -1.0, 1.0, -1.0, 0.0, 0.0, 1.0,  // v6 Blue
  -1.0, -1.0, -1.0, 0.0, 0.0, 0.0   // v7 Black
]), gl.STATIC_DRAW);

gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, Float32Array.BYTES_PER_ELEMENT * 6, 0);
gl.enableVertexAttribArray(aPosition);

gl.vertexAttribPointer(aColor, 3, gl.FLOAT, false, Float32Array.BYTES_PER_ELEMENT * 6, Float32Array.BYTES_PER_ELEMENT * 3);
gl.enableVertexAttribArray(aColor);

把索引数据传递给着色器

// 把索引数据传给着色器
var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint8Array([
  0, 1, 2, 0, 2, 3,    // front
  0, 3, 4, 0, 4, 5,    // right
  0, 5, 6, 0, 6, 1,    // up
  1, 6, 7, 1, 7, 2,    // left
  7, 4, 3, 7, 3, 2,    // down
  4, 7, 6, 4, 6, 5     // back
]), gl.STATIC_DRAW);

渲染图形

// 渲染
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.enable(gl.DEPTH_TEST);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_BYTE, 0);