10

我环顾四周,从未见过,确定每个矩阵的确切作用以及它们形成的操作(因此实际的特征函数调用)。这就是我要找的。或者至少是对该过程的描述和几个带有特征函数的示例,以大致了解如何做到这一点!无论如何,如果它们有用,这里有一些细节:

我正在设置一个自上而下的透视游戏(因此相机向下固定但可以沿 XY 平面旋转和移动),但由于我将有一些 3D 元素(以及一些严格的 2D 元素)我认为透视投影效果很好。但我确实想知道形成正交投影需要哪些命令......

我有点理解视图,这将通过将相机坐标转换为原点,通过相机旋转旋转,将它们转换回它们所在的位置,然后缩放来完成?但究竟会涉及哪些功能和对象,我不确定。

对于存储任何给定对象的旋转,四元数似乎是最佳选择。那么这会决定模型投影吗?如果我设法将旋转简化为一个角度的 2D 情况,那么四元数会浪费吗?

并且这些矩阵是否都需要从每帧的身份重新生成?还是可以以某种方式对其进行更改以适应新数据?

我真的更喜欢为此使用 eigen 而不是手持库,但我需要一些东西来弄清楚到底发生了什么......我有所有的 GLSL 设置和统一矩阵被输入到渲染中对于我的 VAO,我只需要了解并制作它们。

编辑:
我的顶点着色器使用这个标准设置,将 3 个统一的 mat4 与位置 vec3 相乘:

gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_Position, 1.0);

mat3s 和 vec2 是否可以用于定位以在纯 2D 情况下获得更好的性能?

4

2 回答 2

14

下面是从简单输入创建视图和投影矩阵的 lookAt 和 setPerspective 函数的示例:

void Camera::lookAt(const Eigen::Vector3f& position, const Eigen::Vector3f& target, const Eigen::Vector3f& up)
{
  Matrix3f R;
  R.col(2) = (position-target).normalized();
  R.col(0) = up.cross(R.col(2)).normalized();
  R.col(1) = R.col(2).cross(R.col(0));
  mViewMatrix.topLeftCorner<3,3>() = R.transpose();
  mViewMatrix.topRightCorner<3,1>() = -R.transpose() * position;
  mViewMatrix(3,3) = 1.0f;
}

void Camera::setPerspective(float fovY, float aspect, float near, float far)
{
  float theta = fovY*0.5;
  float range = far - near;
  float invtan = 1./tan(theta);

  mProjectionMatrix(0,0) = invtan / aspect;
  mProjectionMatrix(1,1) = invtan;
  mProjectionMatrix(2,2) = -(near + far) / range;
  mProjectionMatrix(3,2) = -1;
  mProjectionMatrix(2,3) = -2 * near * far / range;
  mProjectionMatrix(3,3) = 0;
}

然后,您可以将矩阵指定给 GL:

glUniformMatrix4fv(glGetUniformLocation(mProgram.id(),"mat_view"), 1, GL_FALSE, mCamera.viewMatrix().data());
glUniformMatrix4fv(glGetUniformLocation(mProgram.id(),"mat_proj"), 1, GL_FALSE, mCamera.projectionMatrix().data());

对于模型转换(最好将视图和模型分开),您可以使用带有 Scaling、Translation 和 Quaternion 类的 Geometry 模块来组装 Affine3f 对象。

于 2012-12-09T09:26:49.260 回答
0

着色器针对提供给渲染管道的每个顶点运行。为了获得最佳性能,通常您在 CPU 上执行“统一”操作,使用统一将详细信息传递给每个着色器实例,然后运行...

在您提供的示例中,最好只计算mat4 * vec4而不是mat4 * mat4 * mat4 * vec4,实际上:

gl_Position = modelviewprojectionMatrix * vec4(in_Position, 1.0);

modelviewprojectionMatrix的结果在哪里projectionMatrix * viewMatrix * modelMatrix。对于您需要渲染的每组顶点,矩阵运算是在 CPU 端实现的。

您如何组织派生模型-视图-投影矩阵所需的数据,这取决于您的要求。实际性能取决于要渲染的场景图;例如,如果您只进行平移(可能只在 XY 平面上),则可以进行仅矢量平移,并在需要时生成矩阵。

矩阵乘以标准代数运算。矩阵可以是模型矩阵或投影矩阵。可以通过将两个变换矩阵相乘来连接变换。

于 2012-12-07T19:51:55.050 回答