zoukankan      html  css  js  c++  java
  • QT高级运用之粒子模拟(Particle Simulations)

    粒⼦模拟是计算机图形技术的可视化图形效果。典型的效果有:落叶,⽕焰,爆炸,流星,云等等。它不同于其它图形渲染, 粒⼦是基于模糊来渲染。它的结果在基于像素下是不可预测的。粒⼦系统的参数描述了随机模拟的边界。传统的渲染技术实现粒⼦渲染效果很困难。有⼀个好消息是你可以使⽤QML元素与粒⼦系统交互。同时参数也可以看做是属性,这些参数可以使⽤传统的动画技术来实现动态效果。

    概念(Concept)

    粒⼦模拟的核⼼是粒⼦系统(ParticleSystem),它控制了共享时间线。⼀个场景下可以有多个粒⼦系统,每个都有⾃⼰独⽴的时间线。⼀个粒⼦使⽤发射器元素(Emitter)发射,使⽤粒⼦画笔(ParticlePainter)实现可视化, 它可以是⼀张图⽚,⼀个QML项或者⼀个着⾊项(shader item)。⼀个发射器元素( Emitter) 也提供向量来控制粒⼦⽅向。 ⼀个粒⼦被发送后就再也⽆法控制。 粒⼦模型提供粒⼦控制器( Affector) , 它可以控制已发射粒⼦的参数。
    在⼀个系统中, 粒⼦可以使⽤粒⼦群元素( ParticleGroup) 来共享移动时间。 默认下, 每个例⼦都属于空( “”) 组。

    • 粒⼦系统(ParticleSystem) - 管理发射器之间的共享时间线。
    • 发射器(Emitter) - 向系统中发射逻辑粒⼦。
    • 粒⼦画笔(ParticlePainter) - 实现粒⼦可视化。
    • ⽅向(Direction) - 已发射粒⼦的向量空间。
    • 粒⼦组(ParticleGroup) - 每个粒⼦是⼀个粒⼦组的成员。
    • 粒⼦控制器( Affector) - 控制已发射粒⼦。

    简单的模拟( Simple Simulation)

    让我们从⼀个简单的模拟开始学习。Qt Quick使⽤简单的粒⼦渲染⾮常简单。下⾯是我们需要的:

    • 绑定所有元素到⼀个模拟的粒⼦系统( ParticleSystem) 。
    • ⼀个向系统发射粒⼦的发射器( Emitter) 。
    • ⼀个ParticlePainter派⽣元素, ⽤来实现粒⼦的可视化。
    1. importQtQuick2.6
    2. importQtQuick.Window2.2
    3. importQtQuick.Particles2.0
    4. Window{
    5. visible:true;
    6. id: root;
    7. width:480;
    8. height:160;
    9. color:"#1f1f1f";
    10. ParticleSystem{
    11. id: particleSystem;
    12. }
    13. Emitter{
    14. id: emitter;
    15. anchors.centerIn: parent;
    16. width:160;
    17. height:80;
    18. system: particleSystem;
    19. emitRate:10;//每S发送10个粒子
    20. lifeSpan:2000;//每个粒子生命周期为1000ms
    21. lifeSpanVariation:500;//一个已发射粒子的生命周期变化是500ms
    22. size:16;//一个粒子开始的大小是16像素
    23. endSize:32;//生命周期结束时的大小是32个像素( endSize:32)
    24. // Tracer {colro: "green"};
    25. }
    26. ImageParticle{
    27. source:"/blur.png";
    28. system: particleSystem;
    29. }
    30. }

    运⾏结果如下所⽰:

    我们使⽤⼀个480x160的矩形框作为我们的根元素和背景。 然后我们定义⼀个粒⼦系统(ParticleSystem)。这通常是粒⼦系统绑定所有元素的第⼀步。 下⼀个元素是发射器( Emitter),它定义了基于矩形框的发射区域和发射粒⼦的基础属性。发射器使⽤system属性与粒⼦系统进⾏绑定。
    在这个例⼦中,发射器每秒发射10个粒⼦( emitRate:10) 到发射器的区域,每个粒⼦的⽣命周期是1000毫秒( lifeSpan:1000) , ⼀个已发射粒⼦的⽣命周期变化是500毫秒( lifeSpanVariation:500) 。 ⼀个粒⼦开始的⼤⼩是16个像素( size:16) , ⽣命周期结束时的⼤⼩是32个像素( endSize:32) 。

    发射器发射逻辑粒⼦。⼀个逻辑粒⼦的可视化使⽤粒⼦画笔( ParticlePainter) 来实现, 在这个例⼦中我们使⽤了图像粒⼦( ImageParticle),使⽤⼀个图⽚链接作为源属性。
    图像粒⼦也有其它的属性⽤来控制粒⼦的外观。

    • 发射频率( emitRate) - 每秒粒⼦发射数( 默认为10个) 。
    • ⽣命周期( lifeSpan) - 粒⼦持续时间( 单位毫秒, 默认为1000毫秒) 。
    • 初始⼤⼩( size),结束⼤⼩( endSize)- 粒⼦在它的⽣命周期的开始和结束时的⼤⼩( 默认为16像素)。

    粒⼦参数( Particle Parameters)

    我们已经知道通过改变发射器的⾏为就可以改变我们的粒⼦模拟。粒⼦画笔被⽤来绘制每⼀个粒⼦。 回到我们之前的粒⼦中, 我们更新⼀下我们的图⽚粒⼦画笔( ImageParticle)。⾸先我们改变粒⼦图⽚为⼀个⼩的星形图⽚:

    粒⼦使⽤⾦⾊来进⾏初始化, 不同的粒⼦颜⾊变化范围为+/- 20%。

    1. color:'#FFD700'
    2. colorVariation:0.2

    为了让场景更加⽣动, 我们需要旋转粒⼦。 每个粒⼦⾸先按顺时针旋转15度, 不同的粒⼦在+/-5度之间变化。 每个例⼦会不断的以每秒45度旋转。每个粒⼦的旋转速度在+/-15度之间变化:

    1. rotation:15
    2. rotationVariation:5
    3. rotationVelocity:45
    4. rotationVelocityVariation:15

    最后, 我们改变粒⼦的⼊场效果。 这个效果是粒⼦产⽣时的效果, 在这个例⼦中, 我们希望使⽤⼀个缩放效果:
    entryEffect: ImageParticle.Scale
    现在我们可以看到旋转的星星出现在我们的屏幕上。

    代码:

    1. importQtQuick2.6
    2. importQtQuick.Window2.2
    3. importQtQuick.Particles2.0
    4. Window{
    5. visible:true;
    6. id: root;
    7. width:480;
    8. height:160;
    9. color:"black";
    10. ParticleSystem{
    11. id: particleSystem;
    12. }
    13. Emitter{
    14. id: emitter;
    15. anchors.centerIn: parent;
    16. width:160;
    17. height:80;
    18. system: particleSystem;
    19. emitRate:10;//每S发送10个粒子
    20. lifeSpan:1000;//每个粒子生命周期为1000ms
    21. lifeSpanVariation:500;//一个已发射粒子的生命周期变化是500ms
    22. size:16;//一个粒子开始的大小是16像素
    23. endSize:32;//生命周期结束时的大小是32个像素( endSize:32)
    24. // Tracer {colro: "green"};
    25. }
    26. ImageParticle{
    27. source:"/start.bmp";
    28. color:"#ffd700";
    29. colorVariation:0.2
    30. rotation:15
    31. rotationVariation:5
    32. rotationVelocity:45
    33. rotationVelocityVariation:15
    34. entryEffect:ImageParticle.Scale
    35. system: particleSystem;
    36. }
    37. }

    粒⼦⽅向( Directed Particle)

    我们已经看到了粒⼦的旋转, 但是我们的粒⼦需要⼀个轨迹。 轨迹由速度或者粒⼦随机⽅向的加速度指定, 也可以叫做⽮量空间。
    有多种可⽤⽮量空间⽤来定义粒⼦的速度或加速度:

    • ⾓度⽅向( AngleDirection) - 使⽤⾓度的⽅向变化。
    • 点⽅向( PointDirection) - 使⽤x,y组件组成的⽅向变化。
    • 目标⽅向( TargetDirection) - 朝着目标点的⽅向变化。

    让我们在场景下试着⽤速度⽅向将粒⼦从左边移动到右边。
    ⾸先使⽤⾓度⽅向( AngleDirection) 。 我们使⽤AngleDirection元素作为我们的发射器( Emitter) 的速度属性。

    1. velocity:AngleDirection{}

    粒⼦的发射将会使⽤指定的⾓度属性。 ⾓度值在0到360度之间, 0度代表指向右边。 在我们的例⼦中, 例⼦将会移动到右边, 所以0度已经指向右边⽅向。 粒⼦的⾓度变化在+/-15度之间:

    1. velocity:AngleDirection{
    2. angle:0
    3. angleVariation:15
    4. }

    现在我们已经设置了⽅向, 下⾯是指定粒⼦的速度。 它由⼀个梯度值定义,这个梯度值定义了每秒像素的变化。 正如我们设置⼤约640像素, 梯度值为100, 看起来是⼀个不错的值。 这意味着平均⼀个6.4秒⽣命周期的粒⼦可以穿越我们看到的区域。 为了让粒⼦的穿越看起来更加有趣, 我们使⽤magnitudeVariation来设置梯度值的变化, 这个值是我们的梯度值的⼀半:

    1. velocity:AngleDirection{
    2. ...
    3. magnitude:100
    4. magnitudeVariation:50
    5. }

    粒⼦画笔( Particle Painter)

    粒⼦控制( Affecting Particles)

    粒⼦组( Particle Group)

    总结( Summary)

    未完待续。。。。。





  • 相关阅读:
    格式化输出数字
    传教士经验
    集合
    替换
    连接
    填充
    取值
    分割
    创建日历和日期列表
    常用日期格式
  • 原文地址:https://www.cnblogs.com/mcumagic/p/5482519.html
Copyright © 2011-2022 走看看