在人们使用虚拟现实技术模拟真实世界的过程中,不规则物体的模拟一直是一个重要的课题.但不规则物体由于外形多变、边界模糊,很难通过传统的建模方式表现出来.针对这个问题,1983年,Reeves首次提出了粒子系统的概念[1].由于粒子系统自身高度灵活的特点[2],其在不规则物体上的模拟更加逼真生动.在虚拟现实、三维建模、电影动画制作、数据可视化等方面占据着越来越重要的地位.而在学术研究上,通过粒子系统对自然景物的模拟也一直是众多学者热点研究方向.周迎春等通过求解动力学方程成功实现了对战场烟雾的特效仿真[3].潘秋羽等提出了一种基于粒子系统的快速云三维仿真算法[4].肖凯涛等在Unity3D中实现了粒子系统在复杂风场和湍流场中的变化[5],吕雪等提出了一种基于GPU粒子系统的烟花模拟方法[6].文献[7-8]利用粒子系统实现了实时降雨降雪的模拟和海洋环境的仿真.文献[9]基于OpenGL图形库完成了喷泉的模拟.上述研究有的研究了自然景物模拟的算法,有的是对粒子系统的算法做出了改进,但是很少有人将自然景物模拟算法得出的数据与粒子系统相结合模拟自然景物.本文就是在这种情况下,以Unreal Engine 4(UE 4) 的粒子系统为基础,研究了粒子系统模拟自然景物的参数,并重点研究了粒子系统在引擎内部以及与外部的通信方式,使得粒子系统能够通过读取外部驱动的算法数据并与内部参数相结合模拟自然景物.
UE 4是EpicGames公司最新推出的游戏引擎, 其Cascade粒子系统编辑器提供了创建精细复杂的火焰、烟雾、雪、尘土、泥土、碎石等所需的工具.其强大的渲染效果和逼真的特效使得设计者创建出无与伦比的效果.它同时提供了Matinee过场动画工具集,可以把场景中的细节设置为最佳效果,令场景属性随着时间进行改变,制作无与伦比的电影片段.正是基于此,本文选择了UE 4为开发平台.
1 粒子系统 1.1 粒子系统的基本原理粒子系统的基本原理是通过大量的具有一定属性的点粒子、线粒子或面粒子来模拟形状不规则且多变的场景.在UE 4中,粒子系统由多个发射器组成,每个发射器包括多个模块,可以根据需求添加和删除模块.每个发射器发射特定的粒子,多个发射器共同发射不同属性粒子组成一个完整的粒子系统,可以创建各种复杂的特效.
![]() |
图 1 粒子系统 Figure 1 Particle system |
粒子的基本属性主要有以下7种:
1) Material:存在于Required模块,是应用在粒子中的材质.
2) Rate:存在于Spawn模块,指的是粒子的生成率,也就是粒子系统每秒发射的粒子数量.
3) Lifetime:存在于Lifetime模块,单个粒子的生命周期(以秒为单位),数值越大,粒子存活时间越长.
4) StartSize:存在于InitialSize模块,指的是单个粒子的初始大小.
5) StartVelocity:存在于InitialVelocity模块,指的是单个粒子的初始速度.
6) ColorOverLife:存在于ColorOverLife模块,指的是粒子的颜色随时间的变化而变化.
7) AlphaOverLife:存在于ColorOverLife模块,指的是粒子的透明度随时间的变化而变化.
1.3 参数的数据类型UE 4粒子系统参数的数据类型为分布(Distribution),分布是一组数据类型,这些数据类型可以是常量值、某个范围内的随机值、沿着曲线上的插值及由参数驱动的值,这些都为UE 4提供了很好的灵活性.多数粒子属性都使用DistributionFloat(浮点分布)和DistributionVector (向量分布)类型.
Constant(常量):用于为常量属性提供一个值.
Uniform(均匀分布):为属性提供一定范围内的值.当计算时,在选中的范围随机地设置返回的值.
ConstantCurve(常量曲线分布):用于为分布在曲线编辑器上随时间变化的属性提供值.时间是绝对的(随着发射器的生命周期)或相对的(随着单个粒子的生命周期)取决于使用分布的模块.
UniformCurve(均匀曲线分布):用于为分布在曲线编辑器上随时间变化的属性提供一定范围的值.在两条曲线范围内随机设置返回值.
ParticleParam(粒子参数分布):这种类型用于为发射器的参数进行代码设置.它提供了把输入值从一个范围映射到另一个范围的功能,在“Cascade-空间”中调整参数而不需要更新游戏形代码.定义一个可靠的输入范围,便可以通过Output(输出)映射自由地调整属性.
2 UE 4粒子系统的内部通信 2.1 设置参数粒子系统参数的数据类型中,ParticleParam(粒子参数)是其中比较特殊的一种,它允许操作者通过外部的蓝图等模块控制参数,从而改变粒子系统的状态.本文以火焰粒子的ColorOverLife(颜色随生命周期变化)参数为例.该参数存在于火焰发射器中的ColorOverLife模块.选择该模块后,在细节面板上可以找到ColorOverLife参数的数据类型.将该数据类型设置为Distribution Vector Particle Parameter;命名为Change in color.
将火焰粒子放置在关卡中,在细节面板的Particle层次下找到Instance Parameter并添加元素,同样命名为Change in color,Param Type模式选择Color.
![]() |
图 2 设置参数 Figure 2 Setting parameters |
选择关卡中的火焰粒子,在细节面板中创建火焰粒子类,命名为P_Fire_BP,打开类的蓝图编辑器进行编程.
数据的内部通信是通过变量进行传递,在类中首先要设置参数变量.在这里以颜色为例,所以创建Vector类型的数据变量, 并将其设置为“显示到Matinee”(此设置可以将变量参数暴露给Matinee以进行修改)和“可编辑”(此设置可以在蓝图实例上公开编辑此变量).参数的改变主要是通过Set Color Parameter模块对火焰粒子的颜色进行修改,该模块以Particle System Component(粒子系统组件)为目标.
2.3 Matinee动画设置参数变量在UE 4中添加Matinee过场动画,点击选中关卡中的P_Fire_BP类,在Matinee中创建新组,命名为“Color Variance”.右键点击选中Color Variance,添加新的Vector Property Track,命名为Color.在选中Color轨迹的前提下,移动黑色光标选择时间点,通过Enter键添加关键帧.将Color轨迹的右下角曲线图标点亮,通过Matinee的曲线编辑器对参数变量进行设置.出于举例的特殊性,本文在2秒的时间内设置了3个关键帧.
在Matinee的细节面板中可以根据需要选择是否循环播放,通过设置各种参数随时间改变粒子系统的状态;也可以在蓝图中设置播放方式以及播放时间等来创建各种想要的特效.通过蓝图可视化编程以及Matinee初步实现了数据在UE 4粒子系统内部的通信.图 3为仿真结果.
![]() |
图 3 火焰颜色变化 Figure 3 Color change of the flame |
UE 4通过蓝图与Matinee实现了粒子系统的内部通信,但这对于粒子系统的数据传输是有局限性的,制约了UE 4粒子系统与外部的数据传输.以VS为开发环境,以C++为开发语言,编程实现了UE 4粒子系统与外部数据的传输.
3.1 粒子系统的接口函数粒子系统通过参数改变其状态,数据传输的前提是实现参数的接口.在UE 4中通过创建不同的类实现各个模块的功能.在UE 4编辑器中创建新的C++类,继承Actor父类,在cpp文件中编写粒子系统的接口类.以火焰粒子系统为例:
首先绑定创建的初始状态的粒子系统:
FName EffectName="/Game/StarterContent/Particles/P_Fire.P_Fire"; //火焰粒子的路径
UParticleSystem *MyEffect=Cast<UParticleSystem>(StaticLoadObject(UParticleSystem::StaticClass(), NULL, *EffectName.ToString())); //绑定火焰粒子
编写修改粒子系统参数的接口函数,在接口函数中,通过MyEffect->Emitters[i]函数(定位粒子系统中的发射器)找到要修改的发射器Emitters[i],在发射器中通过MyEmitter->LODLevels[i]函数(定位发射器中的模块)找到要修改的模块Module,在模块下找到要修改的参数.将接口函数中接收的数据赋值给要修改的参数.不同的参数对应不同的接口函数.其中接口函数接收的数据类型要和修改的参数的数据类型一致.以下为部分接口函数:
void SetActorScale3D(FVector NewScale3D); //粒子系统的整体大小
void SetActorRelativeLocation(FVector NewRelativeLocation); //粒子系统在关卡中的相对位置
void SetActorRelativeRotation(FRotator NewRelativeRotation); //粒子系统的角度
void SetEmitteroneSpawnRate(float NewSpawnRate); //粒子系统第一个发射器的速率
void SetEmitteroneLifeTime(float NewLifeTime); //粒子系统第一个发射器的生命周期
void SetEmitteroneStartSize(FVector NewStartSize); //粒子系统第一个发射器的初始大小
void SetEmitteroneStartVelocity(FVector NewStartVelocity); //粒子系统第一个发射器的初始速度
void SetEmitteroneColorOverLife(MyColor CL); //粒子系统第一个发射器的颜色
void SetEmitteroneAlphaOverLife(MyAlpha CL); //粒子系统第一个发射器的透明度
粒子系统发射器中的每一个参数对应一个函数,其中每一个函数都可以接收数据,并能够将数据传递到相应的的参数中,改变粒子系统的模拟状态.
3.2 外部文本数据的读取UE 4中进行文件I/O操作时,为了其可移植性,不能直接使用C++标准库,为此UE 4提供了IPlatformFile(平台文件I/O接口), 通过IPlatformFile可以实现粒子系统与外部文本的接口通信.
在文本文件中,数据的类型为浮点型.每一行的数据表示要修改的参数,例如,每1行的第1个数据是要修改的速率,第2~第4个数据是要修改的初始大小……,每个数据与数据之间通过空格隔开.如图 4所示.
![]() |
图 4 文本中的数据格式 Figure 4 Data format in text |
设置好文本中数据的格式后,通过FPlatformFileManager:Get().GetPlatformFile().FileExists(*CompleteFilePath)函数(管理文本的函数,通过路径绑定文本文件,其中CompleteFilePath为文本的路径)绑定文本文件.将文本文件中的数据通过LoadFileToString函数(将文本中的数据缓存成字符串的格式)缓存下来并转换成字符串格式.
根据空格(“”)读取一行中的每一个数据,将数据通过Atof函数(转换数据格式的函数)转换成参数所需要的数据类型,赋值给粒子系统接口函数头中接收的参数.读取完一行后,根据换行函数读取下一行直到最后一行, 最终读取完成整个文本中的数据.
图 5的3个示例分别展示了通过改变和读取文本文件中的数据而得到的仿真结果,作者通过读取外部的数据进行了火焰燃烧的仿真实验.在本次仿真中,主要对其中的4个参数进行了改变:速率、初始大小、生命周期、初始速度.其中文本中的数据来源于外部的数据解算模块,UE 4每隔0.25秒读取一次文本数据,模拟了火焰从开始燃烧到剧烈燃烧的场景.
![]() |
图 5 文本文件数据控制的火焰燃烧 Figure 5 Fire controlled by text file data |
可以看出,采用这种方法,可以很好地实现粒子系统与外部数据的通信,可以将外部的解算模块得出的数据与粒子系统中的参数相结合.而通过文本读取数据的方式既能达到实时的效果,又可以较容易地与外部解算模块或软件结合使用,避免了不同软件需要不同的通信协议的问题,为实现基于外部数据驱动的模拟仿真打下基础.
4 结论UE 4粒子系统内部间的通信以及外部数据通信的实现,使得我们可以通过外部的数据控制粒子系统的模拟效果,既可以更加逼真地模拟现实生活中的场景和事件,也提高了其模拟自然景物的真实性和有效性.这也为基于数据解算和驱动的仿真提供了有效手段.
[1] |
REEVES W T. Particle system: a technique for modeling a class of fuzzy objects[J]. Acm siggraph computer graphics, 1983, 17(3): 359-375. DOI:10.1145/964967 ( ![]() |
[2] |
刘刚. 基于CUDA平台和粒子系统技术的实时烟花模拟[D]. 上海: 上海大学, 2013. http://cdmd.cnki.com.cn/Article/CDMD-10280-1014007989.htm
( ![]() |
[3] |
周迎春, 房凌晖, 郑翔玉, 等. 基于粒子系统的虚拟战场烟雾特效仿真[J]. 计算机仿真, 2015, 32(7): 417-420. ( ![]() |
[4] |
潘秋羽, 毕硕本, 陆良虎, 等. 基于粒子系统三维动态云的快速仿真算法[J]. 系统仿真学报, 2014, 26(1). ( ![]() |
[5] |
肖凯涛, 徐路程, 李红辉. 粒子系统在复杂风场及湍流场中的实现[J]. 北京交通大学学报, 2015, 39(2): 13-21. DOI:10.11860/j.issn.1673-0291.2015.02.003 ( ![]() |
[6] |
吕雪, 刘丽, 王俊杰, 等. 基于GPU粒子系统的烟花模拟[J]. 计算机工程与设计, 2013, 34(3): 989-992. ( ![]() |
[7] |
刘芳, 佟巍. 基于粒子系统的实时降雨、降雪模拟[J]. 计算机系统应用, 2015, 24(6): 19-23. ( ![]() |
[8] |
王琪, 邓会亨, 马璐. 基于粒子系统的海洋环境仿真[J]. 计算机系统应用, 2013, 22(2): 230-232. ( ![]() |
[9] |
刘韬. 基于OpenGL喷泉粒子系统设计与实现[J]. 科技视界, 2016(11): 287-288. DOI:10.3969/j.issn.2095-2457.2016.11.219 ( ![]() |