为什么 VERTEX 着色器中的矩阵乘法不能正常工作?

Why wont matrix multiplication in VERTEX shader work properly?

我在 Visual Studio 2017 年开始了解 OpenGL。 按照 www.learnopengl.com 教程并通过了纹理检查点,转换是目前的主要问题。

我使用预先获取的统一位置 ID 将我的模型、视图和透视矩阵发送到着色器,但是当将矩阵和 vec4(vertex, 1.0f) 向量相乘时,window 仍然填充了 clearcolor。

如果我只将 vec4(vertex, 1.0f) 与模型矩阵相乘,则对象会被绘制 (cube_flat.obj) 但会分布在整个视口中,因为没有考虑透视和视图。这是错误的,但有效。

代码: main.cpp

int main()
{
    std::cout << "Application starting...\n" << std::endl;
    glm::ivec2 resolution = glm::ivec2(1280, 720);
    Window* window = new Window(resolution.x, resolution.y);

    SimpleMaterial* simpleMaterial = new SimpleMaterial();

    glFrontFace(GL_CCW);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    glm::mat4 projection = glm::perspective(glm::radians(60.0f), (float)resolution.x / (float)resolution.y, 0.1f, 1000.0f);
    glm::mat4 view = glm::inverse(glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -10.0f)));
    glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f));
    Mesh* mesh = Mesh::load("cube_flat.obj");

    // Render loop
    while (!window->shouldClose())
    {
        // Input
        window->processInput();

        // Rendering commands
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // Tell OpenGL to use this Shader Program
        // Send attribute and uniform data to shader
        // Stream vertex, normal and uv data to shader
        simpleMaterial->render(projection, view, model, mesh);

        // Check & Call events
        window->poolEvents();
        // Swap buffers
        window->swapBuffers();
    }
    // Delete GLFW data
    delete window;
    return 0;
}

SimpleMaterial.cpp
SimpleMaterial::SimpleMaterial() : Material("simple")
{
    _vertex = _shader->getAttrib("vertex");
    _normal = _shader->getAttrib("normal");
    _uv = _shader->getAttrib("uv");

    _model = _shader->getUniform("model");
    _view = _shader->getUniform("view");
    _projection = _shader->getUniform("projection");
}

SimpleMaterial::~SimpleMaterial()
{
}

void SimpleMaterial::render(glm::mat4 pProjection, glm::mat4 pView, glm::mat4 pModel, Mesh* pMesh)
{
    _shader->use();
    glUniformMatrix4fv(_model, 1, GL_FALSE, glm::value_ptr(pModel));
    glUniformMatrix4fv(_view, 1, GL_FALSE, glm::value_ptr(pView));
    glUniformMatrix4fv(_projection, 1, GL_FALSE, glm::value_ptr(pProjection));

    pMesh->draw(_vertex, _normal, _uv);
}

simple.vs

#version 460

in vec3 vertex;
in vec3 normal;
in vec2 uv;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main(void) {
    gl_Position = projection * view * model * vec4(vertex, 1.0f);
}

simple.fs

#version 460

out vec4 fragment_color;

void main(void) {
    fragment_color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

由于没有透视和视图转换,我希望从透视中看到一个立方体,而不是什么都没有/立方体散布在视口上。

视图矩阵的设置是"wrong"。视线方向无处可去

glm::mat4 view = glm::inverse(glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -10.0f)));

当然,视图矩阵是那个矩阵的逆矩阵,由视图位置和方向定义。
视图坐标系描述了观察场景的方向和位置。视图矩阵从世界 space 转换为视图(眼睛)space。

但是 OpenGL 视图 space 坐标系是一个 Right-handed 系统,其中 X 轴指向左侧,Y 轴指向上方。这导致 Z 轴指向视图之外(注意 Z 轴是 X 轴和 Y 轴的叉积)。
事实上,这种行为是由投影矩阵引起的,它定义了视图体积和从视图 space 到剪辑 space 的转换(以及进一步归一化设备 space)。

这意味着视图位置必须是 glm::vec3(0.0f, 0.0f, 10.0f):

glm::mat4 view = glm::inverse(glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 10.0f)));