Unity从深度缓冲重建世界空间位置

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity从深度缓冲重建世界空间位置相关的知识,希望对你有一定的参考价值。

参考技术A 在某些特定应用场景,比如说屏幕空间反射SSR,会要求我们从深度缓冲中重建像素点的世界空间位置。本文介绍在Unity中如何从深度缓冲中重建世界空间位置。

第一种方法是通过像素的屏幕坐标位置来计算。

(1)首先将屏幕空间坐标转换到NDC空间中。

注意1:ComputeScreenPos返回的值是齐次坐标系下的屏幕坐标值,其范围为[0, w]。
所以这里先将范围转为[0, 1],再转为[-1, 1]。
注意2:o.screenPos.z本身就是裁剪空间下的值,范围为[-w, w],除以w范围已经转为[-1, 1],已经没有必要再*2-1,所以这里的z值多做了一步操作,导致变成没有意义的值,但是这里的z值没有用处。

(2)然后将屏幕像素对应在摄像机远平面(Far plane)的点转换到剪裁空间(Clip space)。因为在NDC空间中远平面上的点的z分量为1,所以可以直接乘以摄像机的Far值来将其转换到剪裁空间(实际就是反向透视除法)。

(3)接着通过逆投影矩阵(Inverse Projection Matrix)将点转换到观察空间(View space)。

(4)已知在观察空间中摄像机的位置一定为(0,0,0),所以从摄像机指向远平面上的点的向量就是其在观察空间中的位置。将向量乘以线性深度值,得到在深度缓冲中储存的值的观察空间位置。

(5)最后将观察空间中的位置变换到世界空间中。

第二种方法是利用在世界空间中从摄像机指向屏幕像素点的向量来计算。

(1)首先构造在世界空间中从摄像机指向屏幕像素点的向量。

(2)将向量转换到观察空间,存储其z分量的值。注意向量和位置的空间转换是不同的,当w分量为0的时候Unity会将其视为向量,而当w分量为1的时候Unity将其视为位置。

(3)在深度缓冲中采样。这里使用tex2Dproj而不是tex2D的原因是screenPos是用ComputeScreenPos来计算得到的,用tex2Dproj可以帮我们做透视除法。

(4)因为像素点的观察线性深度就是其在观察空间中的z分量,所以根据向量的z分量计算其缩放因子,将向量缩放到实际的长度。

(5)最后以摄像机为起点,缩放后的向量为指向向量,得到像素点在世界空间中位置。

以上是关于Unity从深度缓冲重建世界空间位置的主要内容,如果未能解决你的问题,请参考以下文章

从线性深度重建世界位置

Unity Shaderlab-从屏幕空间到世界空间的转换

unity urp 获取屏幕深度法向颜色纹理以及从深度纹理重构世界空间坐标

unity urp 获取屏幕深度法向颜色纹理以及从深度纹理重构世界空间坐标

unity, 在image effect shader中用_CameraDepthTexture重建世界坐标

世界空间逆投影透视