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&lt;f32&gt;</code>
+        <tr>
+            <td><dfn>"snorm10-10-10-2"</dfn>
+            <td>signed normalized
+            <td>4
+            <td>4
+            <td><code>vec4&lt;f32&gt;</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]
GPUVertexFormatGPU 顶点格式枚举WebGPU WebIDL 中的枚举类型
WebIDLWeb 接口定义语言用于定义浏览器 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 之间是相通的。