WebGPU 规范新增符号归一化顶点格式
原文作者:wangra-google
原始链接:gpuweb/gpuweb@da251f9
提交摘要
该提交向 WebGPU 规范及 WebIDL 定义中加入 snorm10-10-10-2 顶点格式,并修复 #6292。变更仅涉及 spec/index.bs,总新增 7 行:
- 在
enum GPUVertexFormat中加入"snorm10-10-10-2"; - 在顶点格式表中加入对应行:
signed normalized/ 4 个分量 / 4 字节 /vec4<f32>。
核心变更代码
1. WebIDL 枚举新增
@@ -9921,6 +9921,7 @@ enum GPUVertexFormat {
"sint32x4",
"unorm10-10-10-2",
"unorm8x4-bgra",
+ "snorm10-10-10-2",
};
2. 顶点格式表新增行
@@ -10180,6 +10181,12 @@ enum GPUVertexFormat {
<td>4
<td>4
<td><code>vec4<f32></code>
+ <tr>
+ <td><dfn>"snorm10-10-10-2"</dfn>
+ <td>signed normalized
+ <td>4
+ <td>4
+ <td><code>vec4<f32></code>
</tbody>
</table>
为什么需要 snorm10-10-10-2?
10-10-10-2 是一种经典的紧凑顶点数据布局:三个分量各占 10 bit,第四分量占 2 bit,合计 32 bit(4 字节)。此前 WebGPU 已有 unorm10-10-10-2,即无符号归一化版本,分量映射到 [0, 1];本次加入的 snorm10-10-10-2 则是有符号归一化版本,能够表示负值,更适合存储法线、切线等有向向量。
在着色器侧,该格式会被解码为 vec4<f32>,由 GPU 硬件完成从压缩整数到浮点数的转换,无需手动解包。
3 个核心优化要点
1. 顶点数据压缩,降低显存带宽
float32x4 通常需要 16 字节存储 4 个浮点分量;snorm10-10-10-2 仅用 4 字节,节省 75% 的顶点属性空间。对于高顶点数量场景(如复杂网格、粒子系统),显存占用和顶点抓取带宽会显著下降,间接提升渲染性能。
2. 有符号归一化适配有向矢量
与 unorm10-10-10-2 的 [0,1] 范围不同,snorm 能表示负值。这使得它更适合存储归一化的法线、切线等需要保留符号的数据,避免无符号格式带来的偏置与精度浪费。三个 10 bit 分量对大多数渲染需求已经足够,第四分量仅 2 bit,适合存放低精度辅助数据。
3. 规范与 WebIDL 同步,保证跨实现一致性
该提交同时在 GPUVertexFormat 枚举和顶点格式表中声明新格式,确保了 WebGPU 规范、WebIDL 类型定义、浏览器实现与验证层的一致性。开发者可以直接使用字符串 "snorm10-10-10-2" 配置顶点布局,并在 WGSL 中以 vec4<f32> 接收解包结果,避免跨平台行为差异。
GLSL / WebGL 术语核对
| 英文术语 | 中文译法 | 备注 |
|---|---|---|
vertex format | 顶点格式 | WebGPU / WebGL 中用于描述顶点属性布局 |
signed normalized | 有符号归一化 | 缩写 snorm,将整数值映射到有符号浮点范围 |
unsigned normalized | 无符号归一化 | 缩写 unorm,将整数值映射到 [0,1] |
GPUVertexFormat | GPU 顶点格式枚举 | WebGPU WebIDL 中的枚举类型 |
WebIDL | Web 接口定义语言 | 用于定义浏览器 API 接口 |
vec4<f32> | 浮点 4 分量向量 | WGSL 类型;GLSL 对应 vec4,但 WebGPU 使用 WGSL 而非 GLSL |
vertex buffer | 顶点缓冲区 | GPU 存储顶点属性的缓冲资源 |
说明:WebGPU 的着色语言是 WGSL,而不是 GLSL/WebGL 的 GLSL。但 GLSL 中
vec4与 WGSL 的vec4<f32>在概念上对应;顶点格式、归一化等概念在 WebGL 与 WebGPU 之间是相通的。
