在特征中设置顶点着色器的投影,模型和视图变换

时间:2012-12-07 17:53:32

标签: c++ opengl game-engine eigen

我环顾四周,从未见过,确定了每个矩阵的确切内容以及形成它们的操作(因此实际的特征函数调用)。这就是我要找的东西。或至少对过程的描述和具有特征函数的几个例子一般来看一下如何做到这一点!无论如何,这里有一些细节,以防它们有用:

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

我理解视图,这可以通过将相机坐标转换到原点来完成,通过相机旋转旋转,将它们转换回原来的位置,然后缩放以进行缩放?但确切地说涉及哪些功能和对象,我不确定。

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

这些矩阵是否需要从每个帧的身份重新生成?或者可以以某种方式改变它们以适应新数据?

我真的更喜欢使用eigen代替手持式库,但是我需要一些东西来确定究竟发生了什么...我有所有的GLSL设置和统一矩阵被馈送使用我的VAO进行渲染,我只需要了解并制作它们。

编辑:
我的顶点着色器使用这个标准设置,其中3个统一的mat4s乘以位置vec3:

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

可以将mat3s和vec2用于位置,以在纯2D情况下获得更好的性能吗?

2 个答案:

答案 0 :(得分:13)

以下是一个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());

对于模型转换(最好保持视图和模型分离),可以使用带有缩放,平移和四元数类的Geometry模块来组装Affine3f对象。

答案 1 :(得分:0)

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

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

  

gl_Position = modelviewprojectionMatrix * vec4(in_Position,1.0);

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

如何组织导出模型 - 视图 - 投影矩阵所需的数据,使其符合您的要求。实际性能取决于要渲染的场景图;例如,如果您只进行翻译(可能只在XY平面上),则可以进行仅向量的翻译,在需要时生成矩阵。

矩阵乘以标准algebraic operation。矩阵可以是model matrices or projection matrices。转换可以通过乘以两个转换矩阵来连接。