查看: 3399|回复: 6

正交投影下的剪裁面问题

[复制链接]

该用户从未签到

发表于 2010-7-30 15:20:51 | 显示全部楼层 |阅读模式
在正交投影下,通常我们指定的投影矩阵形如下:
   const double dblWidth = double(pViewport->width());
   const double dblHeight = double(pViewport->height());
   pCamera->setProjectionMatrixAsOrtho(-0.5 * dblWidth, 0.5 * dblWidth, -0.5 * dblHeight, 0.5 * dblHeight, -1e6, 1e6);

可以看出,我们指定的远近剪裁面分别是1e6和-1e6,这种情况下,场景的物体会被远近剪裁面给Cull掉么?或者说,物体会因为距离视点位置太近而被剪裁掉么?

该用户从未签到

发表于 2010-7-30 17:12:49 | 显示全部楼层
OSG是自动计算投影矩阵的远近平面的,您的远近平面初始设置并不会起到效果

该用户从未签到

 楼主| 发表于 2010-7-30 17:54:18 | 显示全部楼层
那我要是事先执行了如下代码:
pCamera->setComputeNearFarMode(osg::Camera:O_NOT_COMPUTE_NEAR_FAR);
那么它还会自动计算么?

该用户从未签到

 楼主| 发表于 2010-7-30 18:20:15 | 显示全部楼层
我一直在试图使用正交投影的矩阵,来模拟透视的效果——仅仅只是模拟近大远小的效果而已,达到这个效果之后,用来模拟高空坠落的效果,即相机从10公里高空落下来,假设相机镜头始终朝向地面,那么应该可以看到地面逐渐接近,同时地物慢慢变大。这里的地物,其实就是一块贴了纹理的板子而已。
这个过程中,我相机的投影矩阵就是:
   const double dblWidth = double(pViewport->width());
   const double dblHeight = double(pViewport->height());
   pCamera->setProjectionMatrixAsOrtho(-0.5 * dblWidth, 0.5 * dblWidth, -0.5 * dblHeight, 0.5 * dblHeight, -1e6, 1e6);


我的程序里面,做了一个osg:lane平面对象,平面的法线就是Z轴正方向。就是如下代码中的m_NavBasePlane,它就直接代表充当地面的那块板子。
下面是我在这种模式下的漫游器的getInverseMatrix里面的部分代码:

  const osg::Vec3 vecCameraDir(0.0, 0.0, -1.0);
  const osg::Vec3 ptCameraEye(0.0, 8765.0, 0.0);  // 这里的Y值每一帧都会变小一点点
  const osg::Vec3 vecUp(0.0, 1.0, 0.0);
  osg::Matrixd mtxLookAt;
  mtxLookAt.makeLookAt(ptCameraEye,  ptCameraEye + vecCameraDir, vecUp);

  const float fltCameraHeight = m_NavBasePlane.distance(ptCameraEye);             // 相机距离地面还有多远
  const float fltFovTheta = osg:egreesToRadians(30.0f * 0.5f);                        // 模拟透视投影下fov角度为30度的情况
  const float fltCameraFovY = fltCameraHeight * tan(fltFovTheta) * 2.0f;

  const osg::Viewport *pViewport = m_pCurrentCamera->getViewport();
  const float fltCurViewHeight = pViewport->height();
  const float fltScale = fltCurViewHeight / fltCameraFovY;                                // 求出一个模拟的缩放量,相机逐渐接近地面时,fltScale的值肯定会不断变大
  const osg::Vec3 vecScaleView(fltScale, fltScale, fltScale);

  osg::Matrixd mtxScale;
  mtxScale.makeScale(vecScaleView);

  return mtxScale * mtxLookAt;               // 返回求出来的相机模型视图矩阵



上面的代码能够让我顺利的看到大地逐渐接近的过程中慢慢放大,放大的程度跟30度张角的透视投影基本上一致。

可惜的是,当上面的变量fltCameraHeight逐渐减小到160左右,我的地面(就那块贴了纹理的板子)就消失了。若我此时使用鼠标滚轮倒回来一点点,地面又可见;也就是说,160左右的值,其实是一个临界值了,相机继续往下,则地面会被剪裁掉,若返回来一点点,地面就不会剪裁掉了。
若我此时将相机的投影矩阵使用透视投影,30度张角,然后上面的代码无需计算缩放部分,仅仅需要mtxLookAt即可,则相机足以接近到地面并穿过地面。

事实上,我的程序可以随时切换投影矩阵,对比正交和透视下的效果。我的程序在切换矩阵的时候,视口中可见的地表幅面也一直是差不多的。

整体来说吧,感觉就是我这个情况,正交投影下OSG将在相机接近地面160距离的时候,地面会被剪裁掉。

该用户从未签到

 楼主| 发表于 2010-7-30 18:23:42 | 显示全部楼层
上面的文字比较多,可能看起来比较废脑筋。我花了一天的时间都没有找出这个裁剪的原因。即便我设置相机开关,不让相机自动计算远近剪裁面,结果也是如此。

该用户从未签到

 楼主| 发表于 2010-8-1 10:52:19 | 显示全部楼层
咋没有人说话呐?

该用户从未签到

发表于 2010-8-2 08:27:06 | 显示全部楼层
pCamera->setComputeNearFarMode(osg::Camera:: DO_NOT_COMPUTE_NEAR_FAR);
这样的确不会自动计算了

严格来说我不是很明白您在做什么,不过根据我的经验:-1e6 - 1e6这个范围设置似乎有些问题的,因为它已经超出了显示硬件的绘制精度(浮点数)。这和OSG已经没有直接的关系了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

联系我们

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