本文主要介绍我在做webgpu技术选型时考虑的关键因素,从使用场景、学习成本、兼容性、性能、通用性,以及webgpu未来的发展和缺点多个维度来介绍。
作者也是刚开始入门学习webgpu,在此分享一下个人经验。
什么是webgpu
WebGPU 是一种在Web浏览器中进行高性能图形渲染的新一代图形API。它的目标是提供比现有的WebGL更底层、更现代化、更高效的图形编程接口,以支持更复杂和更高性能的图形应用程序。WebGPU 的设计受到了现代图形API(如Vulkan和Metal)的影响,以满足对于更直接硬件控制和更好性能优化的需求。
使用场景
主要是介绍我接触的一些场景吧
1、web3d相关
- 主流3d渲染引擎,threejs、babylon.js的渲染器都支持webgpu渲染
2、AI相关
- tensorflow.js支持webgpu渲染,并用来加速手机端的深度学习,比起webgl能带来20~30倍提升
- 通过tensorflow+webgpu/webgl 以实现很多效果,比如人像分割,人脸检测
学习成本(达到入门)
1、渲染管线
- 需要了解渲染管线,缓冲区、顶点着色器,片元着色器,图元装配,光栅化等概念

2、WGSL语言
- 如果有其他着色器语言基础,学习会非常简单
- 如果有Typescript、C等基础,理解WGSL相对容易
- 只熟悉js 相对难度高一些
举例:
所有顶点数据经过这个流水线的时候,都会执行顶点着色器代码中顶点计算的函数
less
@vertex
fn main(@location(0) pos: vec3<f32>) -> @builtin(position) vec4<f32> {
var pos2 = vec4<f32>(pos,1.0);//pos转齐次坐标
pos2.x -= 0.2;//偏移所有顶点的x坐标
return pos2;
}
3、webgpu使用的数据结构
在实际开发中,webgl webgpu webassembly会用类型化数组表示数据
javascript
const vertexArray = new Float32Array([
// 三角形三个顶点坐标的x、y、z值
0.0, 0.0, 0.0,//顶点1坐标
1.0, 0.0, 0.0,//顶点2坐标
0.0, 1.0, 0.0,//顶点3坐标
]);
4、调用流程,涉及到的参数细节
1、首先获取gpu适配器,获取gpu器设备,后续就能操作显卡
csharp
const adapter = await navigator.gpu.requestAdapter()
const device = await adapter.requestDevice()
2、画布和gpu绑定
ini
const canvas = document.getElementById('webgpu')
const context = canvas.getContext('webgpu')
context.configure({
device: device,//WebGPU渲染器使用的GPU设备对象
});
3、设置渲染管线,有很多配置细节
php
const pipeline = device.createRenderPipeline({
layout: 'auto',
vertex: {
// 顶点着色器
module: device.createShaderModule({ code: vertex }),
entryPoint: "main",
buffers: [// 顶点所有的缓冲区模块设置
{//其中一个顶点缓冲区设置
arrayStride: 3*4,//一个顶点数据占用的字节长度,该缓冲区一个顶点包含xyz三个分量,每个数字是4字节浮点数,3*4字节长度
attributes: [{// 顶点缓冲区属性
shaderLocation: 0,//GPU显存上顶点缓冲区标记存储位置
format: "float32x3",//格式:loat32x3表示一个顶点数据包含3个32位浮点数
offset: 0//arrayStride表示每组顶点数据间隔字节数,offset表示读取改组的偏差字节数,没特殊需要一般设置0
}]
}
]
},
fragment: {
// 片元着色器
module: device.createShaderModule({ code: fragment }),
entryPoint: "main",
},
primitive: {
topology: "triangle-list",//三角形绘制顶点数据
},
});
4、真正渲染
webgpu API,默认不会直接执行,如果想在GPU上执行,还需要配置GPU命令编码器对象commandEncoder实现
scss
//建立渲染通道,类似图层
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
//传入渲染管线
passEncoder.setPipeline(pipeline);
//绘图,3个顶点
passEncoder.draw(3);
//结束编码
passEncoder.end();
//向gpu提交绘图指令,所有指令将在提交后执行
device.queue.submit([commandEncoder.finish()]);
系统支持/兼容性
可以看到绿色的是已经正式环境支持的,红色的表示正在试验中,暂未支持。
chrome113、edge113、opera99版本以上开始正式支持

再看webgl 兼容性会很好

性能
这是一项矩阵乘法测试
横轴代表矩阵的大小,纵轴代表着时间,明显gpu的运算速度快很多
实验证明,WebGPU 计算着色器实际上比使用像素着色器的 WebGL 计算快 3.5 倍,同时在要处理的数据量方面具有明显更高的限制,而且它不会阻塞主线程。这允许在浏览器中执行新类型的任务:视频和音频编辑、实时物理模拟、更真实的视觉效果、机器学习。

全端/重用
显而易见,webgpu运行在chrominue内核的新版本浏览器,pc端,web端,移动端没有问题的,微信小程序应该暂未支持。
webgpu本身是一套全新的规范api,用到的着色器语言是wgsl,也无法复用opengl、webgl的着色器代码
未来发展
webgpu从性能上还是对显卡的操作上,都是更效率,性能更好的一种方式,而webgl源于opengl2.0版本做出的一套规范,并且应该有十几年了,对于现在的显卡来说,操作方式略微过时。
但目前主流的3d渲染引擎还是主要用webgl,但同时也在支持webgpu,未来webgpu肯定会逐渐发展起来。
缺点 top3
1、兼容性问题
webgpu是一个较新的技术,兼容性很低,不是所有浏览器都支持,而webgl已经存在了一段时间,得到了更广泛的支持。
2、复杂性和学习曲线
webgpu比起webgl更加底层,更接近硬件,提供了更多的控制和性能优化机会,然而也导致的更高的复杂性和学习曲线,需要深入了解图形学原理,有效使用webgpu。
3、性能的优势有限
对于一些简单的图形应用,webgpu可能显得过于复杂,而性能并不明显,webgl已经足够适用于更多的场景,简单的需求性能表现可能会更好。