I've been working on my game and finding particle systems a big drain on performance, that is until I found a GPU particle example by Jonbro. (viewtopic.php?t=81865).
With his permission, I'm releasing an enhanced version with the following features:
Particle collision via distance field calculation.
Control over various parameters like spawn rate and particle type.
Particle stretching with velocity.
Multiple particle systems working alongside each other.
Multiple types of particles possible within a single system.
Multiple particle textures in a single system.
Translation and scaling of the particles within world space.
Delta time instead of lockstep velocity.
It requires a video card capable of 32 bit floating point textures, although it will run on 16f - it doesn't look good past a certain resolution. Your mileage may vary on mobiles and laptops. Some people have had problems with this system in the past but I had none between 3 different machines personally - although I haven't tested this using a modern AMD video card yet. I'm sure there are multiple issues and performance enhancements that could be made to this, but I've run out of time. I wanted to have it automatically re-compile particle shaders from strings to construct each particle system based on parameters for maximum efficiency.
GPU particles aren't as flexible as CPU systems, but they are a great deal faster. 1 million particles, each with individual collision and texture are no problem. Modern games typically combine light CPU particle systems with GPU particles to make up numbers.
The actual textures in memory storing all the particles:
The distance field:
This provides the collision normals for determining particle reflections. It's a fairly heavy shader pass but it doesn't need to run every frame. I have it set to reconstruct every 50ms, with the previous distance field interpolated with camera movement, which is sufficient for my game - it's not that bad running every frame, but I'd avoid it where possible.
Ideally for performance reasons you'll want to split up your particle effects instead of using one giant shader for all of them (although one system is much more efficient if you're using a lot of one particle). Each particle effect should have it's own shader unless it can reasonable share physics without overloading your shader with comparison statements.
When or If Love develops an asynchronous PBO/getPixel implementation, GPU particles may be used for more complicated purposes, like managing hundreds of thousands of objects which the CPU cannot and similar applications like that. I think in it's current state you could do liquid, but if you want to interact with it from the CPU that makes it difficult to do in real-time.
Known issues:
Collision inaccuracy from either scaling or the 1024x1024 distance field.
RGBA16f could probably still be used for a big speed and compatibility boost, but I'm still not sure how to get it working acceptably.
It's possible for particles to get stuck, especially if the distance field isn't regenerated when scaling the view.
Distance field rendering normals could be improved. The field should actually extend to well within the collider so that particles that overstep the collision barrier can escape.
Particles under a certain velocity don't have the floating point accuracy to actually move. This is not much of a problem generally since you can scale both the system up/down and the particle itself, although 16f positional textures will make it readily apparent.
This is not a library that I will be maintaining, but I thought it might be useful to the community in its current state. Let me know if you have problems or have an interesting effect to share. Jonbro's original work is licensed under MIT and mine under public domain.
edit: updated with a higher compatibility version
GPU particles
GPU particles
- Attachments
-
- gpart_notables.love
- higher compatibility version with hardcoded particle data in the shader
- (35.36 KiB) Downloaded 211 times
-
- gpart.love
- (35.24 KiB) Downloaded 244 times
Last edited by Magitek on Mon Oct 24, 2016 6:06 am, edited 1 time in total.
Re: GPU particles
Does it runs on a patched version? When I try to run it, it immediately throws "invalid number of arguments" error.
Re: GPU particles
I managed to get it to work with 0.11.0 (monkeypatching setColor to make it accept 0-255 colours); it's nice, it doesn't ever drop under 60 FPS on an integrated GPU (an Intel HD 530 if I recall correctly). By the way, I don't understand this comment:
If your VRAM usage is accurate, I get 40MB of used VRAM with rgba16f and 41.5 with rgba32f.
Code: Select all
gp_velocity_format = "rgba32f"--32 provides more variety, but usually isn't worth the wasted vram
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
ls = love.sound
la = love.audio
lp = love.physics
lt = love.thread
li = love.image
lg = love.graphics
Re: GPU particles
It runs on stock 0.10.1, assuming I uploaded the most recent version.raidho36 wrote:Does it runs on a patched version? When I try to run it, it immediately throws "invalid number of arguments" error.
I think GLSL has some misgivings about the table I use to upload particle data, I might have to remove it and hardcode them.
Re: GPU particles
Well that's kind of interesting - the normal example uses just as you say; but when you use a million particles, there's a much larger difference: 81.7mb -> 98.5mb.Nixola wrote:I managed to get it to work with 0.11.0 (monkeypatching setColor to make it accept 0-255 colours); it's nice, it doesn't ever drop under 60 FPS on an integrated GPU (an Intel HD 530 if I recall correctly). By the way, I don't understand this comment:If your VRAM usage is accurate, I get 40MB of used VRAM with rgba16f and 41.5 with rgba32f.Code: Select all
gp_velocity_format = "rgba32f"--32 provides more variety, but usually isn't worth the wasted vram
32f is slower regardless so that's a factor too. I just didn't notice much improvement in velocities with 32f to warrant using it.
Re: GPU particles
How is it supposed to be used? If I click and drag my mouse frantically I occasionally see a moving dot like the one to the right of rgb32f in this snapshot:
but nothing like in your snapshots above.
but nothing like in your snapshots above.
Re: GPU particles
hmm that looks quite odd. Can you take a screenshot of debug mode 1 while holding right mouse?
Also what kind of video card are you using?
Also what kind of video card are you using?
Re: GPU particles
nVidia GeForce 210, with proprietary drivers (version 340.96). LÖVE 0.10.1 is supported. Screenshot:
Output in terminal:
Before resizing I don't see anything either. I resize the window only to make the screenshots smaller.
Output in terminal:
Code: Select all
$ love10 gpart.love
Detected desktop resolution: 1280,1024
Render-to-texture limit: 16
Texture size limit: 8192
Texture formats supported:
rgb10a2
r32f
rgba4
r16f
r8
rg32f
rgba32f
rgba8
rgb565
normal
rgba16f
rg16f
rgb5a1
hdr
rg8
srgb
rg11b10f
Changing resolution: 1280,720
Constructing GP particle tables and canvases using resolution: 1280 / 720
GPu: Initialized gp with collision texture.
GPu: Autocreating a mesh..
GPu: Initializing gp: table: 0xb77d2d58
GPu: Initialized gp with collision texture.
GPu: Autocreating a mesh..
GPu: Initializing gp: table: 0xb3bfbc68
GPu: Initialized gp with collision texture.
GPu: Initializing gp: table: 0xb77cb7f0
GPu: Initialized gp with collision texture.
GPu: Initializing gp: table: 0xb506db48
GPu: Initialized gp with collision texture.
GPu: Initializing gp: table: 0xb186e368
GPu: Initialized gp with collision texture.
GPu: Initializing gp: table: 0xb506dad8
GPu: Initialized gp with collision texture.
GPu: Initializing gp: table: 0xb506b6d0
GPu: Initialized gp with collision texture.
GPu: Initializing gp: table: 0xb186ec18
Window resized to 640x720.
Window resized to 640x480.
Window resized to 775x480.
Window resized to 768x480.
Re: GPU particles
Yeah the data looks different somehow, almost like your textures are half size. Could take some serious debugging.
Does the original demo work properly?: viewtopic.php?t=81865
I wonder how forcing driver settings like AA and texture quality would affect this system.
Re: GPU particles
Actually pgimeno, that looks identical to my radeon laptop. I think the problem may actually be with the rendering side.
Try this table-less version if you get time.raidho36 wrote:Does it runs on a patched version? When I try to run it, it immediately throws "invalid number of arguments" error.
- Attachments
-
- gpart_notables.love
- (35.36 KiB) Downloaded 156 times
Who is online
Users browsing this forum: No registered users and 6 guests