简体   繁体   English

矩阵类乘法产生错误的结果

[英]Matrix class multiplication yielding incorrect results

I have created a basic Math Library for an assignment, involving a Matrix3 and Matrix4 class, alongside some others. 我为作业创建了一个基本的数学库,其中涉及Matrix3和Matrix4类以及其他一些类。 For OpenGL, to project a cube onto the screen, I have created a lookAt function and a Perspective function for the Projection * View * Model algorithm that yields a proper view for the scene. 对于OpenGL,为了将多维数据集投影到屏幕上,我为Projection * View * Model算法创建了lookAt函数和Perspective函数,该算法可为场景生成适当的视图。 They are designed to be replacements for the corresponding functions in the GLM library/other libraries, since they have to interface with my Matrix classes in the future. 它们被设计为替代GLM库/其他库中的相应功能,因为将来它们必须与我的Matrix类交互。

The lookAt function yields correct results, the Projection function is yielding close results, with some temporary manual tweaking to get it to provide the same results. lookAt函数产生正确的结果,而Projection函数产生接近的结果,并进行一些临时的手动调整以使其提供相同的结果。 However, when I multiply them together with the Projection * View (lookat) * Model (an Identity matrix), my library yield completely different results to GLM's (the MVP Matrix4). 但是,当我将它们与Projection * View(外观)* Model(身份矩阵)相乘时,我的库产生的结果与GLM的结果(MVP Matrix4)完全不同。 Mine match up with a graphics calculator, the GLM one doesn't. 我的与图形计算器匹配,而GLM没有。 The GLM one actually displays the cube on the screen correctly, my one looks as if the cube has imploded. GLM实际上在屏幕上正确显示了多维数据集,而我的那个看起来好像多维数据集已爆裂。 The Matrices themselves have minimal to no similarity. 矩阵本身几乎没有相似性。

GLM Library GLM库

        // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
    glm::mat4 ProjectionGLM = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
    // Camera matrix
    glm::mat4 ViewGLM = glm::lookAt(
        glm::vec3(4, 3, 3), // Camera is at (4,3,3), in World Space
        glm::vec3(0, 0, 0), // and looks at the origin
        glm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down)
        );
    // Model matrix : an identity matrix (model will be at the origin)
    glm::mat4 ModelGLM = glm::mat4(1.0f);  // Changes for each model !
                                        // Our ModelViewProjection : multiplication of our 3 matrices
    glm::mat4 MVP = ProjectionGLM * ViewGLM * ModelGLM; // Remember, matrix multiplication is the other way around
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

Output Matricies (MVP Matrix4) 输出矩阵(MVP矩阵4)

Custom Library 定制图书馆

    Vector3 vectornew1(4, 3, 3);
    Vector3 vectornew2(0, 0, 0); 
    Vector3 vectornew3(0, 1, 0);

    // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
    Matrix4 Projection = Matrix4::Perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
    Projection = Matrix4::Transpose(Projection);
    // Camera matrix
    Matrix4 View = Matrix4::lookAt(
        vectornew1, // Camera is at (4,3,3), in World Space
        vectornew2, // and looks at the origin
        vectornew3  // Head is up (set to 0,-1,0 to look upside-down)
        );
    // Model matrix : an identity matrix (model will be at the origin)
    Matrix4 Model = Matrix4::Identity();  // Changes for each model !
                                        // Our ModelViewProjection : multiplication of our 3 matrices
    Matrix4 MVP = Projection * View * Model; // Remember, matrix multiplication is the other way around
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP.data[0][0]);

Custom Matrix4 Multiplication code: 自定义Matrix4乘法代码:

temp.data[0][0] = this->data[0][0] * Other.data[0][0] + this->data[0][1] * Other.data[1][0] + this->data[0][2] * Other.data[2][0] + this->data[0][3] * Other.data[3][0];
temp.data[0][1] = this->data[0][0] * Other.data[0][1] + this->data[0][1] * Other.data[1][1] + this->data[0][2] * Other.data[2][1] + this->data[0][3] * Other.data[3][1];
temp.data[0][2] = this->data[0][0] * Other.data[0][2] + this->data[0][1] * Other.data[1][2] + this->data[0][2] * Other.data[2][2] + this->data[0][3] * Other.data[3][2];
temp.data[0][3] = this->data[0][0] * Other.data[0][3] + this->data[0][1] * Other.data[1][3] + this->data[0][2] * Other.data[2][3] + this->data[0][3] * Other.data[3][3];

temp.data[1][0] = this->data[1][0] * Other.data[0][0] + this->data[1][1] * Other.data[1][0] + this->data[1][2] * Other.data[2][0] + this->data[1][3] * Other.data[3][0];
temp.data[1][1] = this->data[1][0] * Other.data[0][1] + this->data[1][1] * Other.data[1][1] + this->data[1][2] * Other.data[2][1] + this->data[1][3] * Other.data[3][1];
temp.data[1][2] = this->data[1][0] * Other.data[0][2] + this->data[1][1] * Other.data[1][2] + this->data[1][2] * Other.data[2][2] + this->data[1][3] * Other.data[3][2];
temp.data[1][3] = this->data[1][0] * Other.data[0][3] + this->data[1][1] * Other.data[1][3] + this->data[1][2] * Other.data[2][3] + this->data[1][3] * Other.data[3][3];

