packUnorm2x16
将 vec2 中两个归一化浮点分量映射到 16 位无符号整数(UNORM16),再打包到同一个 32 位 uint 中。每个分量的量化规则为 round(clamp(c, 0, 1) * 65535.0)。
核心优势
专门针对 [0,1] 区间的参数做高效定点量化:相比直接用 float32 存储,两路归一化数据可以压缩成一个 uint,既节省显存和带宽,又保持线性语义(UNORM),适合 G-Buffer、存储缓冲、贴图编码等场景。
常见用途
在延迟渲染或自定义 G-Buffer 中,将两个 [0,1] 物理参数(例如 roughness 和 metallic)打包为一个 uint 以减少颜色通道或缓冲区大小。
在 storage buffer / SSBO 中紧凑存储归一化参数对(如强度 + 权重、遮罩 A + 遮罩 B),供后续 compute 或后处理 pass 解码使用。
对本身已经归一化的数据(如 0–1 权重、mask、normalized UV 偏移等)进行整数量化,以便在网络传输或缓存时降低数据量。
配合自定义解码逻辑,构建简单可控的“0–1 定点格式”:例如用高 16 bit 存储某个混合权重,低 16 bit 存储另一条 mask。
如何调整
packUnorm2x16 本身没有可调参数,关键在于输入 rm 的设计:1)请确保输入值大致落在 [0,1] 范围内,超出部分会被 clamp,导致信息丢失;2)对于大于 1 或小于 0 的物理量,可以先做归一化(缩放 / 偏移)后再打包,在解码端做逆变换;3)UNORM16 提供 0..65535 的离散刻度,足以表达大多数 0–1 参数,但仍然存在量化误差,可根据需求决定是否使用;4)输出是 uint,仅作为“打包容器”,不要直接用于颜色/光照计算,应写入对应的 uint 缓冲或纹理,再在其他阶段按相同 UNORM 约定解包。
代码示例
1// 将两个归一化参数(例如 roughness 和 metallic)打包为一个 uint
2const rm = vec2( roughnessNode, metalnessNode );
3
4// 使用 UNORM16 规则打包到 32 位无符号整数中
5const packedRM = packUnorm2x16( rm );
6
7// packedRM 适合写入 uint 类型的缓冲区或纹理中
8// 在后续 pass 中再用匹配的 UNORM2x16 解包逻辑,还原回近似的 [0,1] 值。