osgParticle示例简单的演示了在osg中使用粒子系统的效果,用到了osgParticle库中的相关类,在osgParticle中主要有:

(以下部分材料摘取自osg向场景中添加osgParticle粒子效果一文,Google了一下未找到原创作者,贴出转载地址,在此谢过原创作者~)

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

粒子系统(osgParticle::ParticleSystem)- 维护并管理一系列粒子的生成,更新,渲染和销毁。粒子系统类继承自Drawable类。粒子的渲染控制因此与其它Drawable对象的渲染类似:控制其渲染属性StateAttribute即可。OSG提供了一个方便的函数以允许用户控制三个常用的渲染状态属性。方法setDefaultAttributes可以用于指定材质(或者指定为NULL以禁用材质),允许/禁止附加的图像融合,允许/禁止光照。

粒子(osgParticle::Particle)- 粒子系统的基本单元。粒子类同时具有物理属性和图像属性。它的形状可以是任意的点(POINT),四边形(QUAD),四边形带(QUAD_TRIPSTRIP),六角形(HEXAGON)或者线(LINE)。每个粒子都有自己的生命周期。生命周期也就是每个粒子可以存活的秒数。(生命周期为负数的粒子可以存活无限长时间)所有的粒子都具有大小(SIZE),ALPHA值和颜色(COLOR)属性。每一组粒子都可以指定其最大和最小值。为了便于粒子生命周期的管理,粒子系统通过改变生命周期的最大和最小值来控制单个粒子的渲染。(根据已经消耗的时间,在最小和最大值之间进行线性插值)
程序员也可以自行指定最小到最大值的插值方法。

放置器(osgParticle::Placer)- 设置粒子的初始位置。用户可以使用预定义的放置器或者定义自己的放置器。已定义的放置器包括:点放置器PointPlacer(所有的粒子从同一点出生),扇面放置器SectorPlacer(所有的粒子从一个指定中心点,半径范围和角度范围的扇面出生),以及多段放置器MultiSegmentPlacer(用户指定一系列的点,粒子沿着这些点定义的线段出生)。

发射器(osgParticle::Shooter)- 指定粒子的初始速度。RadialShooter类允许用户指定一个速度范围(米/秒)以及弧度值表示的方向。方向由两个角度指定:theta角 - 与Z轴夹角,phi角 - 与XY平面夹角。

计数器(osgParticle::Counter)- 控制每一帧产生的粒子数。RandomRateCounter类允许用户指定每帧产生粒子的最大和最小数目。

标准放射极(osgParticle::ModularEmitter)- 一个标准放射极包括一个计数器,一个放置器和一个发射器。它为用户控制粒子系统中多个元素提供了一个标准机制。

粒子系统更新器(osgParticle::ParticleSystemUpdater)- 用于自动更新粒子。将其置于场景中时,它会在拣选遍历中调用所有“存活”粒子的更新方法。

标准编程器(osgParticle::ModularProgram)- 在单个粒子的生命周期中,用户可以使用ModularProgram实例控制粒子的位置。ModularProgram需要与Operator对象组合使用。

计算器(osgParticle::Operator)- 提供了控制粒子在其生命周期中的运动特性的方法。用户可以改变现有Operator类实例的参数,或者定义自己的Operator类。OSG提供的Operator类包括:AccelOperator(应用常加速度),AngularAccelOperator(应用常角加速度),FluidFrictionOperator(基于指定密度和粘性的流体运动进行计算),以及ForceOperator(应用常力)。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

接下来看代码:

首先代码中创建了一个Operator的子类,用来模拟涡流的效果,这个操作类会被添加到Program中从而对粒子系统中的每一个粒子产生作用:

  1. void operate(osgParticle::Particle *P, double dt)
  2. {
  3. float l = xf_axis_ * (P->getPosition() - xf_center_);
  4. osg::Vec3 lc = xf_center_ + xf_axis_ * l;
  5. osg::Vec3 R = P->getPosition() - lc;
  6. osg::Vec3 v = (R ^ xf_axis_) * P->getMassInv() * intensity_;
  7.  
  8. osg::Vec3 newpos = P->getPosition() + v * dt;
  9. P->setPosition(newpos);
  10. }

