Depth Value Return To WorldSpace
在很多SS(屏幕空间)算法中,都需要用到深度缓冲这个东西,在前向渲染或者延迟渲染中得到深度信息,然后重建它在世界空间的位置。这里就总结一下重建方法,免得时间久了后搞忘。
通过屏幕坐标还原
屏幕坐标是通过NDC坐标经过屏幕映射得到的,NDC一个[-1,1]的三维立方体,所以第一步就是从屏幕转换回NDC坐标:
1 | NDCPos = (ScreenPos / ScreenPos.w) * 2 -1; |
注意视口坐标和屏幕坐标是不一样的,渲染管线中的屏幕映射是指从NDC转换到屏幕空间ScreenSpace,是指游戏窗口的坐标,以像素为单位,视口坐标是一个从(0,0)到(1,1)的二维坐标,是单位化的屏幕坐标。一般会通过ComputeScreenPos去得到一个齐次坐标,然后除以w分量再得到视口坐标。
首先组建一个到这个点的方向向量,然后因为NDC坐标是通过剪裁空间做透视除法得到的,所以直接逆向做一个变换,乘一个远平面的值就行了:
1 | ClipPos = float3(NDCPos.x,NDCPos.y,1.0) * _ProjectionParams.z |
然后乘投影矩阵的逆矩阵就可以转换到观察空间,观察空间摄像机在原点,所以原点指向这个点的向量乘线性深度值,就得到了深度缓冲中存的值在观察空间的位置。
最后乘viewmatrix的逆矩阵,就到了世界空间。
视锥体插值重建
核心:
1 | float3 worldPos = _WorldSpaceC eraPos + linearDepth * interpolaedRay; |
得到视锥体四个角的向量,通过插值得到摄像机到某个像素的方向向量,用它乘线性深度,然后再加上摄像机在世界空间的坐标,就得到在世界空间的坐标。