Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl 透视矩阵背后的数学_Opengl_Matrix_Perspectivecamera - Fatal编程技术网

Opengl 透视矩阵背后的数学

Opengl 透视矩阵背后的数学,opengl,matrix,perspectivecamera,Opengl,Matrix,Perspectivecamera,我想创建自己的mvp矩阵作为练习 auto lookAt(Vec)(const Vec eye, const Vec center, const Vec up) if(isVector!Vec && Vec.dimension is 3){ auto z = (eye - center).unit; auto x = cross(up.unit, z); auto y = cross(z, x); alias Mat = Matrix!(Vec.T

我想创建自己的mvp矩阵作为练习

auto lookAt(Vec)(const Vec eye, const Vec center, const Vec up)
if(isVector!Vec && Vec.dimension is 3){
    auto z = (eye - center).unit;
    auto x = cross(up.unit, z);
    auto y = cross(z, x);
    alias Mat = Matrix!(Vec.Type, 4, 4);
    alias Vec4 = Vector!(Vec.Type, 4);
    return Mat(Vec4(x, 0),
               Vec4(y, 0),
               Vec4(z, 0),
               Vec4(0, 0, 0, 1)) * translate(-eye);
}
视图转换非常简单,我将其设置为沿负Z轴查看

但是透视矩阵有一些问题

y' = 1 / (tan(fov/2) * z
x' = 1 / (ar * tan(fov/2) * z
其中
x'
y'
是新的扭曲值。所以我想出了这个矩阵

Mat4f projection(float fov, float ar, float near, float far){
  import std.math: tan;
  auto tanHalfAngle = tan(fov/2.0f);
  return Mat4f(
      Vec4f(1.0f / (ar * tanHalfAngle) , 0, 0, 0),
      Vec4f(0, 1.0f / tanHalfAngle, 0, 0),
      Vec4f(0, 0, 1, 0),
      Vec4f(0, 0, -1, 0));
}
Mat4f projection(float fov, float ar, float near, float far){
  import std.math: tan;
  auto tanHalfAngle = tan(fov/2.0f);
  return Mat4f(
      Vec4f(1.0f / (ar * tanHalfAngle) , 0, 0, 0),
      Vec4f(0, 1.0f / tanHalfAngle, 0, 0),
      Vec4f(0, 0, -1, 0),
      Vec4f(0, 0, 1, 0));
}
我目前只是将其设置为
Z
值始终为
-1
。但是我犯了一个小错误,因为现在我正在除以
-Z

问题是上面的矩阵是有效的。我目前正在渲染一个旋转的立方体,除了深度值之外,一切看起来都是正确的

但我真的很想要这个矩阵

Mat4f projection(float fov, float ar, float near, float far){
  import std.math: tan;
  auto tanHalfAngle = tan(fov/2.0f);
  return Mat4f(
      Vec4f(1.0f / (ar * tanHalfAngle) , 0, 0, 0),
      Vec4f(0, 1.0f / tanHalfAngle, 0, 0),
      Vec4f(0, 0, 1, 0),
      Vec4f(0, 0, -1, 0));
}
Mat4f projection(float fov, float ar, float near, float far){
  import std.math: tan;
  auto tanHalfAngle = tan(fov/2.0f);
  return Mat4f(
      Vec4f(1.0f / (ar * tanHalfAngle) , 0, 0, 0),
      Vec4f(0, 1.0f / tanHalfAngle, 0, 0),
      Vec4f(0, 0, -1, 0),
      Vec4f(0, 0, 1, 0));
}
但是立方体不再出现在屏幕上,我不明白为什么

auto view = lookAt(Vec3f(0, 0, -5), Vec3f(0, 0, 0), Vec3f(0, 1, 0));
auto proj = projection(PI/2, 4.0f/3.0f, 0.1f, 100);
我设置测试值

auto v = proj * view * Vec4f(0.5,0.5,0.5,1);
这是我在第一个矩阵中得到的输出,其中我除以
-Z

Vec(-0.375, 0.5, -5.5, 5.5)
Vec(-0.0681818, 0.0909091, -1) // divided by w
这是我通过第二个矩阵得到的输出,其中我除以
Z

Vec(-0.375, 0.5, 5.5, -5.5)
Vec(0.0681818, -0.0909091, -1) //divided by w
唯一改变的是标志


但是为什么我可以看到第一个矩阵的立方体,而第二个矩阵却没有呢?

OpenGL的默认剪裁规则是在剪裁空间中制定的,因为所有满足以下不平等性的点都位于视锥体内:

-w <= x, y, z <= w
-w