无需登录 数据私有 本地保存

WebGPU入门演示 - GPU渲染基础三角形

13
0
0
0

WebGPU 基础三角形渲染

体验下一代 Web 图形 API —— 使用 WGSL 着色语言在 GPU 上渲染你的第一个三角形

实时控制
渲染流程步骤:
  • ① 初始化GPU
  • ② 创建缓冲区
  • ③ 编译着色器
  • ④ 构建管线
  • ⑤ 编码渲染
// 顶点着色器 - 处理旋转与坐标变换
struct VertexOutput {
    @builtin(position) position: vec4<f32>,
    @location(0) color: vec4<f32>,
};

struct Uniforms {
    angle: f32,
    time: f32,
    colorMul: vec4<f32>,
};

@group(0) @binding(0) var<uniform> uniforms: Uniforms;

@vertex
fn vs_main(
    @location(0) pos: vec2<f32>,
    @location(1) col: vec4<f32>,
) -> VertexOutput {
    var out: VertexOutput;
    let c = cos(uniforms.angle);
    let s = sin(uniforms.angle);
    let rx = pos.x * c - pos.y * s;
    let ry = pos.x * s + pos.y * c;
    out.position = vec4<f32>(rx, ry, 0.0, 1.0);
    out.color = col;
    return out;
}

// 片元着色器 - 输出插值颜色
@fragment
fn fs_main(
    @location(0) color: vec4<f32>,
) -> @location(0) vec4<f32> {
    return color * uniforms.colorMul;
}
// 1. 检查 WebGPU 支持
if (!navigator.gpu) {
    console.error('WebGPU 不受支持');
}

// 2. 请求 GPU 适配器与设备
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

// 3. 配置 Canvas Context
const ctx = canvas.getContext('webgpu');
ctx.configure({ device, format: navigator.gpu.getPreferredCanvasFormat() });

