從depth buffer中構建view-space position
觀察透視投影矩陣:
對於x和y,矩陣變換只是一個縮放係數,
設Xndc Yndc為NDC空間中的XY座標,Xview Yview Zview為view space中的座標,則
所以
所以已知XY的NDC座標和view space z,就能求出view space position,寫成代碼就是:
float M = tan(fov*0.5f)*aspect; float N = tan(fov*0.5f); float3 GetViewSpacePos(float2 NDCPos, float ViewSpaceZ) { float3 VPos = float3(NDCPos.xy, 1.f) * float3(M, N, 1.f); return VPos * ViewSpaceZ; }如果depth buffer中已經存儲了線性的view space depth,那麼只需採樣出depth,然後計算出position即可;如果depth buffer中儲存的是非線性的perspective z(NDC z),那麼需要先把perspective z逆變換為view space z,再使用上述方法計算position。
把perspective z變換為view space z:
對於view space z,乘以投影矩陣然後除以w得到ndc z:
由上式可得:
其中
寫成代碼就是:
float P0 = 1/zn; float Q = zf/(zf - zn); float P1 = 1/(zn*Q); float PerpectiveZToLinearZ(float Zndc) { return 1.f / (P0 - P1 * Zndc); }所以對於perspective z,構建view-space postion的代碼如下: