查看: 3104|回复: 3

near--far plane有几对?

[复制链接]

该用户从未签到

发表于 2012-11-12 13:53:20 | 显示全部楼层 |阅读模式
本以为投影矩阵里的near far参数就是近远裁剪的near far,但是通过一系列测试,产生了一些矛盾,如下:

1.手动设置相机投影参数和模型位置,使模型放置在眼睛与近投影面之间,按照视椎体裁剪规则,不在视锥体的部分都会被裁剪。可结果是模型仍能够被渲染。---ps:各位可以动手试试。

2.cookbook charter3-9中的vertex-displacement mapping示例,相信不少人看过,其中有一段解释:osg会自动根据根据模型和节点的包围体(BVH),计算投影矩阵的near,far平面,然后进行裁剪。

3.cookbook charter 4-3 depth-partition to display huge scene示例中,同样有一段near,far的解释:osg缺省情况下自动计算near,far平面,大概是这样计算的:在view(相机)坐标系中,取scene graph在z轴上的最大值最为far plane, 然后用far plane乘上一个参数得到near plane,该参数default下为0.0005。

小节了一下:
第一点表明近远投影面不是近远裁剪面;
第三点的裁剪面的解释很好理解。场景范围不在天文单位下(即排除z-buffer情况),在view坐标下近裁剪面位置约为0,远裁剪面为scene graph在z轴上的最大值,因此不管如何拉远拉近视角都能不会出现improper clip。但是第2点中的示例所做,用shader语言修改vertex position,如果不对模型set Initial Bound,将会出现improer clip,说明进裁剪面位置又不约为0。

这是怎么个情况。。共有几对near ,far?

该用户从未签到

发表于 2012-11-12 14:59:13 | 显示全部楼层
视椎体只有一对near-far,这个不需要纠结
OSG默认自动计算远近平面,所以您是否确认过自己设置的值是不是有效的?如果没有的话,那么您之后做的所有分析都是无意义的了

该用户从未签到

 楼主| 发表于 2012-11-12 15:12:46 | 显示全部楼层
array 发表于 2012-11-12 14:59
视椎体只有一对near-far,这个不需要纠结
OSG默认自动计算远近平面,所以您是否确认过自己设置的值是不是有 ...

自动计算远近平面的方法只有一种吧,请问是如下的方式吗?
获取scene graph在view坐标系z轴上的最大值作为远平面,乘上一个极小的系数的结果作为近平面。
并且这个结果作为缺省下的projectionMatrix的near,far参数?

该用户从未签到

发表于 2012-11-13 08:05:52 | 显示全部楼层
xn1924 发表于 2012-11-12 15:12
自动计算远近平面的方法只有一种吧,请问是如下的方式吗?
获取scene graph在view坐标系z轴上的最大值作 ...

就是这玩意
  1. template<class matrix_type, class value_type>
  2. bool _clampProjectionMatrix(matrix_type& projection, double& znear, double& zfar, value_type nearFarRatio)
  3. {
  4.     double epsilon = 1e-6;
  5.     if (zfar<znear-epsilon)
  6.     {
  7.         if (zfar != -FLT_MAX || znear != FLT_MAX)
  8.         {
  9.             OSG_INFO<<"_clampProjectionMatrix not applied, invalid depth range, znear = "<<znear<<"  zfar = "<<zfar<<std::endl;
  10.         }
  11.         return false;
  12.     }

  13.     if (zfar<znear+epsilon)
  14.     {
  15.         // znear and zfar are too close together and could cause divide by zero problems
  16.         // late on in the clamping code, so move the znear and zfar apart.
  17.         double average = (znear+zfar)*0.5;
  18.         znear = average-epsilon;
  19.         zfar = average+epsilon;
  20.         // OSG_INFO << "_clampProjectionMatrix widening znear and zfar to "<<znear<<" "<<zfar<<std::endl;
  21.     }

  22.     if (fabs(projection(0,3))<epsilon  && fabs(projection(1,3))<epsilon  && fabs(projection(2,3))<epsilon )
  23.     {
  24.         // OSG_INFO << "Orthographic matrix before clamping"<<projection<<std::endl;

  25.         value_type delta_span = (zfar-znear)*0.02;
  26.         if (delta_span<1.0) delta_span = 1.0;
  27.         value_type desired_znear = znear - delta_span;
  28.         value_type desired_zfar = zfar + delta_span;

  29.         // assign the clamped values back to the computed values.
  30.         znear = desired_znear;
  31.         zfar = desired_zfar;

  32.         projection(2,2)=-2.0f/(desired_zfar-desired_znear);
  33.         projection(3,2)=-(desired_zfar+desired_znear)/(desired_zfar-desired_znear);

  34.         // OSG_INFO << "Orthographic matrix after clamping "<<projection<<std::endl;
  35.     }
  36.     else
  37.     {

  38.         // OSG_INFO << "Persepective matrix before clamping"<<projection<<std::endl;

  39.         //std::cout << "_computed_znear"<<_computed_znear<<std::endl;
  40.         //std::cout << "_computed_zfar"<<_computed_zfar<<std::endl;

  41.         value_type zfarPushRatio = 1.02;
  42.         value_type znearPullRatio = 0.98;

  43.         //znearPullRatio = 0.99;

  44.         value_type desired_znear = znear * znearPullRatio;
  45.         value_type desired_zfar = zfar * zfarPushRatio;

  46.         // near plane clamping.
  47.         double min_near_plane = zfar*nearFarRatio;
  48.         if (desired_znear<min_near_plane) desired_znear=min_near_plane;

  49.         // assign the clamped values back to the computed values.
  50.         znear = desired_znear;
  51.         zfar = desired_zfar;

  52.         value_type trans_near_plane = (-desired_znear*projection(2,2)+projection(3,2))/(-desired_znear*projection(2,3)+projection(3,3));
  53.         value_type trans_far_plane = (-desired_zfar*projection(2,2)+projection(3,2))/(-desired_zfar*projection(2,3)+projection(3,3));

  54.         value_type ratio = fabs(2.0/(trans_near_plane-trans_far_plane));
  55.         value_type center = -(trans_near_plane+trans_far_plane)/2.0;

  56.         projection.postMult(osg::Matrix(1.0f,0.0f,0.0f,0.0f,
  57.                                         0.0f,1.0f,0.0f,0.0f,
  58.                                         0.0f,0.0f,ratio,0.0f,
  59.                                         0.0f,0.0f,center*ratio,1.0f));

  60.         // OSG_INFO << "Persepective matrix after clamping"<<projection<<std::endl;
  61.     }
  62.     return true;
  63. }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表