(Unity3D) MultiplyPoint 和 MultiplyPoint3x4 之间的区别

问题描述 投票:0回答:3

Unity 文档和往常一样没有帮助。

MultiplyPoint3x4 只是一个变换矩阵 - 我已经使用点积手动进行了测试并具有相同的输出。

但是,我对 MultiplyPoint3x4 中的标准矩阵乘法与 MultiplyPoint 使用的标准矩阵乘法之间的区别感到非常困惑。 我被告知源代码许可证可用,但我只需要一个功能。

欢迎任何建议。

matrix vector unity-game-engine 3d
3个回答
6
投票

我也很好奇这个问题。 Unity 可能会跳过矩阵乘法的哪些步骤?优化是可能的,因为缩放和旋转只需要一个 3x3 矩阵和另一个用于平移的向量。因此,完整 4x4 矩阵的一部分未使用,可以在乘法中忽略。

public Vector3 MultiplyPoint(Vector3 v)
{
    Vector3 vector3;
    vector3.x =  ( m00 *  v.x +  m01 *  v.y +  m02 *  v.z) + m03;
    vector3.y =  ( m10 *  v.x +  m11 *  v.y +  m12 *  v.z) + m13;
    vector3.z =  ( m20 *  v.x +  m21 *  v.y +  m22 *  v.z) + m23;
    float num = 1f / ( ( m30 *  v.x +  m31 *  v.y +  m32 *  v.z) + m33); // this is 1/1=1 when m30, m31, m32 = 0 and m33 = 1
    vector3.x *= num; // so then multiplying by 1 is pointless..
    vector3.y *= num;
    vector3.z *= num;
    return vector3;
}

这是一个完整的 4x4 * 4x1 矩阵乘法,然后将结果的 x y z 按结果的 w 缩放。

这对于投影变换是必要的,但对于旋转和缩放不是必需的。

这就是为什么他们有更快的 3x4 版本。它假设每列的 w 分量为 0,并跳过底行的乘法和缩放,因为结果 w 始终为 1。

public Vector3 MultiplyPoint3x4(Vector3 v)
{
    Vector3 vector3;
    vector3.x =  ( m00 *  v.x +  m01 *  v.y +  m02 *  v.z) + m03;
    vector3.y =  ( m10 *  v.x +  m11 *  v.y +  m12 *  v.z) + m13;
    vector3.z =  ( m20 *  v.x +  m21 *  v.y +  m22 *  v.z) + m23;
    return vector3;
}

这个函数相当于矩阵相乘,如下所示:

源代码从此页面引用:https://github.com/jameslinden/unity-decompiled/blob/master/UnityEngine/UnityEngine/Matrix4x4.cs


0
投票

正如文档中提到的,考虑到矩阵是常规的 3D Xform,MultiplyPoint3x4 基本上是 MultiplyPoint 的更快版本。至于它到底如何更快,正如您可能已经猜到的那样,除非您有权访问源代码,否则相信开发人员自己所说的话才符合您的最大利益。您还可以尝试在 Unity 论坛上发帖,以便更好地让模组/开发人员注意到您的兴趣。

我一直盲目地相信他们。 如果我有证据的话,我就会责怪他们。这是一个简单的流程;)

希望有帮助!


-1
投票

找到了! - 请注意,您不需要统一源代码许可证!

    public Vector3 MultiplyPoint( Vector3 v )
    {
        Vector3 result;
        result.x = this.m00 * v.x + this.m01 * v.y + this.m02 * v.z + this.m03;
        result.y = this.m10 * v.x + this.m11 * v.y + this.m12 * v.z + this.m13;
        result.z = this.m20 * v.x + this.m21 * v.y + this.m22 * v.z + this.m23;
        float num = this.m30 * v.x + this.m31 * v.y + this.m32 * v.z + this.m33;
        num = 1 / num;
        result.x *= num;
        result.y *= num;
        result.z *= num;
        return result;
    }
© www.soinside.com 2019 - 2024. All rights reserved.