由于Operator是一个纯虚类,子类必须要重载它的operator方法。此外子类也可以重载beginOperator方法,实现在操作粒子之前完成一些准备工作。

下面我们看看create_simple_particle_system这个函数,它完整演示了最简单的创建粒子效果的步骤:

  1. //首先创建粒子系统对象
  2. osgParticle::ParticleSystem *ps = new osgParticle::ParticleSystem;
  3. ps->setDefaultAttributes("", true, false);
  4. //设置Emitter的参数(设置发射数量)
  5. osgParticle::ModularEmitter *emitter = new osgParticle::ModularEmitter;
  6. emitter->setParticleSystem(ps);
  7. osgParticle::RandomRateCounter *rrc =
  8. static_cast<osgParticle::RandomRateCounter *>(emitter->getCounter());
  9. rrc->setRateRange(20, 30);
  10. root->addChild(emitter);
  11. //将离子系统添加到叶节点
  12. osg::Geode *geode = new osg::Geode;
  13. geode->addDrawable(ps);
  14. root->addChild(geode);

在create_complex_particle_system中只是设置了更多的参数,同时添加了一个作用于粒子系统的Program,并在里面添加了很多的operator,整个设置过程还是一样的

  1. //设置Emitter更多的参数
  2. osgParticle::ModularEmitter *emitter = new osgParticle::ModularEmitter;
  3. emitter->setParticleSystem(ps);
  4.  
  5. osgParticle::RandomRateCounter *counter = new osgParticle::RandomRateCounter;
  6. counter->setRateRange(60, 60);
  7. emitter->setCounter(counter);
  8.  
  9. osgParticle::SectorPlacer *placer = new osgParticle::SectorPlacer;
  10. placer->setCenter(8, 0, 10);
  11. placer->setRadiusRange(2.5, 5);
  12. placer->setPhiRange(0, 2 * osg::PI);
  13. emitter->setPlacer(placer);
  14.  
  15. osgParticle::RadialShooter *shooter = new osgParticle::RadialShooter;
  16. shooter->setInitialSpeedRange(0, 0);
  17. emitter->setShooter(shooter);
  18.  
  19. root->addChild(emitter);
  20.  
  21. //添加Operator到Program之中
  22. osgParticle::ModularProgram *program = new osgParticle::ModularProgram;
  23. program->setParticleSystem(ps);
  24.  
  25. osgParticle::AccelOperator *op1 = new osgParticle::AccelOperator;
  26. op1->setToGravity();
  27. program->addOperator(op1);
  28.  
  29. VortexOperator *op2 = new VortexOperator;
  30. op2->setCenter(osg::Vec3(8, 0, 0));
  31. program->addOperator(op2);
  32.  
  33. osgParticle::FluidFrictionOperator *op3 = new osgParticle::FluidFrictionOperator;
  34. op3->setFluidToAir();
  35. program->addOperator(op3);
  36.  
  37. root->addChild(program);
  38.  
  39. osg::Geode *geode = new osg::Geode;
  40. geode->addDrawable(ps);
  41.  
  42. root->addChild(geode);

create_animated_particle_system创建了一个切换纹理的粒子效果动画:

这样粒子的纹理会在这些纹理切片之中不停地进行切换:

  1. //设置纹理所使用的纹理切片
  2. pexplosion.setTextureTileRange(8, 8, 0, 15);
  3. psmoke.setTextureTileRange(8, 8, 32, 45);

其他部分的设置与上面一致。

