我不明白红色部分:据我所知,我们将顶点乘以投影矩阵,以将它们从视图空间转换为齐次剪辑空间。然后硬件做透视划分,转化为NDC空间。那么我们如何通过将 x 坐标乘以纵横比 r 来反转这种变换呢?
这应该只适用于首先位于图像平面中的点(在视图空间中),因为这些点在从 x 方向的纵横比缩放投影时不会改变它们的 x 和 y 坐标。
您可以将视图空间视为位于相机中心 (C) 的(查看)平截头体。图像平面在距相机中心 C 一定距离(即 zNear 距离)处与该视锥相交。在进行透视投影时,比 zNear 更接近 C 的事物在屏幕上被缩放为更大,并且图像平面“后面”的事物被缩小(这是透视失真)。这在技术上是通过在齐次坐标中除以 w 来实现的。关键是图像平面中的点没有缩放。你可以想象一个平截头体变成一个立方体,图像平面保持相同大小,是一个无限大的平面与平截头体以及立方体的交集。
现在,在想象平截头体视图空间 --> 立方体之后,唯一需要做的就是应用纵横比以匹配 (NDC-) 立方体的 x-,y-坐标到屏幕矩形。这是通过保留 y 并仅将 x 除以 r 来完成的。这是通过采用 NDC 坐标并乘以 r 来撤消的步骤。但这只会让您在 NDC 坐标(NDC 立方体的横截面)中从矩形到方形图像平面。投影不会因此而撤销。
诀窍是,这个图像平面的横截面设计等于视图空间中的横截面,正如我用我想象的变形所描述的那样。因此,从技术上讲,您可以说您的点 (x_v y_v) 再次位于视图空间坐标中 - 尽管您仅始终位于图像平面中。谈论视图空间(和它的好)的原因是您现在可以通过 (x_v, y_v) 从 C 射出一条射线,并且您的原始 3d 对象点位于该射线上。只有它的距离 z 是未知的。例如,您可以从深度缓冲区查找中获得此距离,这就是 XMVector3Unproject 可能正在做的事情(我猜)。