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)

未完待續。。。。。






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM