繁体   English   中英

如何从世界空间渲染到相机空间?

[英]How to render from world space into camera space?

我有两个函数,第一个函数在世界中渲染我的对象,而第二个函数应该像 UI 一样直接在相机的视图框架中渲染我的对象。 如果相机移动,则对象在随相机移动时看起来是静止的。 但是,我的第二个函数似乎不起作用,因为什么都没有出现,我的视图投影矩阵的逻辑不正确吗?

这是将相机的视图投影矩阵发送到顶点着色器以渲染世界中对象的函数,它的工作原理是:

void Renderer2D::BeginScene(const OrthographicCamera& camera)
{
    s_Data.shader = LightTextureShader;
    (s_Data.shader)->Bind();
    (s_Data.shader)->SetMat4("u_ViewProjection", camera.GetViewProjectionMatrix());
    s_Data.CameraUniformBuffer->SetData(&s_Data.CameraBuffer, sizeof(Renderer2DData::CameraData));
    s_Data.QuadVertexBuffer = LightQuadVertexBuffer;
    s_Data.QuadVertexArray = LightQuadVertexArray;
    s_Data.QuadIndexCount = LightQuadIndexCount;
    s_Data.QuadVertexBufferBase = LightQuadVertexBufferBase;
    StartBatch();
}

这是应该像 UI 一样将我的对象直接渲染到相机的功能,但它不起作用:

void Renderer2D::BeginUIScene(const OrthographicCamera& camera)
{
    s_Data.shader = TextureShader;
    (s_Data.shader)->Bind();
    Mat4 projection = getOrtho(0.0f, camera.GetWidth(), 0.0f, camera.GetHeight(), -1.0f, 1.f);
    (s_Data.shader)->SetMat4("u_ViewProjection", projection);
    s_Data.CameraUniformBuffer->SetData(&s_Data.CameraBuffer, sizeof(Renderer2DData::CameraData));
    s_Data.QuadVertexBuffer = TexQuadVertexBuffer;
    s_Data.QuadVertexArray = TexQuadVertexArray;
    s_Data.QuadIndexCount = TexQuadIndexCount;
    s_Data.QuadVertexBufferBase = TexQuadVertexBufferBase;
    StartBatch();
}

编辑:getOrtho() 的声明:

Mat4 getOrtho(float left, float right, float bottom, float top, float zNear, float zFar);

我能想到的有两种方法。 一种是直接将屏幕空间坐标传递给不对其应用模型、视图或投影矩阵的顶点着色器。 示例顶点着色器如下所示:

#version ...

layout (location = 0) in vec3 aPos; // The vertex coords should be given in screen space

void main()
{
    gl_Position = vec4(aPos, 1.0f);
}

这将在固定位置将 2D 图像渲染到屏幕上,该位置不会随着相机移动而移动。

另一种方式是,如果您想要一个“附加”到相机的 3D 对象(因此它在屏幕上处于固定位置),您只需要应用模型和投影矩阵,而不是视图。 执行此操作的示例顶点着色器:

#version ...

layout (location = 0) in vec3 aPos;

uniform mat4 model;
uniform mat4 projection;

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

通过不使用视图矩阵,模型将始终显示在模型矩阵将模型移动到的任何位置的屏幕上。 这里的中心是相机,因此由向量vec3(0.1f, 0.0f, -0.2f)转换的模型矩阵会将模型0.1f移动到相机中心的右侧,将0.2f远离相机移动到屏幕。 本质上,这里的模型矩阵定义了模型相对于相机位置的变换。 请注意,如果您想对模型进行光照计算,那么您将需要使用第二种方法而不是第一种方法,并且您需要在此模型的视图/相机空间中进行所有光照计算。

编辑:

要将屏幕空间坐标从 [0.0, screen resolution] 范围转换为 [-1.0, 1.0],这是 OpenGL 使用的范围:

float xResolution = 800.0f;
float yResolution = 600.0f;

float x = 200.0f;
float y = 400.0f;

float convertedX = ((x / xResolution) * 2) - 1;
float convertedY = ((y / yResolution) * 2) - 1;

暂无
暂无

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

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