Opengl es 深度在平截头体环境中是如何工作的?

Opengl es 深度在平截头体环境中是如何工作的?,opengl-es,Opengl Es,我需要一些帮助来理解平截体变换的基础知识。主要是深度的工作原理 下面使用的视口为768x1024。使用正交投影和768x768(z默认为0)的正方形(无平移或缩放),以及glViewport(0,0,768,1024)视口,该正方形可以轻松填充帧的宽度: 现在,当我将项目更改为平截体并处理z平移时,由于透视图的更改,正方形会适当缩放 在这样的环境中,这里是同一个广场: 我可以使用这个z平移,以及平截头体矩阵的近参数和远参数,并相应地在屏幕上进行明显的平方变化。好的 但我不能弄清楚的是它的屏幕

我需要一些帮助来理解平截体变换的基础知识。主要是深度的工作原理

下面使用的视口为768x1024。使用正交投影和768x768(z默认为0)的正方形(无平移或缩放),以及
glViewport(0,0,768,1024)
视口,该正方形可以轻松填充帧的宽度:

现在,当我将项目更改为平截体并处理z平移时,由于透视图的更改,正方形会适当缩放

在这样的环境中,这里是同一个广场:

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

但我不能弄清楚的是它的屏幕大小和这些深度参数之间的明显关系

例如,假设我想使用一个frustum,但是让正方形填充框架宽度,如上面的第一个示例图像所示。如何做到这一点

我认为如果z平移与
平面附近的
相匹配,那么基本上会有一个正方形“就在摄影机前面”,填充整个帧。但我无法找到实现这一目标的方法如果我的near是
1
,而我的z平移是
-1
,则正方形应该位于near平面本身的右侧
(右?!),填充帧的宽度(其中平截头体的左右平面与正交投影相同)

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


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

我的顶点着色器是简单的
gl\u位置=投影*模型视图*位置

因此,我的投影矩阵(平截头体)是:

平截头体(-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;
}
如您所见,平移应将正方形放置在近平面上,但它看起来是这样的:

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

如果我的near是1,z平移是-1,那么正方形应该正好位于near平面上(对吗?!)

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


不一定。近平面的范围由glFrustum的左、右、底部和顶部参数给定。当放置在近平面距离处时,正好与这些边界对齐的矩形将与视口紧密配合。

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

但是,这个错误不是你的错。这是我的错!事实上,我是第一个写这段代码的人,不幸的是它已经扩散开来了。这是我的书(iPhone3D编程)中的一个勘误表,也是它首次出现的地方


对此感到非常内疚

似乎你支持我的观点:如果左平面和右平面的x值分别为-100和100,那么一个从x=-100到x=100的正方形,并且位于近平面上,它本身应该填充视口的宽度,对吗?(在本例中假设视口宽度为200)@SebbyJohanns:没错。当然,如果它正好在附近,它可能会被剪掉,从而变得“看不见”。嗯,我的经验不是这样的。在我的平截头体中,我将我的
near
设置为
1
,我的2d正方形被转换为
-1
的z,并且它仍然从近平面“向后”放置,四周填充得很好,好像离得更远。问题解决了。我使用的书中的平截头体矩阵有一个打字错误。例如,我在平截头体矩阵中没有看到一个常量
1
at
m.w.w
。应该是
0
。谢谢你忽略我的评论。没问题,这确实解决了问题。错误总会发生。谢谢你指出这一点。你的书是否有勘误页,或者这可能是唯一的错误?是的,勘误页是--平截头体错误被记录在页面底部。希望这是唯一一个真正让人悲伤的错误!感谢philip,这本书总体来说非常棒,尽管我必须承认,其中一些概念对新手来说非常具有挑战性,我仍然很难在网上找到解释,只是徒劳地“像我才10岁一样向我解释”。特别是四元数的东西,如何正确使用它们,仍然让人困惑。我通过观看加州大学伯克利分校免费的iTunes大学关于计算机图形学的讲座,设法解决了我对四元数的困惑(至少现在大部分是这样)。这绝对是个好主意。但我离题了。我在这里添加了一个关于矩阵库的问题:
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;
}