1

我做了这个教程:

http://ltslashgt.com/2011/02/28/molehill-spinning-cube/

有趣的是他没有使用 perspectiveFieldOfViewLH 而是定义了自己的投影矩阵。我是 3d 编程的新手,所以在阅读了投影矩阵的这个解释之后:

http://www.songho.ca/opengl/gl_projectionmatrix.html

我试图实现我自己的矩阵,看看我是否真的理解它:

var y2:Number = near * Math.tan(fov * Math.PI / 360);
var y1:Number = -y2;
var x1:Number = y1 * aspect;
var x2:Number = y2 * aspect;

return new Matrix3D(Vector.<Number>([
    2 * near / (x2 - x1), 0, 0, 0, //x
    0, 2 * near / (y2 - y1), 0, 0, //y
    0, 0, (far + near) / (near - far), -2 * far * near/ (far - near), //z
    0, 0, -1, 0 //w
    ]));

我得到了黑屏。我所做的只是用这个矩阵交换教程中的矩阵。我试着玩了一段时间,但没有结果。这是教程中的矩阵:

protected function perspectiveProjection(fov:Number=90,
  aspect:Number=1, near:Number=1, far:Number=2048):Matrix3D {
  var y2:Number = near * Math.tan(fov * Math.PI / 360);
  var y1:Number = -y2;
  var x1:Number = y1 * aspect;
  var x2:Number = y2 * aspect;

  var a:Number = 2 * near / (x2 - x1);
  var b:Number = 2 * near / (y2 - y1);
  var c:Number = (x2 + x1) / (x2 - x1);
  var d:Number = (y2 + y1) / (y2 - y1);
  var q:Number = -(far + near) / (far - near);
  var qn:Number = -2 * (far * near) / (far - near);

  return new Matrix3D(Vector.<Number>([
    a, 0, 0, 0,
    0, b, 0, 0,
    c, d, q, -1,
    0, 0, qn, 0
  ]));
}

请注意,第一行和第二行是相同的。

4

1 回答 1

0

事实上有一个很好的答案,但它可能有点太高了。投影矩阵的工作是从眼睛空间到剪辑空间。眼睛空间是眼睛或相机位于原点 (0,0,0) 并向下看 z 的位置。在眼睛空间中,顶点通常是 (x,y,z,1)。顶点程序输出在剪辑空间中。理解它的最简单方法是使用那些 (x,y,z,w) 剪贴空间坐标进行绘图:它们是通过将所有坐标除以 w(不是 z!)来投影的。所以 x 屏幕坐标是 x/w 等,但要获得透视,你想除以 z 或距离,而不是 w ,在眼睛空间中仍然是 1。所以投影矩阵的主要工作是将眼睛空间 z 移动到剪辑空间 w 中。所有其他的东西只是额外的缩放折叠。看起来这些缩放中的一个在你的版本中是错误的,很可能是 z。在 molehill 中,z 输出用于深度测试,在 -1..0 范围内。只要确保不要忘记 z 也将被 w 除。这就是为什么教程矩阵在 z 行的 w 上有 -1,以便在深度测试中获得类似 1/z 的东西。现在我写了一堵文字墙 :) 也许最好的学习建议是真正熟悉 4x4 矩阵数学并尝试在纸上遵循转换管道。

于 2012-01-29T10:45:16.980 回答