【问题标题】:What is the relation between View Space & NDC?View Space 和 NDC 是什么关系?
【发布时间】:2016-10-10 11:00:08
【问题描述】:

我想在 DirectX 11 中将拾取射线从 屏幕空间 坐标转换到 视图空间,用于拾取目的。

下面是解释这种转换的一部分(来自 Frank D. Luna 的“DirectX 11 3D 游戏编程简介”)。

我不明白红色部分:据我所知,我们将顶点乘以投影矩阵,以将它们从视图空间转换为齐次剪辑空间。然后硬件做透视划分,转化为NDC空间。那么我们如何仅通过将 x 坐标乘以纵横比 r 来反转这种变换呢?

一般用XMVector3Unproject()来实现这个变换,就是把视口变换反转,然后乘以(逆投影*逆视图*逆世界)矩阵。

有人可以解释(为什么?)这种使用纵横比的“方法”是如何工作的吗?

编辑:我在下面添加了引用的 5.6.3.3 部分:

【问题讨论】:

  • 我比 dx 更 opengl,但对我来说,似乎误解是红色框“仅”为您提供了从相机中心拍摄光线的点。我的意思是,您实际上并没有取回“丢失的”透视分割和 3d 点的 NO x、y、z 坐标。相反,搜索到的 3d 位置是射线 C+a*(x_v, y_v, 1) 上的任何位置,其中 C 是相机中心,x_v 和 y_v 如上所述,“1”是到相机平面的距离(焦距) - 在 directx 中可能不是 1(不知道)。
  • 您可能应该查看第 5.6.3.3 节,以弄清楚纵横比与那里的透视划分有什么关系......
  • @Thomas 我认为你所说的是朝着正确方向迈出的一步。你能解释一下吗?
  • @ChuckWalbourn 最初我也打算包含该部分,但认为这是浪费空间,因为它真正所说的是将视图空间中投影坐标的 x 坐标除以纵横比 r。不过现在会添加它。

标签: 3d directx-11 direct3d coordinate-transformation mouse-picking


【解决方案1】:

我不明白红色部分:据我所知,我们将顶点乘以投影矩阵,以将它们从视图空间转换为齐次剪辑空间。然后硬件做透视划分,转化为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 可能正在做的事情(我猜)。

【讨论】:

  • 很好的答案,可视化部分也很聪明也很有帮助。总而言之,这个“技巧”仅适用于图像平面中的点。这实际上是一个很好的优化。可惜这本书的作者没有你那么清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
  • 2013-06-14
  • 2018-02-16
  • 2020-05-04
  • 2020-01-08
相关资源
最近更新 更多