【问题标题】:Why wont matrix multiplication in VERTEX shader work properly?为什么 VERTEX 着色器中的矩阵乘法不能正常工作?
【发布时间】:2019-04-29 11:26:31
【问题描述】:

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

我使用预先获取的统一位置 id 将我的模型、视图和透视矩阵发送到着色器,但是当将矩阵与 vec4(vertex, 1.0f) 向量相乘时,窗口仍然充满了 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);
}

简单的.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);
}

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

【问题讨论】:

    标签: c++ opengl glsl glm-math opengl-4


    【解决方案1】:

    视图矩阵的设置是“错误的”。视线方向无处可去。

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

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

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

    这意味着视图位置必须是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)));
    

    【讨论】:

    • Rabbid76 非常感谢!将值从 -10.0f 更改为 10.0f 后,它起作用了。我尝试以这种方式解决它,但可能与不同的代码行组合在一起,因此它不起作用。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 1970-01-01
    • 2018-07-10
    相关资源
    最近更新 更多