temp.data[2][0] = this->data[2][0] * Other.data[0][0] + this->data[2][1] * Other.data[1][0] + this->data[2][2] * Other.data[2][0] + this->data[2][3] * Other.data[3][0];
temp.data[2][1] = this->data[2][0] * Other.data[0][1] + this->data[2][1] * Other.data[1][1] + this->data[2][2] * Other.data[2][1] + this->data[2][3] * Other.data[3][1];
temp.data[2][2] = this->data[2][0] * Other.data[0][2] + this->data[2][1] * Other.data[1][2] + this->data[2][2] * Other.data[2][2] + this->data[2][3] * Other.data[3][2];
temp.data[2][3] = this->data[2][0] * Other.data[0][3] + this->data[2][1] * Other.data[1][3] + this->data[2][2] * Other.data[2][3] + this->data[2][3] * Other.data[3][3];

temp.data[3][0] = this->data[3][0] * Other.data[0][0] + this->data[3][1] * Other.data[1][0] + this->data[3][2] * Other.data[2][0] + this->data[3][3] * Other.data[3][0];
temp.data[3][1] = this->data[3][0] * Other.data[0][1] + this->data[3][1] * Other.data[1][1] + this->data[3][2] * Other.data[2][1] + this->data[3][3] * Other.data[3][1];
temp.data[3][2] = this->data[3][0] * Other.data[0][2] + this->data[3][1] * Other.data[1][2] + this->data[3][2] * Other.data[2][2] + this->data[3][3] * Other.data[3][2];
temp.data[3][3] = this->data[3][0] * Other.data[0][3] + this->data[3][1] * Other.data[1][3] + this->data[3][2] * Other.data[2][3] + this->data[3][3] * Other.data[3][3];

What could GLM be doing with the Matrix multiplication to yield vastly different results? GLM如何对矩阵乘法进行处理以产生截然不同的结果? My method matched up with graphics calculators and yields correct results with identity matrices. 我的方法与图形计算器匹配,并通过身份矩阵产生正确的结果。

I tried your multiply in my engine (also based on glm, or at least tested against it) and the results were correct when I swapped over this and Other. 我在引擎中尝试了您的乘法(也基于glm,或至少针对它进行了测试),当我将其替换为Other和Other时,结果是正确的。 So this should be correct: 因此,这应该是正确的:

temp.data[0][0] = Other.data[0][0] * this->data[0][0] + Other.data[0][1] * this->data[1][0] + Other.data[0][2] * this->data[2][0] + Other.data[0][3] * this->data[3][0];
temp.data[0][1] = Other.data[0][0] * this->data[0][1] + Other.data[0][1] * this->data[1][1] + Other.data[0][2] * this->data[2][1] + Other.data[0][3] * this->data[3][1];
temp.data[0][2] = Other.data[0][0] * this->data[0][2] + Other.data[0][1] * this->data[1][2] + Other.data[0][2] * this->data[2][2] + Other.data[0][3] * this->data[3][2];
temp.data[0][3] = Other.data[0][0] * this->data[0][3] + Other.data[0][1] * this->data[1][3] + Other.data[0][2] * this->data[2][3] + Other.data[0][3] * this->data[3][3];
temp.data[1][0] = Other.data[1][0] * this->data[0][0] + Other.data[1][1] * this->data[1][0] + Other.data[1][2] * this->data[2][0] + Other.data[1][3] * this->data[3][0];
temp.data[1][1] = Other.data[1][0] * this->data[0][1] + Other.data[1][1] * this->data[1][1] + Other.data[1][2] * this->data[2][1] + Other.data[1][3] * this->data[3][1];
temp.data[1][2] = Other.data[1][0] * this->data[0][2] + Other.data[1][1] * this->data[1][2] + Other.data[1][2] * this->data[2][2] + Other.data[1][3] * this->data[3][2];
temp.data[1][3] = Other.data[1][0] * this->data[0][3] + Other.data[1][1] * this->data[1][3] + Other.data[1][2] * this->data[2][3] + Other.data[1][3] * this->data[3][3];
temp.data[2][0] = Other.data[2][0] * this->data[0][0] + Other.data[2][1] * this->data[1][0] + Other.data[2][2] * this->data[2][0] + Other.data[2][3] * this->data[3][0];
temp.data[2][1] = Other.data[2][0] * this->data[0][1] + Other.data[2][1] * this->data[1][1] + Other.data[2][2] * this->data[2][1] + Other.data[2][3] * this->data[3][1];
temp.data[2][2] = Other.data[2][0] * this->data[0][2] + Other.data[2][1] * this->data[1][2] + Other.data[2][2] * this->data[2][2] + Other.data[2][3] * this->data[3][2];
temp.data[2][3] = Other.data[2][0] * this->data[0][3] + Other.data[2][1] * this->data[1][3] + Other.data[2][2] * this->data[2][3] + Other.data[2][3] * this->data[3][3];
temp.data[3][0] = Other.data[3][0] * this->data[0][0] + Other.data[3][1] * this->data[1][0] + Other.data[3][2] * this->data[2][0] + Other.data[3][3] * this->data[3][0];
temp.data[3][1] = Other.data[3][0] * this->data[0][1] + Other.data[3][1] * this->data[1][1] + Other.data[3][2] * this->data[2][1] + Other.data[3][3] * this->data[3][1];
temp.data[3][2] = Other.data[3][0] * this->data[0][2] + Other.data[3][1] * this->data[1][2] + Other.data[3][2] * this->data[2][2] + Other.data[3][3] * this->data[3][2];
temp.data[3][3] = Other.data[3][0] * this->data[0][3] + Other.data[3][1] * this->data[1][3] + Other.data[3][2] * this->data[2][3] + Other.data[3][3] * this->data[3][3];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM