Float16Array并非标准Web API,截至2026年5月浏览器仍不支持原生构造;WebGL上传半精度纹理需手动将float32转为IEEE 754-2008半精度字节,用Uint8Array或Uint16Array配合OES_texture_half_float扩展调用texImage2D。

Float16Array 不是标准 Web API,WebGL 中无法直接使用它上传半精度纹理数据。 你看到的 Float16Array 名称容易误导——截至 2026 年 5 月,JavaScript 运行时(包括所有主流浏览器)仍不提供原生 Float16Array 构造函数。ES2025 虽然正式引入了语言级 float16 支持(如 Number.float16、Float16Array 语法提案落地),但实际引擎实现尚未完成,typeof Float16Array 仍是 "undefined"。
WebGL 中加载半精度纹理必须用 Float32Array + 扩展检测
WebGL 本身不解析或转换数据类型;它只按你指定的 type 参数解释内存字节。要上传半精度浮点纹理,关键不是“用什么 JS 数组”,而是:确保传入 gl.texImage2D 的 type 是 gl.HALF_FLOAT_OES,且数据内存布局符合 IEEE 754-2008 半精度格式。
这意味着:
- 你得自己把 float32 值转成 16 位半精度字节(两个
Uint8组成一个Uint16),再塞进Uint8Array或Uint16Array - 不能依赖
new Float16Array([...])—— 它会报ReferenceError: Float16Array is not defined - 必须先获取
OES_texture_half_float扩展对象,否则gl.HALF_FLOAT_OES是 undefined
示例片段:
const ext = gl.getExtension('OES_texture_half_float');
if (!ext) {
throw new Error('OES_texture_half_float not supported');
}
// 手动将 [0.5, 1.0, -0.25] 转为 half-float bytes(需查表或用工具函数)
const halfBytes = new Uint8Array([0x00, 0x38, 0x00, 0x3C, 0x00, 0xB8]); // 示例编码
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 3, 0, gl.RGBA, ext.HALF_FLOAT_OES, halfBytes);
OES_texture_half_float_linear 决定采样是否平滑
即使你成功上传了半精度纹理,如果没启用线性过滤,GPU 默认用最近邻(gl.NEAREST)采样,会出现明显块状锯齿——尤其在缩放或旋转时。
要启用双线性插值,必须:
- 额外检测
OES_texture_half_float_linear扩展 - 设置纹理参数为
gl.LINEAR(而非gl.NEAREST) - 注意:仅当两个扩展都存在时,
gl.LINEAR+ext.HALF_FLOAT_OES才真正生效;否则 WebGL 会静默降级为 nearest,且不报错
常见错误现象:gl.generateMipmap() 失败、gl.getError() 返回 gl.INVALID_OPERATION,往往就是漏了 linear 扩展检测。
EXT_color_buffer_half_float 用于 HDR 渲染输出
如果你的目标是 HDR 后处理(比如 bloom、tonemapping),光有半精度纹理不够——你还得让帧缓冲区能存半精度颜色值。
这时需要 EXT_color_buffer_half_float 扩展:
- 它提供
gl.RGBA16F和gl.RGB16F等内部格式,用于gl.renderbufferStorage() - 但注意:不是所有支持
OES_texture_half_float的设备都支持该扩展(尤其移动端) - 调用
gl.checkFramebufferStatus(gl.FRAMEBUFFER)必须返回gl.FRAMEBUFFER_COMPLETE,否则渲染目标无效
性能影响:半精度颜色缓冲比 RGBA8 多占一倍显存带宽,但在中高端 GPU 上通常比全精度 RGBA32F 更快,适合平衡精度与性能。
真正容易被忽略的是:**半精度浮点数的动态范围和精度限制**。它的指数只有 5 位,能表示的最大正数约 65504,最小正规格化数约 6.1e-5;远小于 Float32Array。一旦你在着色器里做累加或除法,极易下溢(变成 0)或上溢(变成 inf)。这不是兼容性问题,而是数值稳定性问题——得靠算法调整,不是换数组类型就能解决。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











