webgl高精度浮点纹理需启用oes_texture_half_float等扩展,用uint16array手动转换半精度数据并指定ext.half_float_oes类型上传;单精度需oes_texture_float扩展,且过滤需对应linear扩展支持。

WebGL 处理高精度浮点数纹理,核心不是“用什么 JS 数组”,而是确保 GPU 接收的数据字节布局符合 IEEE 754 半精度(16 位)或单精度(32 位)规范,并配合对应扩展与类型参数正确上传。目前(2026 年中)浏览器仍不支持原生 Float16Array,也不能直接传 Float32Array 当作半精度用——必须显式转换。
必须启用 OES_texture_half_float 扩展
WebGL 默认只支持 UNSIGNED_BYTE(8 位整数)纹理。要使用半精度浮点(HALF_FLOAT_OES)或单精度浮点(FLOAT),需先检测并获取扩展:
const ext = gl.getExtension('OES_texture_half_float');
if (!ext) {
throw new Error('半精度纹理扩展不可用');
}
// 注意:OES_texture_float 才支持 full 32-bit float(部分设备不支持)
没有这个扩展,gl.HALF_FLOAT_OES 是 undefined,调用 texImage2D 会失败。
半精度纹理 ≠ 直接 new Float16Array
Float16Array 在所有主流浏览器中仍是 undefined(ES2025 虽已纳入语法提案,但 V8/SpiderMonkey/JSC 均未完成实现)。你不能写:
// ❌ 报错:ReferenceError: Float16Array is not defined new Float16Array([0.5, 1.0]);
正确做法是:
- 用工具函数将
Float32Array中每个值转为 IEEE 754-2008 半精度的 16 位整数(Uint16); - 再拆成
Uint8Array(2 字节/像素)或保持Uint16Array; - 传入
texImage2D时指定type: ext.HALF_FLOAT_OES。
例如手动编码 [0.5, 1.0]:
// 假设已有 halfFromFloat32() 工具函数(查表或位运算实现) const halfValues = new Uint16Array([ halfFromFloat32(0.5), // → 0x3800 halfFromFloat32(1.0), // → 0x3C00 ]); const halfBytes = new Uint8Array(halfValues.buffer); // [0x00, 0x38, 0x00, 0xC0] gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, // internalFormat(通常与 format 一致) 2, 1, 0, // width, height, border gl.RGBA, // format ext.HALF_FLOAT_OES, // type ← 关键!必须匹配数据字节格式 halfBytes );
单精度浮点纹理(FLOAT)更受限但无需手动编码
若目标设备支持 OES_texture_float 扩展,可直接用 Float32Array + gl.FLOAT:
const extFloat = gl.getExtension('OES_texture_float');
if (extFloat) {
const data = new Float32Array([0.1, 0.2, 0.3, 1.0]); // RGBA
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0,
gl.RGBA, gl.FLOAT, data);
}
⚠️ 注意:gl.FLOAT 要求硬件和驱动完全支持,移动端尤其容易失败;且不支持线性过滤(mipmap/filter),除非同时启用 OES_texture_float_linear。
过滤与采样必须单独配置
即使成功上传半精度/单精度纹理,GPU 默认仍用 NEAREST 采样(块状锯齿)。要启用平滑插值,必须显式设置:
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); // 若需 mipmap,还需 gl.generateMipmap(gl.TEXTURE_2D)
而 OES_texture_half_float_linear 扩展决定 LINEAR 是否对半精度生效——没它,LINEAR 会被静默降级为 NEAREST。
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











