
在前端开发中,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 绘图的大门,让你在前端开发中创造出更加炫酷的效果。