研究three.webgpu.js的代码时,我遇到了“线性深度”、“透视深度”和“正交深度”这些术语。我知道透视投影和正交投影之间存在视觉差异,但为什么viewZ
不同投影之间的值会有所不同?此外,线性深度只是正交深度的另一个名称吗?
在研究了函数viewZToOrthographicDepth
和之后viewZToPerspectiveDepth
,我注意到没有viewZToLinearDepth
函数,于是受到了启发,提出了这个问题。
const viewZToOrthographicDepth = (viewZ, near, far) => viewZ.add(near).div(near.sub(far));
const viewZToPerspectiveDepth = (viewZ, near, far) => near.add(viewZ).mul(far).div(far.sub(near).mul(viewZ));
注意:我特别指的是每种投影类型之间的深度(z)值。
n 3D 图形、透视和正交投影处理深度的方式不同,这就是
viewz
两者之间的值会发生变化的原因。以下是简单的分解:透视投影:
这就是模拟真实世界视觉的方法。距离较远的物体看起来较小。深度(z 值)不是线性的。远处的物体被挤压到较小的范围内,因此随着物体离相机越来越远,细节就会丢失。该函数
viewZToPerspectiveDepth
通过调整远处物体的深度计算方式来处理这种压缩。正交投影:无论距离有多远,物体的大小都保持不变。这里的深度是线性的。这意味着它从近到远均匀增加。该函数
viewZToOrthographicDepth
处理这种线性映射,因为没有像透视投影那样的深度压缩。线性深度呢?线性深度意味着深度均匀增加,这正是正交投影的工作原理。所以,不需要函数viewZToLinearDepth
。正交深度函数已经在做这件事了。总之:
透视投影会压缩远处物体的深度(非线性深度)。正交投影可保持所有物体均匀(线性深度)。