Visual LabINTERACTIVE LEARNING
阶段 2 · 数据流基础18 分钟

WGSL 基础:类型、结构体、函数与内建值

强类型着色语言的核心语法

通过一个程序化渐变学习标量、向量、结构体、函数、属性和内建坐标。

LEARNING GOALS

先明确本课目标

1

认识 vec/mat/struct

2

理解 @vertex、@fragment 与 @builtin

3

在着色器中编写可复用函数

MENTAL MODEL · 再建立心智模型

WGSL 不是 JavaScript 的 GPU 方言,而是一门静态类型语言;每个输入、输出和资源地址空间都必须明确。

MINIMAL EXAMPLE

@builtin 到底是什么,值从哪里来?

@builtin 是 WGSL 的系统接口属性。作为输入时,它让着色器读取 GPU/管线自动生成的值;作为输出时,它把控制信息交回固定功能管线。名称、着色阶段、方向和类型必须匹配规范。

最小例子wgsl
struct VertexOut {
  // 顶点着色器必须交给光栅化器的裁剪空间位置
  @builtin(position) clipPosition: vec4f,
  @location(0) color: vec3f,
}

@vertex
fn vs(@builtin(vertex_index) id: u32) -> VertexOut {
  var out: VertexOut;
  out.clipPosition = vec4f(f32(id) - 1.0, 0.0, 0.0, 1.0);
  out.color = vec3f(1.0, 0.5, 0.2);
  return out;
}

@compute @workgroup_size(64)
fn cs(@builtin(global_invocation_id) id: vec3u) {
  // id 是整个 dispatch 网格中的三维坐标
}
  1. vertex_index:顶点输入 由 draw/drawIndexed 生成,类型是 u32;常用于索引数组或程序化几何。
  2. position:顶点输出 类型是 vec4f,交给裁剪、透视除法和光栅化阶段;它不是普通自定义 varying。
  3. position:片元输入 同名 builtin 在片元阶段表示当前片元的 framebuffer 坐标,方向和含义已改变。
  4. global_invocation_id:计算输入 类型是 vec3u,表示当前 invocation 在整个 dispatch 网格中的坐标。

@builtin 不是“声明一个全局变量”,而是在入口函数边界上声明着色器与 GPU 固定管线之间的系统数据契约。

本课概念
OPTIONAL · 按需查阅完整术语表与概念边界

遇到陌生术语时再展开,不打断主线实验。

展开⌄
LIVE EXPERIMENT · 先获得反馈

边改边运行

浏览器加载后会激活代码编辑器、独立运行环境与实时输出。

本课挑战

写一个 hash 函数,在片元着色器里生成稳定噪点。

DEEP DIVE · 实验之后

回到原理,解释刚才发生了什么

先用结果建立反馈,再按运行流程、核心原理和知识关系逐层深入。

CORE IDEA

核心讲解

01

强类型带来的可移植性

着色器必须在不同 GPU 后端上保持一致。明确类型与布局能让浏览器在提交前完成严格验证。

02

入口函数与接口

@vertex、@fragment、@compute 标记入口;@location 连接用户数据,@builtin 连接 WebGPU 定义的系统值。

OPTIONAL · 迁移时查阅WebGPU 与 WebGL2 对照

主线实验完成后,再用完整映射处理跨平台或跨 API 迁移。

展开⌄
API COMPARISON

GLSL ES 与 WGSL 都描述着色器计算,但 WGSL 的类型、接口和资源地址空间更显式。

WebGL

GLSL ES 使用 in/out、uniform 与隐式数值转换规则,经编译和链接形成阶段接口。

WebGPU

WGSL 用属性、结构体和地址空间声明入口接口,并在模块/管线创建时验证。

GLSL 不能机械替换关键字得到 WGSL;先重画入口参数、返回值和资源地址空间。