wgpu-matrix中mat4.invert返回空数组致unproject输出NaN问题
问题分析与解决方案
核心问题拆解
- 执行
let projectionMatrix = [...object.projectionMatrix]后,原object.projectionMatrix被填充为NaN mat4.invert(outp, object.projectionMatrix)和mat4.invert(outv, modelViewProjectionMatrix)返回空数组,导致unproject输出全NaN- 调换
mat4.invert参数顺序后输出异常
针对性解决步骤
1. 修复解构赋值污染原矩阵的问题
wgpu-matrix的矩阵对象可能带有内部逻辑,直接解构数组会触发意外副作用。换用以下两种安全的复制方式:
- 用库内置的复制方法:
let projectionMatrix = mat4.copy(object.projectionMatrix); - 用原生数组方法复制(需确保原矩阵是合法16元素数组):
let projectionMatrix = Array.from(object.projectionMatrix);
2. 解决mat4.invert返回空数组的问题
空数组返回通常意味着输入矩阵不可逆(行列式为0),按以下步骤排查修复:
- 提前校验矩阵合法性:确认
object.projectionMatrix和modelViewProjectionMatrix是完整的16元素数组,无NaN/Infinity值,且投影矩阵的近裁剪面未设为0(这会直接导致矩阵奇异) - 严格遵循API调用规则:
mat4.invert的返回值是布尔值(表示反转是否成功),不是矩阵本身。必须先初始化输出矩阵,再传入函数:const outp = mat4.create(); // 先创建空的输出矩阵容器 const invertSuccess = mat4.invert(outp, object.projectionMatrix); if (!invertSuccess) { console.error('投影矩阵不可逆:', object.projectionMatrix); } - 检查矩阵计算顺序:
modelViewProjectionMatrix必须是projection * view * model的左乘顺序(wgpu-matrix采用左乘规则,和部分其他矩阵库逻辑相反)
3. 修正参数顺序错误的问题
wgpu-matrix的mat4.invert签名是mat4.invert(out: Mat4, a: Mat4): boolean,第一个参数是输出矩阵,第二个是待反转的输入矩阵。调换顺序会直接用输入矩阵覆盖输出容器,必然导致异常,必须严格遵循输出在前,输入在后的调用顺序。
额外排查建议
- 在调用反转函数前,打印
object.projectionMatrix和modelViewProjectionMatrix的具体值,确认无异常数据 - 同步检查raycast流程的矩阵更新时机:确保
unproject调用前,投影、视图、模型矩阵已经完成正确计算 - 对比原项目的raycast实现,重点核对矩阵创建、复制、反转步骤的细节差异,尤其注意不同矩阵库的API逻辑区别
内容的提问来源于stack exchange,提问作者Nikola Lukic
相关产品推荐
相关产品推荐

