ogre3D学习基础14 -- 雾化效果与天空面,天空盒,天空穹

时间:2022-02-06 04:16:59

前几天设置天空盒时一直出问题,现在问题终于解决了,问题来的莫名其妙,走的也莫名其妙。

  第一,还是框架,我们依然使用ExampleApplication文件,框架如下

 1 #include "ExampleApplication.h"
2
3 class TutorialApplication : public ExampleApplication
4 {
5 protected:
6 public:
7 TutorialApplication()
8 {
9 }
10
11 ~TutorialApplication()
12 {
13 }
14 protected:
15 void chooseSceneManager(void)
16 {
17 mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE);
18 ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
19 }
20
21 void createScene(void)
22 {
23 }
24 };
25 #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
26 #define WIN32_LEAN_AND_MEAN
27 #include "windows.h"
28
29 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
30 #else
31 int main(int argc, char **argv)
32 #endif
33 {
34 // Create application object
35 TutorialApplication app;
36
37 try {
38 app.go();
39 } catch( Exception& e ) {
40 #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
41 //MessageBox( NULL, e.getFullDescription().c_str(), L"An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
42 #else
43 fprintf(stderr, "An exception has occured: %s\n",
44 e.getFullDescription().c_str());
45 #endif
46 }
47
48 return 0;
49 }

  第二,我们需要实例化一下chooseSceneManager()函数,添加如下两行代码进行初始化工作

1 void chooseSceneManager(void)
2 {
3 mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE);//创建一个ST_EXTERIOR_CLOSE类型的场景管理器
4     ResourceGroupManager::getSingleton().initialiseAllResourceGroups();// 初始化所有资源
5   }

  第三,首先实现天空效果,在createScene()里添加如下代码实现天空穹

 1       mSceneMgr->setAmbientLight(ColourValue(1,1,1));//设置环境光
2 //创建一个节点
3 Entity *ent2;
4 SceneNode *node;
5 ent2 = mSceneMgr->createEntity( "Knot1", "ogrehead.mesh" );
6 node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "Knot1Node",Vector3( 0.0f, 0.0f, 0.0f ) );
7 node->setPosition(0,10,0);
8 node->attachObject( ent2 );
9 //创建一个平面
10 Plane plane(Vector3::UNIT_Y, 0);//创建一个平面,法线为Y轴,与原点距离为0
11 MeshManager::getSingleton().createPlane("ground", //面板名称为“ground”
12 ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
13 1500,1500,//平面尺寸
14 20,20,true,1,5,5,Vector3::UNIT_Z);
15 Entity *ent = mSceneMgr->createEntity("GroundEntity", "ground");//创建实体面板
16 mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);//将面板添加到场景管理器
17 ent->setMaterialName("Examples/Rockwall");//给面板添加材质
18 ent->setCastShadows(false);//本身不作为投射阴影体
19
20 mSceneMgr->setSkyDome( true, "Examples/CloudySky", 5, 8 );//天空穹

  效果如图

ogre3D学习基础14 -- 雾化效果与天空面,天空盒,天空穹

  然后实现天空盒效果,屏蔽天空穹,添加如下代码

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

  效果如下

ogre3D学习基础14 -- 雾化效果与天空面,天空盒,天空穹

  最后添加天空面的代码

     Plane plane1;
plane1.d
= 1000;
plane1.normal
= Vector3::NEGATIVE_UNIT_Y;
mSceneMgr
->setSkyPlane( true, plane1, "Examples/SpaceSkyPlane", 1500, 50 ,true,1.5f,150,150);//天空面

  有必要解释一下setSkyPlane的参数,第四个参数是天空面的大小(在这里是1500x1500个单位)第五个参数是他重复的次数,第六个参数渲染顺序。第七个参数允许你设置天空面的弯曲度,最后两个是线段数量。

ogre3D学习基础14 -- 雾化效果与天空面,天空盒,天空穹

  第四,我们来实现雾的效果,雾分为线型雾和指数雾线性雾“线性的”增浓,而指数雾“指数的”增浓(每个距离单位雾的浓度都会比上一个单位增加得更多)。

  首先是白天的雾,线型雾

     ColourValue fadeCoulour(0.1,0.1,0.1);//雾的颜色
mWindow->getViewport(0)->setBackgroundColour(fadeCoulour);//
mSceneMgr->setFog(FOG_LINEAR,fadeCoulour,0.0,50,500);//线型雾

  如图:

ogre3D学习基础14 -- 雾化效果与天空面,天空盒,天空穹

  然后我们看看指数雾:删除线型雾,添加如下代码 mSceneMgr->setFog(FOG_EXP,fadeCoulour,0.005);//指数雾

  还有一种指数雾 mSceneMgr->setFog(FOG_EXP2,fadeCoulour,0.003);//指数雾,离摄像机越远它的雾更浓,不过这两种差不多,至少我没看出来明显差别