最后一个步骤,我们需要将这些粒子系统添加到一个Updater之中,由Updater再场景的拣选遍历中更新粒子系统

  1. osgParticle::ParticleSystem *ps1 = create_simple_particle_system(root);
  2. osgParticle::ParticleSystem *ps2 = create_complex_particle_system(root);
  3. osgParticle::ParticleSystem *ps3 = create_animated_particle_system(root);
  4.  
  5. osgParticle::ParticleSystemUpdater *psu = new osgParticle::ParticleSystemUpdater;
  6. psu->addParticleSystem(ps1);
  7. psu->addParticleSystem(ps2);
  8. psu->addParticleSystem(ps3);
  9.  
  10. root->addChild(psu);

/************************************************************************************************/

粒子

OSG中使用osgParticle::Particle这个类,来表示粒子。 
而本例子中,使用的是默认的粒子,所以没出现粒子。 
如果要产生自定义的粒子,则要自己定义一个Particle对象,然后将这个Particle对象设置为粒子产生器的模板。 
这是通过函数Emitter::setParticleTemplate来实现的。

粒子产生

OSG中粒子的产生,使用的是一个叫做粒子发射器(Emiter)的东东。使用的类叫做osgParticle::Emitter。 
这个粒子发射器,不停地产生新的粒子,每个粒子都从粒子产生器的初始位置发出, 
然后以一定的初始发射角度和初始发射速度向外发出。 
这里使用的是OSG自己内置的一个标准发射器osgParticle::ModularEmitter。

粒子管理

粒子发射器,不停地发射粒子,这些发射出来的粒子,如何管理呢? 
这是通过粒子系统来进行的。 
对应的类叫osgParticle::ParticleSystem。 
粒子发射器,发射出来粒子后,交个粒子系统,就不用操心了。 
这个转交的过程,是用过emitter->setParticleSystem(ps)实现的。

粒子显示

由于粒子系统本身,只负责管理粒子,并不负责显示粒子,所以,还需要一个东西,将粒子显示出来。 
OSG中是通过osg::Geode将粒子系统显示出来。 
然后通过geode->addDrawable(ps)将粒子系统与Geode结合起来。

粒子更新

由于粒子是在不停地运动,所以需要不停地更新。 
粒子系统的更新是通过类osgParticle::ParticleSystemUpdater来实现的。 
然后通过psu->addParticleSystem(ps);来将更新器和粒子系统进行关联。

最后,将粒子系统,加到场景中,需要添加三个东西到场景树中:发射器,显示的Geode,更新器。

