OGRE雾化效果入门

本文介绍了在OGRE中实现雾化效果的方法,包括线性和指数雾的设置,强调了设置顺序的重要性。线性雾通过设定起始和结束距离逐渐增浓,指数雾根据距离指数级增浓。同时讨论了雾与天空盒/天空穹的配合问题,并给出了在黑暗环境中设置雾的技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[编辑] 雾化效果
[编辑] 入门
雾化效果在OGRE里非常简单。但是在你使用它之前要注意,当你使用地面管理器(TerrainSceneManager)的时候,一定要在调用setWorldGeometry函数之前调用setFog函数。(别的场景管理器里没关系的)。根据你调用这两个函数的顺序,不同的顶点程序会被调用。(注意在OGRE 1.0.0 里有一个Bug,当你使用正确顺序调用这些函数的时候,指数雾化不会被渲染。这个Bug在1.0.1的时候就已经被修复了)。

在我们开始之前,清除掉createScene函数里除了setWorldGeometry之外的所有内容。

你需要知道关于设置雾化效果的很重要的一点是他并不像你想象的那样在空的地方创建“雾”的实体。实际上雾只是当你观看物体时的一个滤镜。当你面前没有任何物体时,你是看不见雾的。事实上,你只会看到视口(viewport)的背景色。所以想要使雾逼真,我们必须将视口的背景色设成雾的颜色。

雾分两种:线性的和指数的。线性雾“线性的”增浓,而指数雾“指数的”增浓(每个距离单位雾的浓度都会比上一个单位增加得更多)。你自己看他们效果的差距比这样讲更容易理解,所以我们来看几个例子。

[编辑] 雾化类型
我们将看到的第一种雾的类型是线性的,这也是最容易理解的类型。在调用setWorldGeometry后首先要设置视口的背景颜色。我们可以用createViewport方法(象用在上一个指南)一样,但是有时我们并不需要调用视口。代码如下:

        ColourValue fadeColour(0.9, 0.9, 0.9);
       mWindow->getViewport(0)->setBackgroundColour(fadeColour);
如果视口不唯一的话,你可以用getNumViewports元函数来得到视口的数量然后不断的操作她,但是通常这种情况是很少见的(目前为止我们知道我们仅用了一个视口),我们可以直接得到视口。设置完背景色以后我们就可以创建雾了。记住,这段代码必须出现在setWorldGeometry被调用之前。

        mSceneMgr->setFog(FOG_LINEAR, fadeColour, 0.0, 50, 500);
第一个参数设置雾的类型(这里我们设的是线性的)。第二个参数是我们用到的雾的颜色。第三个参数在线性雾里面是不用设置的。第四个和第五个参数是设置雾慢慢变浓的范围。这里我们从50开始结束于500。这就意味着在摄像机的0到50个单位内是没有雾的。从50到500单位内雾慢慢线性变浓。在500单位以外全是雾了。编译运行这个应用程序。

另一种雾的类型是指数雾。和设置雾的起点和终点不一样的是,我们要设置雾的密度(第四个和第五个参数不需要设置)。代码如下:

      mSceneMgr->setFog(FOG_EXP, fadeColour, 0.005);
编译运行这个应用程序。如果你用的是DirectX渲染器你会发现完全在雾的外面,在setWorldGeometry之前调用setFog来修正它。OpenGL渲染器会按照文档里说的那样做,这能产生另一种生成雾的效果。这里还有一种更厉害的指数雾函数(与前一种比较起来,离摄像机越远它的雾更浓)。注意,如果你使用FOG_EXP2会得到更加浓密的雾。将上面的代码替换成下面的:

     mSceneMgr->setFog(FOG_EXP2, fadeColour, 0.003);
再一次编译和运行这个程序。基本上Ogre提供的这三种雾函数是可以互换的。你应该都实验一下这些函数,来看看哪一种在你的应用程序里效果更好。

