osg场景中模型的大小匹配问题(续再谈osg中的树)

在场景中树的问题解决后,原以为就快要结束了。可没想到硬是半路又杀出一个头疼的问题。再换过地形后,导入osg场景中的各个模型大小不匹配!具体情况就是osg场景中的一个房子或一棵树就可能遮盖了整个地形。刚开始时还不知道怎么回事,只是奇怪,怎么所有的房子和树都挤在一起了,地形不见了?经过一番折腾后才明白原来地形太小了,所以所有的房子和树就挤在一起了,而地形也就被房子盖住了。看到这,你也许会说只要把地形放大不就行了吗??答案是否定的,还要看什么情况。因为刚开始我也的确试图把地形放大,但结果是徒劳的,问题没能解决。
为什么会这样呢?现在总结一下原因。

一,建模的时候没有统一好单位,其中地形的系统单位是cm,而房子和树的单位是毫米,这样导入到osg中就出现了上述的情况。但在3dmax中,不同单位的地形和树大小是匹配的(我想可能是因为3dmax中设置的可见单位相同都是米)。关于这个问题,我在osgchina的论坛上发过帖子(osg中的单位问题
http://bbs.osgchina.org/forum.php?mod=viewthread&tid=10789&fromuid=6399)如大神所说,osg中是没有具体的单位,长度单位是1,(不分是毫米,还是米),这样的话地形显示的长度是100m,设置的单位是cm,所以实际长度为10000cm,在osg中就是10000单位。而一棵5m高的树,设置单位是mm,那么实际长度就是5000mm,在osg中就是5000单位,这样一棵很小的树就和地形的大小相当了,也就可以解释地形会被树和房子覆盖的问题。而将地形的单位转化成和树的单位一致后(在max里有一个缩放过程cm转化成MM是一个放大的过程)100m的地形就变成了100 000mm,在osg中就是100 000单位,这样和树就匹配了。这个结果也就验证了上面的推理过程。

所以,上面问题的第一个解决方法就是:将模型按系统单位缩放,使地形的系统单位和树木的单位一致。注意这里的缩放不是在osg中的缩放,是在3dmax中按单位转换!!!第二种解决办法很简单就是在osg挂载模型的时候将模型缩小一定的比例(我试过比较合适的是0.03,至于为什么不是上面分析过程中得到的结果0.1我也不太清楚,可能是因为缩放还涉及到其他父节点的变换矩阵,原因下面会说。)

现在说下为什么不能将地形在osg中放大。我在上一篇博客中说到,可以用小方块标记树木和建筑实现模型的共享,而这次我用的就是这个方法。说到这也许你们已经想到了。正是这样,因为地形中有标记树木建筑用的小方块,当地形放大时,小方块也会被一起放大。这就使地形放大多少,挂载的模型就放大多少,所以不论将地形怎样放大都是徒劳的。但我说过的空节点的方法就不存在这个问题,你完全可以将地形放大后再加入空节点,这就和在挂载模型时将模型缩小一样了。

再说下3dmax中的建模时标记用的小方块和osg中挂载的模型的关系。也许你们会问,那小方块的大小会影响osg中挂载模型的大小吗?答案是否定的,影响挂载模型的大小和形状的变化的是小方块的缩放矩阵,比如在建模过程中你可能将某部分放大了几倍,然后里面的小方块也同时被均匀的放大了同样的倍数,那么挂载的模型就会被放大相同的倍数。而且需要说明的是,如果小方块是在某个方向缩放的话,模型也会在某方向缩放。比如把小方块沿x轴方向放大5倍,其他方向不变,那么挂载的模型也会在x轴被放大5倍。所以如果想通过调整小方块的大小来调整模型的大小的话就应该是对小方块进行缩放,而不是单纯在数值上改变小方块的大小。小方块的大小跟模型的大小是没有任何关系的,有关系的只是小方块的变换矩阵,如论坛中大神所说  每个节点的实际大小:  是所有父亲节点的Transform的累计与本节点的Transform一起叠加作用。也就是说挂载的模型的实际大小是模型本身的变换矩阵和小方块的变换矩阵等一系列父节点变换矩阵的累积一起的叠加作用。这样也就可以解释上面所说的缩放不是0.1了。然后小方块的前后左右也是和模型的前后左右相对应的,如果挂载后发现模型的方向错了,可以通过调整小方块的方向来调整模型的方向。

突然忘记了还有什么要写,那就等想起来再写吧,,如果有什么不对的,还请大神们指点!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
osgEarth解决模型透明问题,可以采用以下两种方式: 1. 使用深度排序 深度排序是一种常用的解决模型透明问题的方法。在渲染透明模型时,需要按照模型的深度从后往前渲染,这样才能保证前面的模型不会遮挡后面的模型osgEarth提供了DepthOffsetNode这个节,可以用于设置渲染时的深度偏移量,从而实现深度排序。 例如,可以将需要渲染的节加入到DepthOffsetNode,然后设置合适的深度偏移量,即可实现深度排序。示例代码如下: ``` osg::ref_ptr<osgEarth::Util::DepthOffsetNode> depthOffsetNode = new osgEarth::Util::DepthOffsetNode; depthOffsetNode->addChild(model); depthOffsetNode->setDepthOffset(-1.0f, -1.0f); root->addChild(depthOffsetNode); ``` 在上述代码,我们创建了一个DepthOffsetNode节,并将需要渲染的模型model添加到其。然后,我们设置了深度偏移量为(-1.0f, -1.0f),表示在渲染透明模型时,深度值需要减去一个较小的偏移量,以保证透明模型能够正确地进行深度排序。最后,我们将DepthOffsetNode节添加到场景根节root即可。 2. 使用Alpha测试 另一种解决模型透明问题的方法是使用Alpha测试。Alpha测试是一种在渲染透明模型时,根据像素的Alpha值来决定是否进行绘制的方法。在osgEarth,可以使用StateSet来设置Alpha测试相关的状态,例如设置Alpha测试函数和Alpha测试值等。 示例代码如下: ``` osg::ref_ptr<osg::StateSet> stateSet = model->getOrCreateStateSet(); stateSet->setAttributeAndModes(new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.5f), osg::StateAttribute::ON); stateSet->setMode(GL_BLEND, osg::StateAttribute::ON); ``` 在上述代码,我们首先获取或创建模型的StateSet,然后设置Alpha测试函数为GREATER,Alpha测试值为0.5f。这表示只有像素的Alpha值大于0.5f时,才会进行绘制。最后,我们使用setMode()函数将混合模式设置为ON,表示需要进行混合处理。 总之,这两种方法都可以解决模型透明问题,在具体应用可以根据情况选择。需要注意的是,深度排序需要考虑场景所有透明物体的深度关系,而Alpha测试只是根据像素的Alpha值进行判断,因此在场景比较复杂的情况下,深度排序可能更加合适。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值