WebGL是一套基于OpenGL ES标准的浏览器端3D图形渲染接口,允许开发者通过JavaScript调用GPU的并行计算能力,在网页中渲染复杂的3D图形。它不需要额外安装插件,只要浏览器支持WebGL规范就能运行,是网页3D可视化、小游戏开发等场景的核心技术之一。

WebGL 3D渲染的基础准备
要使用WebGL进行渲染,首先需要在HTML页面中准备一个<canvas>元素,它是WebGL的渲染载体。然后通过JavaScript获取WebGL上下文,后续所有的渲染操作都会基于这个上下文完成。
获取WebGL上下文的代码如下:
// 获取canvas元素
const canvas = document.getElementById('webgl-canvas');
// 获取WebGL上下文,第二个参数是上下文配置,可设置抗锯齿等属性
const gl = canvas.getContext('webgl');
// 兼容性处理,部分浏览器支持experimental-webgl
if (!gl) {
const gl = canvas.getContext('experimental-webgl');
}
if (!gl) {
console.error('当前浏览器不支持WebGL');
}
编写WebGL着色器程序
WebGL的渲染逻辑分为顶点着色器和片元着色器两部分,两者都是用GLSL语言编写的小程序,运行在GPU上。顶点着色器负责处理每个顶点的位置、颜色等属性,片元着色器负责计算每个像素的最终颜色。
顶点着色器示例
下面的顶点着色器定义了一个顶点位置属性和一个顶点颜色属性,同时将顶点位置传递给内置变量gl_Position,将颜色传递给片元着色器:
// 顶点着色器代码
const vertexShaderSource = `
// 顶点位置属性,从外部传入
attribute vec4 a_position;
// 顶点颜色属性
attribute vec4 a_color;
// 传递给片元着色器的颜色变量
varying vec4 v_color;
void main() {
// 设置顶点最终位置,这里直接输出传入的位置
gl_Position = a_position;
// 将颜色传递给片元着色器
v_color = a_color;
}
`;
片元着色器示例
片元着色器接收顶点着色器传递过来的颜色,直接作为像素的最终颜色输出:
// 片元着色器代码
const fragmentShaderSource = `
// 精度声明,WebGL中片元着色器需要指定浮点数精度
precision mediump float;
// 接收顶点着色器传递的颜色
varying vec4 v_color;
void main() {
// 设置像素最终颜色
gl_FragColor = v_color;
}
`;
编译和链接着色器程序
编写完着色器源码后,需要将它们编译成GPU可执行的着色器对象,再链接成一个完整的着色器程序,才能被WebGL使用。
编译和链接的代码如下:
// 创建着色器对象并编译的函数
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;
}
// 创建着色器程序并链接的函数
function createProgram(gl, vertexShader, fragmentShader) {
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
// 检查链接是否成功
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.error('着色器程序链接失败:', gl.getProgramInfoLog(program));
gl.deleteProgram(program);
return null;
}
return program;
}
// 编译顶点着色器
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
// 编译片元着色器
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
// 创建着色器程序
const program = createProgram(gl, vertexShader, fragmentShader);
// 使用当前着色器程序
gl.useProgram(program);
传递顶点数据到GPU
着色器程序准备好后,需要将3D图形的顶点数据传递到GPU的缓冲区中,然后告诉着色器如何读取这些数据。
首先定义一组三角形的顶点数据,包含位置和颜色信息:
// 顶点数据:每5个值为一组,前3个是xyz位置,后2个暂时不用,这里用0填充,实际颜色用后面的rgba // 这里简化为每个顶点包含位置和颜色,位置是3个float,颜色是4个float,共7个float一组 const vertices = new Float32Array([ // 位置x,y,z 颜色r,g,b,a 0.0, 0.5, 0.0, 1.0, 0.0, 0.0, 1.0, // 顶部顶点,红色 -0.5, -0.5, 0.0, 0.0, 1.0, 0.0, 1.0, // 左下顶点,绿色 0.5, -0.5, 0.0, 0.0, 0.0, 1.0, 1.0 // 右下顶点,蓝色 ]); // 创建缓冲区对象 const vertexBuffer = gl.createBuffer(); // 绑定缓冲区到ARRAY_BUFFER目标 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); // 将顶点数据写入缓冲区 gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); // 获取顶点着色器中a_position属性的位置 const aPositionLocation = gl.getAttribLocation(program, 'a_position'); // 获取顶点着色器中a_color属性的位置 const aColorLocation = gl.getAttribLocation(program, 'a_color'); // 每个顶点的数据长度,7个float,每个float4字节,共28字节 const stride = 7 * Float32Array.BYTES_PER_ELEMENT; // 位置数据在每组的起始偏移,0字节 const positionOffset = 0; // 颜色数据在每组的起始偏移,3个float之后,即12字节 const colorOffset = 3 * Float32Array.BYTES_PER_ELEMENT; // 启用a_position属性 gl.enableVertexAttribArray(aPositionLocation); // 告诉GPU如何读取位置数据 gl.vertexAttribPointer(aPositionLocation, 3, gl.FLOAT, false, stride, positionOffset); // 启用a_color属性 gl.enableVertexAttribArray(aColorLocation); // 告诉GPU如何读取颜色数据 gl.vertexAttribPointer(aColorLocation, 4, gl.FLOAT, false, stride, colorOffset);
执行绘制命令
所有准备工作完成后,只需要调用WebGL的绘制命令,就能将3D图形渲染到<canvas>上。同时可以设置清屏颜色,每次绘制前清空画布。
绘制代码如下:
// 设置清屏颜色为黑色,透明度1.0 gl.clearColor(0.0, 0.0, 0.0, 1.0); // 清空颜色缓冲区 gl.clear(gl.COLOR_BUFFER_BIT); // 绘制三角形,从0号顶点开始,绘制3个顶点 gl.drawArrays(gl.TRIANGLES, 0, 3);
常见问题说明
- 如果<canvas>显示黑色,首先检查浏览器是否支持WebGL,然后检查着色器编译和链接是否有报错。
- 顶点坐标的范围是-1到1,超出这个范围的部分不会被显示,这是WebGL的归一化设备坐标规则。
- 如果要渲染更复杂的3D模型,只需要准备更多的顶点数据,调整drawArrays的参数即可,核心流程和上述示例一致。
以上就是使用JavaScript的WebGL进行基础3D图形渲染的完整流程,掌握这些步骤后,可以在此基础上扩展添加旋转、缩放、光照等更复杂的3D效果。
WebGLJavaScript3D图形渲染canvas修改时间:2026-07-13 09:06:35