[编辑] 雾与天空面
当你试图将雾与天空盒/天空穹一起使用时,会遇到些有趣的问题。因为天空盒/天空穹是方形的,而雾效是以球形的方式工作的。清空createScene方法里的内容,如果巧妙地调整天空穹和雾的参数,我们就能明显地发现这个问题。

       ColourValue fadeColour(0.9, 0.9, 0.9);
       mSceneMgr->setFog(FOG_LINEAR, fadeColour, 0.0, 50, 515);
       mWindow->getViewport(0)->setBackgroundColour(fadeColour);
       mSceneMgr->setWorldGeometry("terrain.cfg");
       mSceneMgr->setSkyDome(true, "Examples/CloudySky", 5, 8, 500);
编译运行程序。如果你转动摄像机,你会发现天空穹的某些部分会探出来(蓝色部分从边缘探出来,而不是中央):

http://www.idleengineer.net/images/beginner03_fogbox.png

这显然不是我们想要的。另一种选择就是使用天空面。在createScene里用以下代码替换:

       ColourValue fadeColour(0.9, 0.9, 0.9);
       mSceneMgr->setFog(FOG_LINEAR, fadeColour, 0.0, 0, 130);
       mWindow->getViewport(0)->setBackgroundColour(fadeColour);

       Plane plane;
       plane.d = 100;
       plane.normal = Vector3::NEGATIVE_UNIT_Y;

       mSceneMgr->setWorldGeometry("terrain.cfg");

       mSceneMgr->setSkyPlane(true, plane, "Examples/CloudySky", 500, 20, true, 0.5, 150, 150);
这样看起来就对了。如果我们往上看,就能看见天空(真实情况也是这样),而不会滑稽地从别处探出来。不管你是否使用弯曲,这都能解决当你往地平线上看的时候出现的不正常现象。

还有一种办法能让雾效不涉及整个天空,但需要对材质脚本进行修改。这已不是本课的内容,为了今后参考,它就是材质里禁用雾效的那个参数。

[编辑] 黑暗中的雾
当你设置雾的时候,可能不想使用天空,因为雾已经浓到你无法看见天空了。上面讲的雾效的一些技巧在某些场景非常有用。不把雾设置成明亮的颜色,而是设成非常暗,看看有什么效果。(注意,我们把天空面设置成离摄像机只有10个单位距离,在设置雾之前):

       ColourValue fadeColour(0.1, 0.1, 0.1);
       mWindow->getViewport(0)->setBackgroundColour(fadeColour);
       mSceneMgr->setFog(FOG_LINEAR, fadeColour, 0.0, 10, 150);

       mSceneMgr->setWorldGeometry("terrain.cfg");

       Plane plane;
       plane.d = 10;
       plane.normal = Vector3::NEGATIVE_UNIT_Y;

       mSceneMgr->setSkyPlane(true, plane, "Examples/SpaceSkyPlane", 100, 45, true, 0.5, 150, 150);

 

雾化效果:

Ogre::SceneManager::setFog(FogMode mode, const ColorValue & colour, Real expDensity, Real linearStart, Real linearEnd);

雾的颜色应与背景色相同((0.9, 0.9, 0.9)是个不错的选择).

该方法应在设置地形之后调用. 否则, 线性雾中无明显区别, 但指数雾Fog_EXP中若使用DirectX渲染器则没有雾效果出现, OpenGL渲染器可以修正这个问题.

其中mode说明雾的类型为线性还是指数, colour为雾的颜色, expDensity在指数雾中才定义, 该数值决定了雾变浓的速度, 越大则雾越浓. 线性雾中设置为0即可. linearStart与linearEnd仅在线性雾中定义, 分别为"开始有雾"的距camera距离与"全都是雾"的距camera距离.若linearEnd数值设置得过小, 则会产生较恐怖的效果.

指数雾中, Ogre::Fog_EXP和Ogre::Fog_EXP2的效果有一些区别.

总体上讲, 指数雾的渐进效果更出色, 但线性雾或许会出现在一些特殊场合的应用中.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值