模型视图投影 - 如何在世界中移动对象

Posted

技术标签:

【中文标题】模型视图投影 - 如何在世界中移动对象【英文标题】:Model View Projection - How to move objects in a world 【发布时间】:2018-03-19 23:32:03 【问题描述】:

我有一个 3D 世界,里面有一个立方体。我知道立方体的顶点被定义为立方体“质心”的坐标。

我想将立方体放置在远离我的位置,向右上方,所以我想将立方体放置在 (1,1,1)。我目前没有任何“相机”代码,所以假设我的观看位置是 (0,0,0)。

我需要翻译什么才能将立方体移动到新位置?

我对 View 和 Model 矩阵感到困惑。我认为 View 是相机视图/位置,而 Model 是 3D 世界中顶点的位置。

我下面的代码对 x 和 y 位置的工作方式与我预期的一样,但 z 进入屏幕(更远)是负数,正向/移出屏幕。我希望 z 是正的,对象离视点越远。

我做错了什么?

  glm::mat4 Projection = glm::perspective( 45.0f, g_AspectRatio, 0.1f, 100.0f );

  glm::mat4 View = glm::mat4(1.0);

  glm::mat4 Model = glm::mat4(1.0);

  // Move the object within the 3D space
  Model = glm::translate( Model, glm::vec3( m_X, m_Y, m_Z ) );

  glm::mat4 MVP;
  MVP = Projection * View * Model;

MVP 被传递到 transform 制服中。

我的着色器:

char *vs3DShader  = 

"#version 140\n"

"#extension GL_ARB_explicit_attrib_location : enable\n"

"layout (location = 0) in vec3 Position;"
"layout (location = 1) in vec4 color;"
"layout (location = 2) in vec3 normal;"

"out vec4 frag_color;"

"uniform mat4 transform;"

"void main()"
""
"  gl_Position = transform * vec4( Position.x, Position.y, Position.z, 1.0 );"

"  // Pass vertex color to fragment shader.. \n"
"  frag_color = color;"
""

;

【问题讨论】:

【参考方案1】:

我下面的代码对 x 和 y 位置的工作方式与我预期的一样,但 z 进入屏幕(更远)是负数,正向/移出屏幕。我希望 z 为正值,对象离视点越远。

您可以通过设置一个镜像 Z 轴的视图矩阵来实现这一点:

glm::mat4 View = glm::scale(glm::mat4(1.0), glm::vec3(1.0f, 1.0f, -1.0f));

视图矩阵从世界空间转换到视图空间。您的视图矩阵是单位矩阵:

glm::mat4 View = glm::mat4(1.0);

这意味着世界空间等于视图空间。请注意,通常一个视图矩阵由glm::lookAt 设置。

Z 轴是 X 轴和 Y 轴的叉积。这意味着,如果在right handed system 中 X 轴指向左侧,Y 轴指向上方,则 Z 轴指向视口之外。 见Understanding OpenGL’s Matrices

我上面描述的坐标通常是right handed system 中的视图坐标,因为glm::glm::perspective 设置了一个右手投影矩阵,它将这个坐标转换为剪辑空间,这样 z 轴被反转并变成深度。

【讨论】:

非常感谢。 Z=-1 的比例让一切变得不同。我不确定为什么首选右手系统 - 这对我来说感觉违反直觉,但很高兴知道这一点。很好的答案。 也许Is OpenGL coordinate system left-handed or right-handed?可以带来进一步的澄清

以上是关于模型视图投影 - 如何在世界中移动对象的主要内容,如果未能解决你的问题,请参考以下文章

AR 对象不应随 AR 相机 Vuforia Unity3d 移动

OpenGL边用边学------2 经典照相机模型

OpenGL的视图变换模型变换投影变换视口变换

如何在 Unity 中从 3D 对象中获取 2D 视图/纹理

xna 坐标设置为模型坐标

OpenGL投影缩放