[粒子特效]osg的自带粒子系统osgParticle::ParticleSystem的更多相关文章

  1. [原][粒子特效][spark]粒子系统system、主节点group、渲染器render

    深入浅出spark粒子特效连接:https://www.cnblogs.com/lyggqm/p/9956344.html system: A class defining a complete sy ...

  2. Three.js粒子特效,shader渲染初探(一篇非常详细的介绍)

    Three.js粒子特效,shader渲染初探 转载来源:https://juejin.im/post/5b0ace63f265da0db479270a 这大概是个序 关于Three.js,网上有不多 ...

  3. Qt移动应用开发(四):应用粒子特效

    Qt移动应用开发(四):应用粒子特效 上一篇文章介绍了Qt Quick是如何对帧动画进行支持的.帧动画的实现离不开状态机.而状态机.动画和状态切换(transitions)则是Qt框架的核心内容.也就 ...

  4. UGUI中显示粒子特效

    今天在UGUI上显示粒子特效的时候遇到的一些问题,Mark一下.原理:修改特效中每一个ParticleSystem的Layer为UI,并且把ParticleSystemRenderer.sorting ...

  5. UGUI中粒子特效与UI的遮挡问题

    问题背景: 在做主线任务时发现完成任务后的特效显示穿透上面的UI层,不美观,策划不乐意了,抓紧解决下 解决思路: 首先讲下影响渲染顺序的因素: 能够影响渲染顺序的因素有:1.Camera Depth  ...

  6. 利用OSG实现模拟飞机尾迹-粒子系统

    利用OSG实现模拟飞机尾迹-粒子系统 粒子系统简介:         粒子系统是用于不规则模糊物体建模及图像生成的一种方法.         粒子系统是一种过程模型,即利用各种计算过程生成模型各个体素 ...

  7. Unity:控制粒子特效的移动方向

    前几天在项目中遇到一个问题,需求是界面中先展示一段闪光特效,停顿一段时间后特效飞往一个固定的位置然后消失,类似于跑酷游戏吃到金币后金币飞往固定的金币数值显示框那种效果(具体是通过特效来实现还是直接通过 ...

  8. Mask裁切UI粒子特效或者3D模型

    刚好前几天有人问我这个问题,再加上新项目也可能用,所以这两天就研究了一下.其实如果粒子特效 和3D模型 都用RenderTexture来做的话就不会有裁切的问题,但是粒子特效用RenderTextur ...

  9. 【Stage3D学习笔记续】真正的3D世界(五):粒子特效

    先看效果,按下空格键添加粒子特效: 一般而言粒子特效的实现都是比较复杂的,且不说实现粒子特效的编码和设计,光是编写一个粒子编辑器就不是简单的一件事,但是作者使用了很取巧的方式来完成,我们接下来深入代码 ...

随机推荐

  1. opencv之颜色过滤只留下图片中的红色区域

    如图,这次需要在图片中找到卷尺的红色刻度,所以需要对图像做过滤,只留下红色部分. 一开始的想法是分别找到RGB值,然后找到红色区域的部分保留就可以了,不过好像很难确定红色区域的RGB取值范围,所以要把 ...

  2. testng入门教程16数据驱动(把数据写在xml)

    testng入门教程16数据驱动(把数据写在xml) testng入门教程16数据驱动(把数据写在xml)把数据写在xml文件里面,在xml文件右键选择runas---testng执行 下面是case ...

  3. linux命令:压缩解压命令

    压缩解压命令:gzip 命令名称:gzip 命令英文原意:GNU zip 命令所在路径:/bin/gzip 执行权限:所有用户 语法:gzip 选项  [文件] 功能描述:压缩文件 压缩后文件格式:g ...

  4. EntityFramework包含作用

    System.Data.Entity.Infrastructure.DbQuery的引用需要加入上面那个包

  5. 关于在ASP.NET中使用JavaScript的建议

    一个很恼人的情况,就是当你使用JS在一个ASP,NET应用程序中引用一个在模板页初始化的服务器控件的时候: 比如,我们在模板页有一个TextBox的服务器控件,而且我们想要去获取他的Text:如果你使 ...

  6. 新版.Net开发必备十大工具(转)

    Snippet Compiler Snippet Compiler是一个基于 Windows 的小型应用程序,你可以通过它来编写.编译和运行代码.如果你具有较小的代码段,并且你不想创建完整的 Visu ...

  7. linux常用命令:killall 命令

    killall命令用进程的名字来杀死进程. 1.命令格式:    killall [ -egiqvw ] [ -signal ] [进程名称] 格式:killall -<signame> ...

  8. python的数据结构之数字和字符串(四)

    一.数字 Python Number 数据类型用于存储数值.数据类型是不允许改变的,这就意味着如果改变 Number 数据类型的值,将重新分配内存空间. Python 支持四种不同的数值类型: 整型( ...

  9. 面试题之一(Spring和堆栈和逻辑运算符)

    1.&和&&区别? 都是逻辑运算符,都是判断两边同时为真,否则为假:但&&当第一个为假时,后面就不执行,而&则还是要继续执行,直至结束: ——————— ...

  10. Python入门之Pycharm开发中最常用快捷键

    要查阅Pycharm的快捷键,当然要看官方文档,https://www.jetbrains.com/help/pycharm/mastering-keyboard-shortcuts.html 编辑类 ...