OGRE布告板与粒子

OGRE布告板与粒子 布告板(Billboard) Ogre中的布告板简单的来讲就是场景中的一个四边形,但它的朝向与相机有关。通常布告板随着相机的视方向旋转以便与相机的视线方向对齐。把布告板放在场景的任何地方,它将会朝向相机。为了效率考虑,布告板与相机的视线方向对齐,而不是与从布告板到相机的向量对齐。大部分情况下两者没有明显的区别。如果想使用后一种的对齐形式,也可以办到,但在性能会有所降低。 布告板集(Billboard Sets) 布告板不能独立存在,他们也不能自我渲染。他们必须属于某个布告板集。布告板集可认为是一组布告板 的管理器,布告板集内的所有布告板有相同的尺寸,使用相同的材质。相同的尺寸,相同的纹理会带来计算与渲染效率的提升。可以在一个布告板集内单独改变某个公告板的尺寸,但这样做会导致性能下降ogre 认为一个布告板集是一个操作的单位,它们要么都不渲染,要么全部进行渲染,换句话说,它们以同样的 方式进行剔除处理,也可以对集合的个体进行单独剔除,但最好不要这么做,同样这也是出于效率的虑。在大范围的应用布告板集来模拟草的例子中,就有可能出现在布告板集内的许多布告板落在视角之外的情况,在这种情况下也许会想到用单独剔除的方式,但这样做同样不可避免地会影响性能。更好的做法是使用多个布告板集而不是在一个巨大的布告板集进行单独剔除。布告板集内的布告板是相对于布告板集attached到的场景结点进行定位的。既然,布告板集内的布告板使用相同的材质,那么它们会在同一batch进行渲染。 布告板创建 布告板可以用与本布告板集的中心的偏移与尺寸(宽,高)来描述。它的方向是它到相机向量的函数。缺省,创建的布告板是所谓的point布告板。这种布告板总是完全地面对相机而且垂直。布告板的原点缺省位置是它的中心,可以在九个规范的位置范围内改变原点位置。第二种类型的布告板是oriented布告板,它即可以沿各自的Y轴旋转,也可沿共同的轴(通常是Y轴)旋转。第三种是perpendicular布告板,它与方向向量(布告板与相机之间的向量)垂直。这个方向向量可以是共享的向量(通常是Z轴),也可以是各自的Z轴。这种类型的布告板也需要一个上方向辅助定位。 point布告板相对于其他类型的布告板有一些优点。一般,ogre为每个布告板产生一个quad(四个顶点,每个 顶点都有位置,纹理坐标),并把生成的几何体送入GPU进行渲染。对于point 布告板,可以废除其中的三个,让GPU挑选,以及决定如何进行基于点绘制纹理属性的渲染。进行硬件点渲染有一些限制:只支持 point布告板,其中只限于以中心为原点的那一类。尺寸与外观在材质中定义,不在布告板集,尺寸是有限 的,不可能与软件创建的一样大。不支持单独的布告板旋转与改变大小,但可以对纹理单元旋转。 布告板池 创建布告板时需要告诉布告板集中布告板的数量。布告板被分别放在active与free列表中,这使得定位非常快。当创建的布告板的数量超过了布告板池的尺寸,池的尺寸会增加一倍。最好事先确定池的大小,避免在使用中使池的大小不合理地增长。 布告板纹理坐标 支持非全范围的纹理坐标分配。举个例子,假如你有个纹理,它包含几个子纹理。每个纹理都包含一个 英文字母。这时,你想创建几个公告板,每个公告板上显示不同的字母,当然它们都来自同一个纹理。 可以先创建一个包含纹理坐标的数组,然后把这个数组提供给布告板集。当利用布告板集创建布告板时, 可以给这个布告板一个存放纹理坐标的数组的索引。图片与代码如下: // create a new billboard set with a pool of 4 billboards BillboardSet* bbset = sceneMgr->createBillboardSet("BBSet", 4); // create a texture coordinate array to address the texture FloatRect texCoordArray[] = { FloatRect(0.0, 0.0, 0.5, 0.5), // address the "A" FloatRect(0.5, 0.0, 1.0, 0.5), // address the "B" FloatRect(0.0, 0.5, 0.5, 1.0), // address the "C" FloatRect(0.5, 0.5, 1.0, 1.0), // address the "D" }; // provide this array to the billboard set bbset->setTextureCoords(texCoordArray, 4); // now create a billboard to display the "D"; this // is the fourth entry in the array, index=3 Billboard* bb = bbset->createBillboard(Vector3(0, 0, 0)); bb->setTexcoordIndex(3); 也可以直接对纹理坐标进行赋值 FloatRect coords(0.5, 0.5, 1.0, 1.0); bb->setTexcoordRect(coords); 布告板使用的材质脚本与可以包括正常材质脚本中的所有东西,而且可以使用布告板与点纹理特有的一些 指令与参数。 布告板链与丝带跟踪(Ribbon Trails) 布告板链一组前后相联结的一组布告板(可以联想“老鹰抓小鸡”的游戏中小鸡们的组织结构)。ogre 提供了一个ribbon-trail引用类,它使用了布告板链,可以追逐场景中的结点,并留下一条尾巴。布告板链可以分多个节,因此可以很好来模拟灯的效果 。布告板链的缺点是必须手动更新。可以为布告板链的每个节的尾部添加项,每个节有最大的长度,假如超过了那个长度,尾部项被移除,重新做为节的头。 ribbon trail有类似的行为,从尾部移除项作为头来增长,从头到尾颜色逐渐褪化。图片与代码如下: void setupTrailLights(void) { NameValuePairList pairList; pairList["numberOfChains"] = "2"; pairList["maxElements"] = "80"; RibbonTrail* trail = static_cast ( mSceneMgr->createMovableObject("1", "RibbonTrail", &pairList)); trail->setMaterialName("Examples/LightRibbonTrail"); trail->setTrailLength(400); mSceneMgr->getRootSceneNode()-> createChildSceneNode()->attachObject(trail); // Create nodes for trail to follow SceneNode* animNode = mSceneMgr->getRootSceneNode()-> createChildSceneNode(); animNode->setPosition(50,30,0); Animation* anim = mSceneMgr->createAnimation("an1", 14); anim->setInterpolationMode(Animation::IM_SPLINE); NodeAnimationTrack* track = anim->createNodeTrack(1, animNode); TransformKeyFrame* kf = track->createNodeKeyFrame(0); kf->setTranslate(Vector3(50,30,0)); kf = track->createNodeKeyFrame(2); kf->setTranslate(Vector3(100, -30, 0)); kf = track->createNodeKeyFrame(4); kf->setTranslate(Vector3(120, -100, 150)); kf = track->createNodeKeyFrame(6); kf->setTranslate(Vector3(30, -100, 50)); kf = track->createNodeKeyFrame(8); kf->setTranslate(Vector3(-50, 30, -50)); kf = track->createNodeKeyFrame(10); kf->setTranslate(Vector3(-150, -20, -100)); kf = track->createNodeKeyFrame(12); kf->setTranslate(Vector3(-50, -30, 0)); kf = track->createNodeKeyFrame(14); kf->setTranslate(Vector3(50,30,0)); AnimationState* animState = mSceneMgr->createAnimationState("an1"); animState->setEnabled(true); mAnimStateList.push_back(animState); trail->setInitialColour(0, 1.0, 0.8, 0); trail->setColourChange(0, 0.5, 0.5, 0.5, 0.5); trail->setInitialWidth(0, 5); trail->addNode(animNode); // Add light Light* l2 = mSceneMgr->createLight("l2"); l2->setDiffuseColour(trail->getInitialColour(0)); animNode->attachObject(l2); // Add billboard BillboardSet* bbs = mSceneMgr->createBillboardSet("bb", 1); bbs->createBillboard(Vector3::ZERO, trail->getInitialColour(0)); bbs->setMaterialName("Examples/Flare"); animNode->attachObject(bbs); } 首先,RibbonTrail创建了两个链,每个最多包括80个元素,尾巴长400个世界单位。创建了一个结点animNoade。为这个结点创建了一个动画,使得这个结点可以根据关键帧的设计在场景中不断变化位置。并把一个RibbonTrail与这个结点联结起来,于是RibbonTrail可与animNode一起运动。又创建了一个灯,并联结到这个结点,灯随结点也一起运动,于是怪物头会有明暗变化。最后用一个布告板来形象表示刚创建的灯,因为灯在场景中是不可见的。因为灯被挂到animNode结点上,所以布告板bbs也挂到同样的结点上。当然别忘了使用了动画状态来推进动画。 粒子系统 ogre中的粒子系统既可用脚本描述,也可用代码完成。用粒子脚本定义的粒子系统实际上是个模板,因此它定义的粒子系统可在程序中方便地重用。 粒子系统与场景 粒子系统会被挂到场景结点上,因此,结点的平移,缩放,旋转会关联到粒子系统,影响粒子反射的向。 粒子会被发射到世界空间中,这意味着当场景移动时,它会牵连到发射器,但已经发射出去的粒子不受影响。假如需要这些粒子受结点的影响,可以把粒子发射到本地空间(local space)中。粒子系统不能无限制的发射粒子,它有一个限额(quota)。一旦到达限额,粒子系统不会再发射粒子,直到已经存在的粒子消亡。缺省的限额是10。 粒子系统约束(Bounds) 粒子系统的动态特征意味着它们的绑定盒必须规律地被重新计算。缺省情况下,ogre会在10秒之后,停止 更新绑定盒。可以用ParticleSystem::setBoundsAutoUpdated( bool autoUpdate, Real stopIn = 0.0f )来改变缺省行为。stopIn这个参数告诉ogre多长时间后停止更新。假如有个粒子系统,可以知道它的增长不会超过某个范围,可以事先用ParticleSystem::setBounds()设置绑定盒尺寸。这样做效率很高,如果无法事先确定粒子系统的增长情况,可先用setBounds()设定一个初始尺寸,而用setBoundsAutoUpdated()让它在一段时间之后更新。 粒子系统更新 对于粒子系统的更新,ogre采用适度启发式的策略。举例来说,当粒子系统不在视锥体之内,ogre仍会对粒子系统进行更新,这是考虑到不久之后,粒子系统有可能会重新进入视锥体之内。这就避免了这种情况下的视觉上的不和谐。但是出于性能上的考虑,当粒子系统退出视锥体一段时间之后,粒子确实会停止更新。这又会碰到上面的问题:被冻结的粒子系统突然重新进入视锥体的情况。ogre提供了一个所谓的 "fast-forward"机制,允许粒子系统在被冻结之后,快速超越当前状态。这种特性也可以用在刚创建的粒子系统,使它们状态提前一段时间,使用的方法是ParticleSystem::fastForward (); 粒子系统排序 可以指示ogre根据与相机之间的距离,对粒子进行排序。虽然这会影响性能,但有时不得不用。在烟的 例子中,不使用排序的结果是,从烟的顶部依然清晰地看到火苗,而使用了排序之后火苗被烟雾模糊掉了。显然后者更加真实。 发射器 点发射器从空间中单一点发射粒子。box发射器可以从规则四方体的任何位置发射粒子。cylinder定义了一个圆柱体。ellipsoid定义了一个椭球体。hollow elipsoid只是椭球体的外壳。ring只出平面圆环的边发射。被发射粒子的速度,方向也可以配置。粒子系统会被挂到场景结点上,因此发射器与父结点有一个相对的位置。粒子通常不会沿直线发射,它们在发射器方向的一个锥内发射,有一个angle参数来定义。假如希望沿直线发射,angle应该设为0,假如希望全方向发射,angle设为180, 90表示会在方向向量的半球内随机发射。 发射率用 粒子数/秒 表示。发射器可以按某个发射率发射,也可以使用一个范围内的随机值。粒子可 以有固定的生命期,也可以从一个范围随机指定。颜色也一样,固定值,随机值都可以。也可以在运动时,以插件的形式提供定制发射器,这是扩展ogre粒子系统最简单的方法。 影响器 粒子一旦被发射到世界中,影响器可被用来影响粒子的运动路径与生命期。 LinearForce:加一个力到粒子上,力是一个向量,有方向与大小(模)。 ColourFader:用于改变粒子颜色。表示每秒减少的值,是一个绝对值。 ColorFader2:与ColourFader相似,但是粒子生命到到达其生命期的某个阶段时,可以转换到另一个褪色函数。 ColourInterpolator:与上面两个相似,但是它最多可以有6个阶段,分别对每个阶段的时间与颜色进行定义,然后不同阶段之间进行插值,这与关键帧动画的思想有点像。 Scaler:用来缩放粒子尺寸,以时间为函数来定义一个缩放因子。 Rotator:通过一组随机数量,或是随机速率来旋转粒子的纹理,这些被定义在某个范围之内。 colourImage:从图像中攻取颜色,方向从左到右,适合一维纹理 。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值