根据我的理解,投影矩阵做了两件事:首先,它裁剪了视图空间以形成平截头体。它只保留落入平截头体的顶点,但剪裁掉的其他顶点落在外面。其次,它将裁剪空间内的坐标映射到 NDC [-1, 1]。
这两个都不做。
4x4 矩阵只是一种转换。变换本身不能剪裁任何东西。虽然矩阵可以将坐标转换为 [-1, 1] 空间,但这不一定是顶点着色器提供的剪辑空间。而且它肯定不是 3D 投影矩阵使用的剪辑空间。
顶点着色器(或最后一个vertex processing shader stage)的唯一强制工作是生成clip-space position for each vertex。剪辑空间由 OpenGL 定义为 4D 空间,其中位置的 XYZ 分量在 [-W, W] 范围内被认为是“可见的”。这里,“W”是位置的W分量。因此对于每个 XYZW,“可见”定义为 XYZ 分量在 W 范围内的位置。
图元的实际裁剪发生在顶点着色器之后。每个图元的顶点都根据之前定义的 4D 裁剪空间进行裁剪。
投影平截头体是通过将位置转换为剪辑空间来创建的,这样在平截头体之外的 4D 位置在 [-W, W] 范围之外,而在平截头体内部的位置在该范围内。
所以不是转换剪辑任何东西;它只是设置数据,以便 OpenGL 的剪辑系统能够正确剪辑。
同样,剪辑空间不是 NDC 空间(除非该位置的 W 分量为 1)。 NDC 空间是通过获取剪辑空间位置的 XYZ 并将其除以该位置的 W 分量来定义的(如果 W 为 1,那么这显然不会改变任何内容)。剪辑和 NDC 空间是两个独立的空间,剪辑发生在之前 NDC 空间。您可以从概念上将裁剪视为针对 NDC 空间的 [-1, 1] 范围进行的。毕竟,剪辑空间在 [-W, W] 范围内,所以如果将其除以 W,就会得到范围 [-1, 1]。
但记住剪辑空间不是 NDC 空间仍然很重要。