使用 WebGL 创建 3D 动画
WebGL 是一种用于渲染交互式 3D 图形的标准,它不需要任何插件就能在现代浏览器中运行。本文将介绍如何使用 WebGL 和 JavaScript 来创建一个简单的旋转立方体动画。
1. 设置基本的 HTML 结构
首先,我们需要创建一个 HTML 文件,包含一个 <canvas>
元素来显示 WebGL 渲染的内容。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebGL Cube</title>
<style>
body {
margin: 0; }
canvas {
width: 100%; height: 100vh; display: block; }
</style>
</head>
<body>
<canvas id="cubeCanvas"></canvas>
<script src="webgl-cube.js"></script>
</body>
</html>
2. 初始化 WebGL 上下文
接下来,在 webgl-cube.js
文件中,我们需要初始化 WebGL 上下文,并设置一些基本的属性。
const canvas = document.getElementById('cubeCanvas');
const gl = canvas.getContext('webgl');
if (!gl) {
console.error('Unable to initialize WebGL. Your browser may not support it.');
}
// 设置视口大小
gl.viewport(0, 0, canvas.width, canvas.height);
// 清除颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清除深度缓冲区
gl.clearDepth(1.0);
// 开启深度测试
gl.enable(gl.DEPTH_TEST);
3. 创建顶点着色器和片段着色器
为了绘制3D图形,我们需要定义顶点着色器和片段着色器。这两个着色器负责处理顶点数据和像素着色。
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}
const vertexShaderSource = `
attribute vec4 a_position;
void main() {
gl_Position = a_position;
}`;
const fragmentShaderSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}`;
4. 编译着色器并创建着色器程序
编译着色器并创建一个着色器程序,该程序将用于渲染。
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error("Unable to initialize the shader program.");
}
gl.useProgram(program);
5. 定义几何体数据
为了绘制一个立方体,我们需要定义它的顶点坐标。
const positions = [
// 前面
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// 后面
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, -1.0, -1.0,
// 左边
-1.0, -1.0, -1.0,
-1.0, 1.0, -1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, 1.0,
// 右边
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
1.0, -1.0, 1.0,
// 顶部
-1.0, 1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
// 底部
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0
];
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
const positionAttributeLocation = gl.getAttribLocation(program, 'a_position');
gl.enableVertexAttribArray(positionAttributeLocation);
gl.vertexAttribPointer(positionAttributeLocation, 3, gl.FLOAT, false, 0, 0);
6. 绘制立方体
最后,我们需要一个函数来绘制立方体,并让它旋转起来。
let angle = 0;
function drawScene() {
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
const matrix = mat4.create();
mat4.rotateX(matrix, matrix, degToRad(angle));
mat4.rotateY(matrix, matrix, degToRad(angle));
const u_matrix = gl.getUniformLocation(program, "u_matrix");
gl.uniformMatrix4fv(u_matrix, false, matrix);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 36);
requestAnimationFrame(drawScene);
}
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
angle += 0.5;
requestAnimationFrame(drawScene);
以上代码创建了一个旋转的3D立方体。你可以在此基础上扩展,添加更多的几何体、纹理或者光照效果。WebGL 是一个强大的工具,通过它你可以创建出非常丰富的3D体验。