Search code examples
matrixvectorunity-game-engine3d

(Unity3D) Difference between MultiplyPoint and MultiplyPoint3x4


Unity docs as unhelpful as usual.

MultiplyPoint3x4 is simply a transformation matrix - which i've tested using dot product manually and had the same output.

However I'm very confused over what differs between standard matrix multiplication in MultiplyPoint3x4and that used by MultiplyPoint. I'm told the source code licence is available, but I only need one function.

Any advice welcome.


Solution

  • I was curious about this as well. What steps of a matrix multiplication could Unity possibly be skipping? The optimization is possible because a scaling and rotation needs only a 3x3 matrix and another vector for the translation. So part of the full 4x4 matrix is unused and can be ignored in the multiplication.

    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;
    }
    

    This is a full 4x4 * 4x1 matrix multiplication, and then scaling the x y z of the result by the w of the result.

    general multiply pointformula

    This is necessary for projective transformations, but not for rotation and scaling.

    This is why they have the faster 3x4 version. It assumes the w component of each column is 0 and skips that bottom row of multiplication and scaling, because the resulting w is always 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;
    }
    

    This function is equivalent to multiplying matrices which look like:

    fast multiply point formula

    The source code was referenced from this page: https://github.com/jameslinden/unity-decompiled/blob/master/UnityEngine/UnityEngine/Matrix4x4.cs