// 4. 创建顶点缓冲区 (3个顶点, RGB渐变)
const vertices = new Float32Array([
    0.0,  0.6,  1,0,0,1,  // 顶部 - 红色
   -0.5, -0.4,  0,1,0,1,  // 左下 - 绿色
    0.5, -0.4,  0,0,1,1,  // 右下 - 蓝色
]);
const vBuf = device.createBuffer({
    size: vertices.byteLength,
    usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(vBuf, 0, vertices);

// 5. 创建渲染管线
const pipeline = device.createRenderPipeline({ ... });

// 6. 渲染循环
function render() {
    const cmd = device.createCommandEncoder();
    const pass = cmd.beginRenderPass({ ... });
    pass.setPipeline(pipeline);
    pass.draw(3);
    pass.end();
    device.queue.submit([cmd.finish()]);
    requestAnimationFrame(render);
}
┌──────────────────────────────────────┐
│  ① 检查浏览器 WebGPU 支持           │
│     navigator.gpu ?                 │
└────────────┬─────────────────────────┘
             │ ✅
┌────────────▼─────────────────────────┐
│  ② 请求 GPU 适配器 & 设备           │
│     adapter.requestDevice()         │
└────────────┬─────────────────────────┘
             │
┌────────────▼─────────────────────────┐
│  ③ 配置 Canvas 与 Swap Chain        │
│     ctx.configure({device, format})  │
└────────────┬─────────────────────────┘
             │
┌────────────▼─────────────────────────┐
│  ④ 创建顶点缓冲区 + Uniform缓冲区   │
│     上传三角形顶点数据到 GPU        │
└────────────┬─────────────────────────┘
             │
┌────────────▼─────────────────────────┐
│  ⑤ 编译 WGSL 着色器 → ShaderModule │
│     顶点着色器 + 片元着色器         │
└────────────┬─────────────────────────┘
             │
┌────────────▼─────────────────────────┐
│  ⑥ 构建渲染管线 (Pipeline)          │
│     绑定着色器、顶点布局、混合模式  │
└────────────┬─────────────────────────┘
             │
┌────────────▼─────────────────────────┐
│  ⑦ 每帧: 命令编码器 → 渲染通道     │
│     cmd.beginRenderPass()           │
│     → setPipeline → draw(3) → end   │
│     → queue.submit()                │
└──────────────────────────────────────┘
核心知识点
GPU 设备
WebGPU 直接与物理 GPU 通信,相比 WebGL 减少驱动层开销
WGSL 着色器
WebGPU Shading Language,专为 GPU 设计的类型安全着色语言
渲染管线
固定功能 + 可编程阶段的组合,定义完整的渲染流程
NDC 坐标系
标准化设备坐标,范围 [-1,1],GPU 自动映射到屏幕像素
Uniform 缓冲
从 CPU 向 GPU 传递每一帧变化的数据(如旋转角度)
顶点插值
GPU 自动在三角形内部平滑过渡顶点颜色,产生渐变效果
常见问题 FAQ
什么是 WebGPU?它和 WebGL 有什么不同?

WebGPU 是新一代 Web 图形与计算 API,为现代 GPU 硬件设计。相比 WebGL:

  • 更低开销:直接映射到 Vulkan/Metal/DX12,减少 JavaScript 层的驱动调用
  • 计算着色器:原生支持 GPU 通用计算(GPGPU),WebGL 需通过扩展
  • 显式资源管理:开发者精确控制 GPU 内存与同步,性能更可预测
  • WGSL 语言:类型安全的着色语言,编译时检查错误,避免 GLSL 的运行时问题
哪些浏览器支持 WebGPU?现在可以使用吗?

截至 2024 年,以下浏览器已正式支持 WebGPU:

  • Chrome 113+(Windows/macOS/ChromeOS/Android)
  • Edge 113+(Windows/macOS)
  • Opera 99+
  • Firefox:实验性支持(需开启 dom.webgpu.enabled 标志)
  • Safari:正在积极开发中,预计未来版本支持

提示:需要 HTTPS 或 localhost 安全上下文才能使用 WebGPU。

WGSL 是什么语言?语法难学吗?

WGSL(WebGPU Shading Language) 是专为 WebGPU 设计的着色语言,语法类似 Rust:

  • 使用 fn 定义函数,var 声明可变变量,let 声明不可变变量
  • 类型系统包含 f32vec2vec3vec4mat4x4
  • 使用 @location@binding@group 等注解连接 CPU 端数据
  • 如果有 GLSL/HLSL 经验,上手 WGSL 只需 1-2 小时
这个三角形演示中,"顶点插值"是什么意思?

三个顶点分别被赋予了红、绿、蓝颜色。GPU 在光栅化阶段会自动计算三角形内部每个像素的颜色——通过对三个顶点颜色进行重心坐标插值。这就是为什么你看到三角形内部呈现出平滑的彩虹渐变效果,这是 GPU 硬件免费提供的功能。

为什么我的浏览器显示"WebGPU 不可用"?

常见原因:

  1. 浏览器版本过旧:请更新到 Chrome 113+ 或 Edge 113+
  2. 非安全上下文:WebGPU 需要 HTTPS 或 localhost
  3. GPU 驱动问题:尝试更新显卡驱动到最新版本
  4. 操作系统限制:某些 Linux 发行版可能需要额外配置
  5. 硬件不支持:极旧的 GPU 可能不兼容 WebGPU 所需的功能级别
WebGPU 性能比 WebGL 好多少?

性能提升因场景而异:

  • Draw Call 密集场景:WebGPU 可减少 50-80% 的 CPU 开销
  • 计算任务:原生计算着色器比 WebGL 的 transform feedback 快数倍
  • 带宽利用率:显式缓冲管理可优化数据传输,减少不必要的拷贝
  • 对于简单场景(如单个三角形),差异不明显;复杂 3D 场景中优势显著