在前端开发中,HTML5 的画布(<canvas>
)元素为我们提供了强大的绘图能力,不仅可以进行 2D 绘图,借助 WebGL(Web Graphics Library)还能实现 3D 绘图。WebGL 是一种基于 OpenGL ES 2.0 的 JavaScript API,它允许在网页上直接渲染高性能的 3D 图形。本文将带领大家创建一个简单的 3D 场景,通过逐步介绍和示例代码,帮助大家掌握基本的 3D 绘图技巧。
在进行 3D 绘图时,我们需要了解几个重要的概念:
首先,我们需要在 HTML 文件中创建一个画布元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple 3D Scene</title>
</head>
<body>
<canvas id="glCanvas" width="640" height="480"></canvas>
<script src="script.js"></script>
</body>
</html>
在 JavaScript 文件(script.js
)中,我们需要获取画布的 WebGL 上下文。
// 获取画布元素
const canvas = document.getElementById('glCanvas');
// 获取 WebGL 上下文
const gl = canvas.getContext('webgl');
if (!gl) {
alert('无法初始化 WebGL,你的浏览器可能不支持。');
return;
}
我们以一个简单的立方体为例,定义其顶点数据。
// 立方体的顶点数据
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 vertexShaderSource = `
attribute vec3 a_position;
void main() {
gl_Position = vec4(a_position, 1.0);
}
`;
// 片段着色器代码
const fragmentShaderSource = `
precision mediump float;
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;
// 创建着色器函数
function createShader(gl, type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (success) {
return shader;
}
console.log(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
// 创建着色器程序函数
function createProgram(gl, vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
const success = gl.getProgramParameter(program, gl.LINK_STATUS);
if (success) {
return program;
}
console.log(gl.getProgramInfoLog(program));
gl.deleteProgram(program);
}
// 创建并编译顶点着色器
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
// 创建并编译片段着色器
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
// 创建着色器程序
const program = createProgram(gl, vertexShader, fragmentShader);
将顶点数据存储到缓冲区中,并绑定到着色器的属性上。
// 创建缓冲区
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, // 每个顶点包含 3 个坐标
gl.FLOAT, // 数据类型为浮点数
false,
0,
0
);
最后,我们可以使用着色器程序绘制立方体。
// 使用着色器程序
gl.useProgram(program);
// 设置清除颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 清除颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
// 绘制立方体
gl.drawArrays(gl.TRIANGLE_FAN, 0, positions.length / 3);
通过以上步骤,我们成功创建了一个简单的 3D 场景,绘制了一个红色的立方体。下面是一个简单的总结表格:
| 步骤 | 描述 |
| —— | —— |
| 1. 创建 HTML 结构 | 创建一个包含画布元素的 HTML 文件 |
| 2. 获取 WebGL 上下文 | 获取画布的 WebGL 上下文 |
| 3. 定义顶点数据 | 定义 3D 模型的顶点坐标 |
| 4. 创建和编译着色器 | 创建顶点着色器和片段着色器,并编译链接成着色器程序 |
| 5. 创建和绑定缓冲区 | 将顶点数据存储到缓冲区中,并绑定到着色器的属性上 |
| 6. 绘制场景 | 使用着色器程序绘制 3D 模型 |
当然,这只是一个简单的示例,实际的 3D 场景可能会更加复杂,需要考虑光照、材质、纹理等因素。希望本文能为你打开 3D 绘图的大门,让你在前端开发中创造出更加炫酷的效果。