Ogre学习笔记2(光源摄像机和阴影)

Ogre学习笔记2(光源摄像机和阴影)

  • 摄像机
    摄像机是我们用来观察场景的对象,摄像机的工作原理与sceneNode类似,有setPosition函数和yaw()等旋转的函数,你可以把摄像机添加到一个sceneNode上。
  • 创建相机
    创建相机是通过sceneManager对象的createCamera()函数来创建
mCamera = mSceneMgr->createCamera("PlayerCam");

同样你也可以通过名称获取摄像机的指针,通过调用getCamera()函数
下面代码我们移动摄像机的位置并且规定摄像机往哪里看。

mCamera->setPosition(Ogre::Vector3(0, 300, 500));
mCamera->lookAt(Ogre::Vector3(0, 0, 0));

摄像机会根据你设置的向量来旋转摄像头。
下面我们设置摄像机的近裁剪距离,如果模型的面比这个距离更近我们就会进入模型的内部。

mCamera->setNearClipDistance(5);

同样也有一个函数可以让你设置摄像机的远裁剪面,但是在这个例子中不需要。
我们通过OgreBites创建一个摄像机的管理器

mCameraMan = new OgreBites::SdkCameraMan(mCamera);

这是动态分配的内存不要忘记释放他

  • 视口
    当有多个摄像机时,视口就会非常有用,比如游戏中的分屏显示。我们需要通过一个摄像机的指针告诉renderWindow创建一个视口。
    我们通过renderWindow来创建视口,通过addViewport函数。
Ogre::Viewport* vp = mWindow->addViewport(mCamera);

创建完视口我们要通过viewport来设置背景颜色。
然后我们要做的事是确定相机的横纵比。即使我们使用了默认的横纵比但是还是示范一下函数的使用。我们通过摄像机类的函数来设置横纵比

vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0));
mCamera->setAspectRatio(Ogre::Real(vp->getActualWidth())/Ogre::Real(vp->getActualHeight()));
  • 建立场景
    为了显示灯光和阴影的效果,我们来建立场景
    注意我们是通过Entity的setCastShadows()来设置开启实体的阴影
Ogre::Entity* ninjaEntity = mSceneMgr->createEntity("ninja.mesh");
ninjaEntity->setCastShadows(true);
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ninjaEntity);

下面我们要创建一个平面,我们需要通过MeshManager来从头创建一个mesh,我们将用它生成一个纹理面来当地面。
我们首先要做的是创建一个抽象的平面物体。

Ogre::Plane plane(Ogre::Vector3::UNIT_Y, 0);

我们指定了它的法向量就是Y轴
接下来我们要用MeshManager创造我们的平面网格,我们可以通过上面的对象创建一个平面网格。

Ogre::MeshManager::getSingleton().createPlane(
  "ground",
  Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
  plane, 
  1500, 1500, 20, 20, 
  true, 
  1, 5, 5, 
  Ogre::Vector3::UNIT_Z);

参数有点多,我们先简单理解成我们创建了一个名字叫ground的新mesh
接下来我们创建一个Entity,用这个新的mesh-“ground”

Ogre::Entity* groundEntity = mSceneMgr->createEntity("ground");
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(groundEntity);

注意这里我们不是在创建Entity的时候传入一个名称,而是一个mesh的名字。
我们要把这个地面的阴影关闭,因为打开它是一种浪费,但是关闭它,我们的物体仍然可以将阴影投射在它上面

groundEntity->setCastShadows(false);

我们可以给地面设置一个材质,最简单的方法是设置一个系统自带的材质。

groundEntity->setMaterialName("Examples/Rockwall");
  • 使用阴影
    SceneManager中有一个setShadowTechnique的方法,可以使用,我们可以控制哪个实体开始阴影和关闭只需要调用Entity的setCastShadows函数即可
    让我们先关掉环境光这样我们可以看到更好的效果。
mSceneMgr->setAmbientLight(Ogre::ColourValue(0, 0, 0));
mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
  • Lights
    Ogre里的光源有三种类型
    Ogre::Light::LT_POINT 点光源
    Ogre::Light::LT_SPOTLIGHT 聚光灯 就像手电筒
    Ogre::Light::LT_DIRECTIONAL 方向光 就像太阳光
    光有很多类型的属性,最重要的两个就是漫反射属性和镜面反射属性的颜色,详细的内容会在后面有讲解
    我们先创建一个聚光灯光源:
    然后我们设置镜面反射和漫反射的属性
    再然后聚光灯需要设置位置和方向,就像一个手电筒
    最后我们设置聚光灯内边缘和外边缘的角度
Ogre::Light* spotLight = mSceneMgr->createLight("SpotLight");
spotLight->setDiffuseColour(0, 0, 1.0);
spotLight->setSpecularColour(0, 0, 1.0);
spotLight->setType(Ogre::Light::LT_SPOTLIGHT);
spotLight->setDirection(-1, -1, 0);
spotLight->setPosition(Ogre::Vector3(200, 200, 0));
spotLight->setSpotlightRange(Ogre::Degree(35), Ogre::Degree(50));
  • 创建更多光源
    接下来我们创建一个方向光添加到我们的场景,他们就像日光和月光一样
Ogre::Light* directionalLight = mSceneMgr->createLight("DirectionalLight");
directionalLight->setType(Ogre::Light::LT_DIRECTIONAL);

设置镜面反射和漫反射颜色

directionalLight->setDiffuseColour(Ogre::ColourValue(.4, 0, 0));
directionalLight->setSpecularColour(Ogre::ColourValue(.4, 0, 0));

因为是方向光所以不具有位置,所以我们只需要设置一个方向即可。

directionalLight->setDirection(Ogre::Vector3(0, -1, 1));

Ligth类还有一个方法可以设置光线的衰减setAttenuation

我们还有一种光源类型没有学习那就是点光源,最后我们要把点光源添加到场景中

Ogre::Light* pointLight = mSceneMgr->createLight("PointLight");
pointLight->setType(Ogre::Light::LT_POINT);
pointLight->setDiffuseColour(.3, .3, .3);
pointLight->setSpecularColour(.3, .3, .3);

点光源因为只有一个位置所以我们不需要设置方向

pointLight->setPosition(Ogre::Vector3(0, 150, 250));

关于阴影还有很多的知识这只是最基本的。

  • 总结
    这节课我们学习了怎么通过MeshManager从头创建一个mesh,也学习了如何开启阴影并且学习了三种灯光的使用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值