非线性的深度信息
深度信息在透视除法之后,是非线性的
Unity中的做法
查阅 Unity Linear01Depth
函数发现
1 | // Z buffer to linear 0..1 depth (0 at eye, 1 at far plane) |
1 | _ZBufferParams, float4, Used to linearize Z buffer values. |
将_ZBufferParams
带入 Linear01Depth
公式为:
将_ZBufferParams
带入 LinearEyeDepth
公式为:
正交投影矩阵
透视矩阵
投影矩阵
投影矩阵摘自虎书章节 Chapter: Viewing
简化矩阵
OpenGL 的投影矩阵
(观察空间是右手坐标系, 看向-z 方向; 但是 NDC 是左右坐标系, 看向+z 方向, 所以 OpenGL 中构建 glFrustum() 所构建的 GL_PROJECTION 矩阵, 需要将参数 near,far 要求是正数, 需要对两个参数进行取反操作)
摘自: songho.ca
翻译: 翻译
为了将深度信息记录到纹理上
需要将
-1~1
转成0~1
将 z'带入, 并且计算出 View 空间中的 z
对反算出来的 z 进行取反
在右手空间坐标系下, View 视图中, 摄像机看向的是-z 方向, 所有 z 都是负值, 为了变成线性空间下 0~1 之间, 需要对 z 进行取反
此时 z 是 view 视图下的, 在视锥下, z 的取值范围是[near, far], 所以将 z 变成 0-1 的线性空间只需要/far 即可
可以发现和 Linear01Depth 公式一致
将公式带入之后会发现还原后成功转为0~1之间的线性空间
LinearEyeDepth 公式为:
开始化简
得出结果和上方计算原始深度 z 值的公式一致
将公式带入之后会发现还原后成功转为y=x的线性空间,将非线性深度信息还原成view空间下的深度信息
结论
Linear01Depth
是将深度信息中的信息还原成 0~1 之间线性的值
LinearEyeDepth
是将深度信息中的信息还原成 view 空间中的 z