Chinaunix首页 | 论坛 | 博客
  • 博客访问: 228381
  • 博文数量: 36
  • 博客积分: 482
  • 博客等级: 下士
  • 技术积分: 290
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-03 12:14
个人简介

Hi-ho, Silver! 在一个商业英雄辈出的年代,让我们用技术做一次华丽的冒险。向Linus致敬,向Stallman致敬!

文章分类

全部博文(36)

文章存档

2013年(24)

2012年(1)

2011年(8)

2010年(3)

我的朋友

分类: C/C++

2011-09-05 15:13:23

Sky

Ogre提供了3种不同类型的天空:天空盒,天空穹和天空面。

 

天空盒

一个天空盒基本上是场景中一个围绕所有对象的巨大的立方体,我们添加代码如下:

mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox");

显示效果:

(注意:天空盒有些斜纹模糊,因为使用的纹理是低分辨率的,如果有高分辨率的纹理,天空盒看起来会更好^-^)

当我们调用setSkyBox的时候,我们可以设置几个有用的参数。第一个参数决定了是否启用天空盒,如果以后你想禁用天空盒,只需简单的调用

mSceneMgr->setSkyBox(false, "");

第二个参数是用于天空盒的材质脚本。第三个和第四个参数对于理解天空盒是十分重要的。第三个参数设置了天空盒离开摄像机的距离。第四个参数设置天空盒是否在场景中其他物体之间绘制。让我们看看把距离参数从默认值5000改成非常近后会发生什么:

mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 10);

效果:

是的,没有变化,这是因为第四个设置是否先绘制天空盒的参数,其默认值为true。如果天空盒先绘制,然后任何之后绘制的东西将被绘制在其之上,从而使天空盒总是出现在背景中(注意:你不应该将距离设置的近于摄像机的近裁剪距离,否则将看不见它)。实际上,最好不是先绘制天空盒,因为这样的话所有的东西都会被绘制。当最后绘制天空盒时,只有可见部分被绘制了,这将少许提升速度。所以,试试最后绘制天空盒:

mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 5000, false);

显示的效果和以前没区别,但是现在,天空盒的不可见部分不会被绘制。当使用这项技术时,有一件事你需要注意,当你把天空盒设置的太近时,你可能会裁减掉部分场景中的物体,如下:

mSceneMgr->setSkyBox(true, "Examples/SpaceSkyBox", 100, false);

效果:

如所见,地面戳穿了天空盒,这肯定不是我们想要的。如果你在你的应用中使用天空盒,你必须决定你想如何使用它们。最后绘制天空盒所得到 的速度提升是非常有限的,并且你不得不注意不要掩盖其他的物体(除非那是你想要的)。总的来说,把第二个参数之后的参数留为默认值是一种安全的选择。

 

天空穹

天空穹和天空盒非常相似,可以通过调用setSkyDome使用它们。围绕着摄像机的巨大的立方体将被创建并呈现出来,最大的区别在于 纹理以一种球形方式映射到天空盒上。你看到的仍旧是立方体,但是它看上去像纹理围绕着球形表面包裹。这种方法最主要的缺点是在立方体的底部不会映射纹理。 所以,你总是需要一定类型的地形去遮掩。

添加如下代码:

mSceneMgr->setSkyDome(true,"Examples/CloudySky",5,8);

效果:

setSkyDome的前2个参数和setSkyBox是一样的,并且你也可以通过调用'mSceneMgr->setSkyDome(false, "");'禁用天空穹。

第三个参数是天空穹使用的曲率,API参考文献建议使用2到65之间的值,低值用于更好的距离效果,高值用于低失真和平滑效果。

第四个参数是纹理平铺的次数,根据纹理的大小而调整,注意这个参数的类型是Real(floating point),不是integer,你可以设置为1.234。

第五和第六个参数是距离和是否先绘制,在天空盒里已经讨论过了。

 

天空面

 天空面和天空盒、天空穹不同。我们仅仅把纹理映射到一个简单的面上,而不再映射到一个立方体上。

我们先创建一个平面,使其朝下,然后我们将调用setSkyPlane方法,该方法不像天空盒和天空穹的方法那样有一个距离参数,距离被设置在平面的d变量中,见如下代码:

Ogre::Planeplane;

plane.d=1000;

plane.normal=Ogre::Vector3::NEGATIVE_UNIT_Y;

现在我们有了平面的定义,我们可以创建天空面了,注意第四个参数是天空面的尺寸而第五个参数是纹理平铺的次数,代码如下:

mSceneMgr->setSkyPlane(true,plane,"Examples/SpaceSkyPlane",1500,75);

效果:

我们创建的天空面有两个问题,第一,使用的纹理分辨率太低,平铺后效果不好。最主要的问题在于如果你朝边上看,将看到天空面的结束。像这样:

基本观点是当你的景点周围都是高山或丘陵时使用天空面是有用的。

setSkyPlane的第六个参数类似天空盒和天空穹中的定义'是否先绘制'的参数,第七个参数允许你定义天空面的曲率,所以我们可以不再使用一 个平面,而是有曲率的表面。现在,我们还必须设置x和y的段数(初始时天空面是一个大的正方形,但是如果我们想平面有曲率的话需要用许多小的正方形组成平 面),第八和第九个参数用来设置x和y的段数,代码如下:

mSceneMgr->setSkyPlane(true,plane,"Examples/SpaceSkyPlane",1500,50,true,1.5f,150,150);

现在看起来效果好多了:

同样,你可以使用'mSceneMgr->setSkyPlane(false, Ogre::Plane(), "");'来禁止天空面。

 

至于该使用哪种完全取决于你的应用。如果你要看你周围的一切,甚至是y的负方向,那么你只能选择天空盒。如果你有地形,或者类似地板之类的,那么使用天空穹看起来更真实。如果你看不到地平线,那么使用天空面看起来效果更好并且只需要一点点GPU代价。

阅读(6010) | 评论(0) | 转发(0) |
0

上一篇:yaw, pitch and roll

下一篇:Ogre 启动过程

给主人留下些什么吧!~~