ogre3D学习基础14 -- 雾化效果与天空面,天空盒,天空穹

  第五,最后我们看看颜色更深的雾,如同在一个伸手不见五指的夜晚,你看向远方,想看清一切,却一片漆黑。

  我们改变一下雾的颜色,ColourValue fadeCoulour(0.1,0.1,0.1);

  然后我们看到效果

ogre3D学习基础14 -- 雾化效果与天空面,天空盒,天空穹

 

原码:

ogre3D学习基础14 -- 雾化效果与天空面,天空盒,天空穹ogre3D学习基础14 -- 雾化效果与天空面,天空盒,天空穹
 1 #include "ExampleApplication.h"
2
3 class TutorialApplication : public ExampleApplication
4 {
5 protected:
6 public:
7 TutorialApplication()
8 {
9 }
10
11 ~TutorialApplication()
12 {
13 }
14 protected:
15 void chooseSceneManager(void)
16 {
17 mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE);
18 ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
19 }
20
21 void createScene(void)
22 {
23 //mSceneMgr->setWorldGeometry("terrain.cfg");
24 mSceneMgr->setAmbientLight(ColourValue(1,1,1));//设置环境光
25 //创建一个节点
26 Entity *ent2;
27 SceneNode *node;
28 ent2 = mSceneMgr->createEntity( "Knot1", "ogrehead.mesh" );
29 node = mSceneMgr->getRootSceneNode( )->createChildSceneNode( "Knot1Node",Vector3( 0.0f, 0.0f, 0.0f ) );
30 node->setPosition(0,10,0);
31 node->attachObject( ent2 );
32 //创建一个平面
33 Plane plane(Vector3::UNIT_Y, 0);//创建一个平面,法线为Y轴,与原点距离为0
34 MeshManager::getSingleton().createPlane("ground", //面板名称为“ground”
35 ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
36 1500,1500,//平面尺寸
37 20,20,true,1,5,5,Vector3::UNIT_Z);
38 Entity *ent = mSceneMgr->createEntity("GroundEntity", "ground");//创建实体面板
39 mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);//将面板添加到场景管理器
40 ent->setMaterialName("Examples/Rockwall");//给面板添加材质
41 ent->setCastShadows(false);//本身不作为投射阴影体
42
43 mSceneMgr->setSkyDome( true, "Examples/CloudySky", 5, 8 );//天空穹
44 //mSceneMgr->setSkyBox(true,"Examples/SpaceSkyBox",5000,false);//天空盒
45 // Plane plane1;
46 // plane1.d = 1000;
47 // plane1.normal = Vector3::NEGATIVE_UNIT_Y;
48 // mSceneMgr->setSkyPlane( true, plane1, "Examples/SpaceSkyPlane", 1500, 50 ,true,1.5f,150,150);//天空面
49
50 //ColourValue fadeCoulour(0.9,0.9,0.9);
51 //mWindow->getViewport(0)->setBackgroundColour(fadeCoulour);
52 //mSceneMgr->setFog(FOG_LINEAR,fadeCoulour,0.0,50,500);//线型雾
53
54 //mSceneMgr->setFog(FOG_EXP,fadeCoulour,0.005);//指数雾
55 //mSceneMgr->setFog(FOG_EXP2,fadeCoulour,0.003);//指数雾,离摄像机越远它的雾更浓
56 ColourValue fadeCoulour(0.1,0.1,0.1);
57 mWindow->getViewport(0)->setBackgroundColour(fadeCoulour);
58 mSceneMgr->setFog(FOG_EXP,fadeCoulour,0.005);//指数雾
59
60 mCamera->setPosition(50.0f, 250.0f, 250.0f );
61 mCamera->pitch( Degree(-45.0f) );
62 mCamera->yaw( Degree(-15.0f) );
63 }
64 };
65 #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
66 #define WIN32_LEAN_AND_MEAN
67 #include "windows.h"
68
69 INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
70 #else
71 int main(int argc, char **argv)
72 #endif
73 {
74 // Create application object
75 TutorialApplication app;
76
77 try {
78 app.go();
79 } catch( Exception& e ) {
80 #if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
81 //MessageBox( NULL, e.getFullDescription().c_str(), L"An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
82 #else
83 fprintf(stderr, "An exception has occured: %s\n",
84 e.getFullDescription().c_str());
85 #endif
86 }
87
88 return 0;
89 }
Code

 

总结:本来打算设置地面的,但是出现了一些莫名其妙的问题,所有就设置了一个简单的面板,下次再设置地面。