Google VR镜头校正使用深度?

Google VR Lens Correction Uses Depth?

我一直在查看来自 Google GVR SDK for Unity 的镜头校正着色器代码,并且一直在摸索视图 space 位置的 z 分量的使用( UNITY_MATRIX_MV,在 undistort() 函数中没有 UNITY_MATRIX_MVP) 的透视变换(这是一个更简单的变体):

float r2 = clamp(dot(pos.xy, pos.xy) / (pos.z*pos.z), 0, _MaxRadSq);
pos.xy *= 1 + (_Undistortion.x + _Undistortion.y*r2)*r2;

根据我的理解,我们想要在 2d 屏幕中扭曲渲染图像space 以抵消通过镜头观看屏幕时将应用的失真,我们到底在做什么除半径(? ) 乘以线性深度 (pos.z) 的平方?我可以想象这可以代替除以 w 的透视,但是为什么我们要除以 z 分量的平方(这比简单地除以 z 或 w 更正确)?

事后觉得有点傻,因为这只是定期优化的结果。

划分是常规的透视划分(但将用于深度 buffer/culling 的 z 坐标保留为线性,因此推测 w 应为 1.0 以确保正确的深度插值)。据推测,重新组织计算可以节省着色器周期 and/or 准确度。

此代码相当于通过先将 pos.xy 除以 pos.z 来缩短 pos.xy,然后将 pos.xy 与自身进行点积以获得其在 2D 屏幕空间中的长度平方(然后夹紧它,等等)