前面介绍了正交投影下的qedl,实际上,还有透视模式,根据摄像机位置的移动,远近切面也在不断变化,所以需要深度补偿。
即
float fixDepth(float depth)
{
if (PerspectiveMode == 1)
{
//‘1/z’ depth-buffer transformation correction
depth = (2.0 * ZM * Zm) / ((ZM + Zm) - (2.0 * depth - 1.0) * (ZM - Zm));
//eventually we want the depth to fall between 0 and 1
depth = (depth - Zm) / (ZM - Zm);
}
return clamp(1.0 - depth, 0.0, 1.0);
}
远近切面是从下式计算。只要摄像机位姿发生变动,就调用一次。
osg::ref_ptrosg::Camera camera = view->getCamera();
double fovy, aspect, zNear, zFar;
camera->getProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar);
同时更新shader的值
void ccEDL::setNearPlane(float zNear)
{
_zNear = zNear;
_zNearUniform->set(_zNear);
}
void ccEDL::setFarPlane(float zFar)
{
_zFar = zFar;
_zFarUniform->set(_zFar);
}
_zNearUniform = new osg::Uniform(“Zm”, _zNear);
_zFarUniform = new osg::Uniform(“ZM”, _zFar);