Particle system that's both calculated and rendered on the GPU using the Metal framework
This is the most highly optimised version of my Swift and Metal particles system; managing over 40 fps with four million particles and four gravity wells. It manages this by rendering to a CAMetalLayer rather than converting a texture to a UIImage and by passing in four particle definitions per step with a float4x4 rather than a particle struct.
You can read about these recent changes at my blog:
- CAMetalLayer work: http://flexmonkey.blogspot.co.uk/2015/03/swift-metal-four-million-particles-on.html
- Use of float4x4: http://flexmonkey.blogspot.co.uk/2015/03/mind-blowing-metal-four-million.html
This branch wraps up all the Metal code into one class so that it's easily implemented in other projects. To create a new particle system object, instantiate an instance of ParticleLab
let particleLab = ParticleLab()
...and when ready, add it as a sublayer to your view:
view.layer.addSublayer(particleLab)
The class has four gravity wells with propeties such as position, mass and spin. These are set with the setGravityWellProperties method:
particleLab.setGravityWellProperties(gravityWell: .One, normalisedPositionX: 0.3, normalisedPositionY: 0.3, mass: 11, spin: -4)
particleLab.setGravityWellProperties(gravityWell: .Two, normalisedPositionX: 0.7, normalisedPositionY: 0.3, mass: 7, spin: 3)
particleLab.setGravityWellProperties(gravityWell: .Three, normalisedPositionX: 0.3, normalisedPositionY: 0.7, mass: 7, spin: 3)
particleLab.setGravityWellProperties(gravityWell: .Four, normalisedPositionX: 0.7, normalisedPositionY: 0.7, mass: 11, spin: -4)
Gravity well positions can be displayed by setting the showGravityWellPositions
property to true.
Classes can implement ParticleLabDelegate
interface which includes particleLabDidUpdate
. This method is invoked with each particle step and can be used, for example, for updating the position of gravity wells.