packHalf2x16
将一个 vec2 的两个 32 位浮点分量压缩为 16 位浮点(half float),再打包进同一个无符号整数 uint 中,用于在缓冲区或纹理中紧凑存储两路浮点数据。
核心优势
在不改变逻辑含义的前提下显著节省带宽和存储:只用 32 bit 的 uint 即可携带两个浮点值。由底层 builder 统一选择合适的 float16 打包实现(GLSL/WGSL 等),避免手写复杂的 bit 操作和兼容性逻辑。
常见用途
在自定义 G-Buffer 中用一个 uint 同时存储 roughness 与 metallic 等两个标量属性,减少 MRT 颜色通道或缓冲大小。
在 storage buffer / SSBO 中紧凑存储一对参数(例如强度 + 半径、速度 + 衰减),方便 compute pass 或后处理 pass 读取。
将高精度浮点数据降级为 half 精度用于缓存或传输,在后续 pass 或 CPU 端再用相同约定解包以恢复近似值。
配合 bit 运算与解包流程,构建自定义的打包格式(例如:一个 uint 里用高 16 bit 存时间片、低 16 bit 存某个强度因子)。
如何调整
packHalf2x16 本身只有一个 vec2 输入,没有额外可调参数,调节点主要在于:1)控制输入值的范围与精度:half float 相比 32 位 float 精度更低、动态范围有限,建议优先用于 [0,1] 这样的归一化参数或对精度不敏感的数据;2)必要时在打包前对值做归一化或缩放,例如先把某个 [0,10] 的值除以 10 再打包,解包后再乘回去;3)输出类型是 uint,仅作为“数据容器”,不要直接当作颜色或普通浮点参与混合,而是写入 uint 缓冲或纹理,再在后续阶段用匹配的解包逻辑还原;4)如果你的管线中还有其他打包函数(如 snorm/unorm),确保编码和解码两端使用一致的 encoding 约定。
代码示例
1// 示例:将 roughness 和 metallic 打包成一个 uint,用于紧凑存储
2const rmVec2 = vec2( roughnessNode, metalnessNode );
3
4// 打包为 float16 ×2 存储在一个 uint 中
5const packedRM = packHalf2x16( rmVec2 );
6
7// packedRM 通常会被写入 uint 类型的缓冲区或纹理
8// 这里仅演示如何构造节点,具体写入逻辑视你的 storageObject / 自定义管线而定
9// 例如在另一个 pass 中再配套使用相同的 float16 解包方案还原出 vec2 数据。