You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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度旋转效果。

解决方案及原因

核心问题

  1. 矩阵乘法顺序错误:Unity采用列主序矩阵,变换应用顺序为从右到左,正确的矩阵组合应该是「投影矩阵 × 视图矩阵」,而非原代码中的「视图矩阵 × 投影矩阵」。
  2. 未处理齐次坐标:透视投影后得到的是齐次坐标,必须通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 09:55:15