Unity自定义定点数LookAt矩阵与官方实现结果不一致问题问询
定点数实现Unity矩阵/四元数的LookAt结果不一致问题
背景
使用C#在Unity中开发基于定点数的自定义Matrix4x4F矩阵类、QuaternionF四元数以满足确定性游戏开发需求,配套编写测试类对比自定义实现与Unity原生Matrix、Quaternion类的计算结果,测试过程中发现LookAt方法计算结果与原生实现不匹配。
现有测试代码
- 数值一致性校验方法
isSame:设置0.001f容差,逐元素对比原生矩阵与定点矩阵的数值差,差值在容差范围内则判定结果一致:
bool isSame(Matrix4x4 a, Matrix4x4F b) { float t = 0.001f; for (int i = 0; i < 16; i++) { if (Mathf.Abs(a[i] - (float) b[i]) > t) return false; } return true; }
- 调试输出方法
show:将一致性校验结果、两个矩阵的具体值、测试项名称输出到Unity调试窗口:
void show(Matrix4x4 a, Matrix4x4F b, String textName) { Debug.Log($"{isSame(a, b)}\n{a} \n{b}" + textName); }
- LookAt测试用例:传入完全一致的参数,分别调用Unity原生
Matrix4x4.LookAt与自定义Matrix4x4F.LookAt,对比输出结果:
show( Matrix4x4.LookAt(new Vector3(3,5,1), new Vector3(76,34,11), new Vector3(10.4323f,13.4343f,2.4398f)), Matrix4x4F.LookAt(new Vector3F(3,5,1), new Vector3F(76,34,11), new Vector3F(10.4323m,13.4343m,2.4398m)), " LOOK AT");
当前自定义实现逻辑
自定义LookAt方法通过TRS矩阵拼接实现:
- 平移参数传入
Vector3F.zero - 旋转参数传入
QuaternionF.LookRotation((to - from).normalized, up.normalized)的计算结果 - 缩放参数传入
Vector3F.one - TRS方法逻辑为分别生成平移矩阵
tr、旋转矩阵ro、缩放矩阵sc,返回三个矩阵按tr * ro * sc顺序相乘的结果
初步排查怀疑问题出在QuaternionF.LookRotation方法,当前该方法实现代码如下:
public static QuaternionF LookRotation(Vector3F forward, Vector3F up) { if(up == forward) { up.Normalize(); Vector3F v = forward + up * -Vector3F.Dot(up, forward); QuaternionF q = QuaternionF.FromToRotation(Vector3F.forward, v); return QuaternionF.FromToRotation(v, forward) * q; } else { return QuaternionF.FromToRotation(Vector3F.forward, forward); } }
配套参考实现包含自定义TRS逻辑、自定义平移矩阵生成逻辑、自定义FromToRotation逻辑三部分。
待解决问题
- 当前LookRotation实现存在哪些逻辑遗漏,导致LookAt计算结果与Unity原生实现不一致?
- 可以通过什么渠道获取Unity官方Matrix LookAt函数的实现源码?
内容的提问来源于stack exchange,提问作者Mert Balkan
相关产品推荐
相关产品推荐

