Unity3D中使用Matrix4x4实现透视投影时模型扭曲问题排查
Unity透视投影转换时模型扭曲的问题解决
问题背景
需将Vector3类型的3D点转换为2D点,模拟相机透视投影效果,已知条件包括3D点集、相机位置、朝向及FOV。
尝试代码
void Update() { Matrix4x4 proj = Matrix4x4.LookAt(FakeCam.transform.position, Vector3.zero, FakeCam.transform.up) * Matrix4x4.Perspective(fov, aspect, zNear, zFar); for (int i=0; i<8; i++) { var point = proj.MultiplyPoint(Points[i]); Dots.SetPosition(i, new Vector3(point.x, 0, point.z)); } Dots.Draw(transform.localToWorldMatrix); }
问题现象
单独使用LookAt矩阵时,模型以正交投影方式正常显示;组合Perspective矩阵后,模型中间出现扭曲,立方体背面呈现180度旋转效果。
解决方案及原因
核心问题
- 矩阵乘法顺序错误:Unity采用列主序矩阵,变换应用顺序为从右到左,正确的矩阵组合应该是「投影矩阵 × 视图矩阵」,而非原代码中的「视图矩阵 × 投影矩阵」。
- 未处理齐次坐标:透视投影后得到的是齐次坐标,必须通过
w分量做除法,才能得到正确的标准化设备坐标(NDC),否则会因透视缩放因子错误导致扭曲。
修正后的代码
void Update() { // 分别创建视图矩阵与投影矩阵 Matrix4x4 viewMatrix = Matrix4x4.LookAt(FakeCam.transform.position, Vector3.zero, FakeCam.transform.up); Matrix4x4 projMatrix = Matrix4x4.Perspective(fov, aspect, zNear, zFar); // 正确的矩阵组合:投影矩阵 × 视图矩阵 Matrix4x4 viewProjMatrix = projMatrix * viewMatrix; for (int i=0; i<8; i++) { // 获取齐次坐标 Vector4 homogenousPoint = viewProjMatrix.MultiplyPoint(Points[i]); // 执行齐次除法,得到标准化设备坐标 Vector3 ndcPoint = new Vector3( homogenousPoint.x / homogenousPoint.w, homogenousPoint.y / homogenousPoint.w, homogenousPoint.z / homogenousPoint.w ); // 按原逻辑设置点位置 Dots.SetPosition(i, new Vector3(ndcPoint.x, 0, ndcPoint.z)); } Dots.Draw(transform.localToWorldMatrix); }
内容的提问来源于stack exchange,提问作者Innovine
相关产品推荐
相关产品推荐

