从视图矩阵中清除比例组件。与摄像机无关的缩放

时间:2017-09-15 15:29:23

标签: c++ opengl matrix glm-math

我需要为我的小程序按照摄像机距离缩放Gizmo,以便随时方便地移动对象。我想我有两个选择:

  1. 计算从小玩意到相机的距离,制作缩放矩阵,乘以周期中的所有点:

    glm::mat4 scaleMat;
    scaleMat= glm::scale(scaleMat, glm::vec3(glm::distance(cameraPos,gizmoPos)));
    
    for (int i = 0; i < vertices.size(); i++)
    {
        vertices[i] = glm::vec3(scaleMat * glm::vec4(vertices[i], 1.0));
    }
    
  2. 仅为Gizmo清除视图(lookAt)矩阵的比例分量。

  3. 如果我使用第一种方式,当我改变相机位置时,我的Gizmo比例会累积比例并增加Gizmo的大小。我认为第二种方式更准确,但如何做到这一点?谢谢!

1 个答案:

答案 0 :(得分:2)

如果你想每次对同一个模型应用不同的缩放,你不应该操纵顶点(实际上你不应该这样做),而是模型矩阵。通过它你可以操纵对象而无需通过代码处理顶点。 我会选择这样的东西:

glm::mat4 modelMatrix(1.0f);
modelMatrix = glm::scale(modelMatrix,glm::vec3(glm::distance(cameraPos,gizmoPos)));

这将为您提供缩放的模型视图矩阵。现在你只需要将它传递给你的顶点着色器。

你应该大致有这样的事情:

#version 330 core

// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;

uniform mat4 M;

void main(){
    gl_Position =  M * vec4(vertexPosition_modelspace,1);
}

我没有测试过代码,但它与我的某个项目的代码非常相似。在那里我保留了我的模型矩阵,因此累积了缩放比例,但是如果每次都将一个全新的矩阵传递给顶点着色器,那么就不会记住任何内容。

如果您需要有关将制服传递到着色器的更多信息,请查看here at my current project's code

您可以在TARDIS::applyScaling内找到缩放,并在main.cpp

中找到着色器加载