加载中…
个人资料
则卷大明
则卷大明
  • 博客等级:
  • 博客积分:0
  • 博客访问:7,035
  • 关注人气:2
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
相关博文
推荐博文
谁看过这篇博文
加载中…
正文 字体大小:

U3D Linear01Depth & LinearEyeDepth

(2014-08-05 11:11:44)
标签:

365

it

UnityCG.cginc中原函数如下:
// Z buffer to linear 0..1 depth (0 at eye, 1 at far plane)
inline float Linear01Depth( float z )
{
return 1.0 / (_ZBufferParams.x * z + _ZBufferParams.y);
}
// Z buffer to linear depth
inline float LinearEyeDepth( float z )
{
return 1.0 / (_ZBufferParams.z * z + _ZBufferParams.w);
}
其中_ZBufferParams的定义如下:
double zc0, zc1;
// OpenGL would be this:
// zc0 = (1.0 - m_FarClip / m_NearClip) / 2.0;
// zc1 = (1.0 + m_FarClip / m_NearClip) / 2.0;
// D3D is this:
zc0 = 1.0 - m_FarClip / m_NearClip;
zc1 = m_FarClip / m_NearClip;
// now set _ZBufferParams with (zc0, zc1, zc0/m_FarClip, zc1/m_FarClip);
参考资料链接:http://forum.unity3d.com/threads/_zbufferparams-values.39332/

经过透视投影变换时,Z值的计算方式如下:
Z' = f*n/[(n-f)*z] + f/(f-n);
可以简单的理解为将z值的倒数进行插值计算,映射到[0, 1](d3d)空间中。
将上式带入Linear01Depth中,可得最后计算结果为z/f;
就是说,是将[0, f]映射到[0, 1]空间,若要映射[n, f]到[0, 1]则是(z-n)/(f-n)。
将上式带入LinearEyeDepth中,可得最后计算结果为z。很明显,LinearEyeDepth是将经过透视投影变换的深度值还原了。
至于在透视投影变换中为什么要用公式Z' = f*n/[(n-f)*z] + f/(f-n);这个说起来比较麻烦,简单来说是为了将深度值映射到[0, 1]空间方便裁剪,以及x'和y'与1/z成线性关系(这是为了光栅化时的透视纹理映射所做的准备),读者可以参考下面链接http://wenku.baidu.com/link?url=GoxRM0e3Neo121CPWVdh7RRYZpN1Gj7xkfNeGxNN92bo-RULSAyEZv_odGdrteg8sBUd7MuX2ihlrBaAcqxRwVop-S3DI2pkKL5rBXlrTvO
注意链接中是以Opengl作为例子进行讲解,其z值的映射空间为[-1, 1]。
关于为什么x'要与1/z成线性关系可参考下面链接:http://blog.csdn.net/popy007/article/details/5570803

0

阅读 评论 收藏 转载 喜欢 打印举报/Report
  • 评论加载中,请稍候...
发评论

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 电话:4000520066 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有