深度如何在平坦的环境中工作?

时间:2013-03-11 12:15:08

标签: opengl-es

我需要一些帮助来理解视锥体转换的基础知识。主要是,深度如何运作。

以下使用768x1024的视口。使用正交投影和768x768的正方形(z默认为0),没有平移或缩放,以及glViewport(0, 0, 768, 1024)的视口,这个方块很容易填充框架的宽度:

enter image description here

现在,当我将项目更改为平截头体并混淆z平移时,由于透视变化,正方形会适当缩放。

在这样的环境中,这是同一个方格:

enter image description here

我可以使用这个z平移,以及平截头体矩阵的近和远参数,并相应地使方形变化明显在屏幕尺寸上。细

但我无法弄清楚它的屏幕尺寸与这些深度参数之间的明显关系。

例如,假设我想使用平截头体但是正方形填充框架宽度,如上面的第一个示例图像。怎么做到这一点?

我认为如果z平移与near平面相匹配,那么你基本上就有一个“正好在镜头前”,填充框架。但我无法想办法实现这一目标。 如果我的附近是1而我的z翻译是-1,那么广场应该坐在靠近的平面上(对吗?!),填充宽度框架(截头锥体的左右平面与正交投影相同)。

我可以在这里粘贴一堆代码来展示我正在做的事情,但我认为这里的概念很清楚。我只想弄清楚近平面的实际位置,如何在其上放置一些东西,因为这将有助于我理解截头锥体是如何工作的。


好的,这是我正在使用的相关代码,其中width=768height=1024

我的顶点着色器是简单的gl_Position=Projection*Modelview*Position;

我的投影矩阵(视锥体)因此是:

Frustum(-width/2, width/2, -height/2, height/2, 1,10);

此功能是:

    static Matrix4<T> Frustum(T left, T right, T bottom, T top, T near, T far)
{
    T a = 2 * near / (right - left);
    T b = 2 * near / (top - bottom);
    T c = (right + left) / (right - left);
    T d = (top + bottom) / (top - bottom);
    T e = - (far + near) / (far - near);
    T f = -2 * far * near / (far - near);
    Matrix4 m;
    m.x.x = a; m.x.y = 0; m.x.z = 0; m.x.w = 0;
    m.y.x = 0; m.y.y = b; m.y.z = 0; m.y.w = 0;
    m.z.x = c; m.z.y = d; m.z.z = e; m.z.w = -1;
    m.w.x = 0; m.w.y = 0; m.w.z = f; m.w.w = 1;
    return m;
}

我的方块只是两个2d三角形,默认z = 0,左边的x范围为-768/2,右边缘为768/2。正如我上面的第一张图片所示,使用正交投影,广场显然正常工作。 (虽然我切换到了这个问题的平截头体投影)

为了绘制正方形,我将模型视图翻译为:

Translate(0, 0, -1);

使用:

static Matrix4<T> Translate(T x, T y, T z)
{
    Matrix4 m;
    m.x.x = 1; m.x.y = 0; m.x.z = 0; m.x.w = 0;
    m.y.x = 0; m.y.y = 1; m.y.z = 0; m.y.w = 0;
    m.z.x = 0; m.z.y = 0; m.z.z = 1; m.z.w = 0;
    m.w.x = x; m.w.y = y; m.w.z = z; m.w.w = 1;
    return m;
}

正如您所看到的,翻译应该将正方形放在近平面上,但它看起来像这样:

enter image description here

如果我翻译而不是-1.01只是为了确保我避免近剪裁,结果是一样的。如果我不翻译,因此z = 0,正方形不会出现,正如您所期望的那样,因为它会在相机后面。

2 个答案:

答案 0 :(得分:5)

在您的平截头体矩阵中,m.w.w应为0,而不是1.这将解决您的问题。

但是,错误不是你的错。我的错!我实际上是第一个编写该代码的人,不幸的是它已经激增。这是我书中的一个勘误表( iPhone 3D Programming ),这是它首次出现的地方。

对此感到非常内疚!

答案 1 :(得分:2)

  

如果我的近是1并且我的z平移是-1,则该方格应该坐在近平面上(对吗?!)

  

,填充框架的宽度(截头锥体的左右平面与正交投影相同)。

不必要。近平面具有glFrustum的 left right bottom top 参数给出的范围。当放置在近平面距离时,一个直接到达那些边界的矩形将贴合视口。