OpenGL、GLFW、GLM:相机向右平移 x 个单位,但所有东西也随之向右移动 x 个单位

OpenGL, GLFW, GLM: Camera Translates x Units to the Right, but Everything also Moves x Units to the Right with It

我正在开发游戏引擎。目前我正在研究相机系统。当我将它向右平移 Time::getMainLoopDeltaTime() 单位时,场景中的所有东西都向右移动,而当一切看起来都应该向左移动时。我不知道我做错了什么。这些是我正在使用的技术:

注意:我使用游戏对象的变换作为相机的变换矩阵,该变换矩阵也用作视图矩阵。 x位置输出正向增加的值,场景中的游戏对象是静止的(它们的x y z位置值没有变化)。

相机游戏对象初始化

    GameObject* gameObject = GameObject::create("Main Camera", 100);
    gameObject->addComponent(ComponentType::CAMERA_2D);
    Transform* transform = gameObject->getTransform();
    transform->scale(glm::vec3(0.1f, 0.1f, 0.1f)); // Zoom out camera 10x and gameObject's transform

投影矩阵初始化:

    glm::mat4 projectionMatrix = glm::ortho(-500.0f, 500.0f, -500.0f, 500.0f, -1.0f, 1.0f);

我有一个运行每个主循环 update/cycle 并翻译 camera/game 对象的逻辑组件:

    Transform* cameraTransform = Camera2D::getMainCamera()->getGameObject()->getTransform();
    cameraTransform->translate(glm::vec3(Time::getMainLoopDeltaTimeF() * 10, 0, 0));
    cout << cameraTransform->getPosition().x << endl;

然后渲染引擎执行以下操作:

    projectionViewMatrix = projectionMatrix * Camera2D::getMainCamera()->getViewMatrix();
    spirVProgram->setProjectionViewMatrix(projectionViewMatrix);

注意:我按此顺序将这些矩阵相乘,因为我使用的是 GLM。

这是我的顶点着色器以获取更多信息:

#version 450 core

layout(location = 0) in vec2 position;
layout(location = 1) in vec4 color;
layout(location = 2) in vec2 textureCoordinates;
layout(location = 3) in float textureSlot;
layout(location = 4) in float ssboIndex;
layout(std430, binding = 2) buffer myBuffer {
    mat4 transform[];
};


layout(location = 0) uniform mat4 uProjectionView;

out vec4 vColor;
out vec2 vTextureCoordinates;
out float vTextureSlot;

void main() {
    vColor = color;
    vTextureCoordinates = textureCoordinates;
    vTextureSlot = textureSlot;

    gl_Position = uProjectionView * transform[int(ssboIndex)] * vec4(position, 1.0, 1.0);
}

我希望有人能发现我做错了什么。如果没有,有人可以向我解释这应该如何完成吗?这甚至应该是预期的行为吗?

这就是一切的样子:

就像游戏对象向右移动而相机向左移动...

重要编辑

根据我的研究,这似乎是预期的行为,但我不确定。如果这是正确的行为,我应该否定这个立场吗?而且,我应该对旋转做同样的事情吗?

编辑:这是一个可以接受的解决方案吗?

glm::mat4 Camera2D::getViewMatrix() {
    Transform* transform = gameObject->getTransform();
    glm::mat4 cameraMatrix = transform->getTransformationMatrix();
    cameraMatrix[3][0] *= -1;
    cameraMatrix[3][1] *= -1;
    cameraMatrix[3][2] *= -1;
    return cameraMatrix;
}

游戏对象的变换会保持原始变换,但每次我得到它时我都会否定它。这给出了预期的 result/behavior.

看来,我认为错误的实际上是正确的,但是相机系统的实现不完整。将 camera/gameObject 矩阵向右平移也会将所有内容向右移动。为了解决这个问题,我们可以在每次需要使用它来渲染事物时取反变换矩阵副本的位置。这将允许保留原始数据,同时在渲染时获得预期的行为。