perf(particlesys): Batch same type particles to reduce cost of particle rendering by 15 to 30% - #3155
Conversation
PR Summary by Qodoperf(particlesys): Batch same-type particles to reduce draw calls
AI Description
Diagram
High-Level Assessment
Files changed (3)
|
Code Review by Qodo
1. canBatch always true
|
|
I think W3DParticleSys.h was supposed to have been moved to core in #3014 but wasn't... |
Outside the scope of this change, but i noticed that too. |
62747ca to
315c30c
Compare
|
Ah stupid VC6 loop handling, will just fixing now |
315c30c to
0df2c07
Compare
|
Fixed VC6 build and issues mentioned by the bot |
| m_pointGroup->Set_Flag( PointGroupClass::TRANSFORM, true ); // transform to screen space | ||
|
|
||
| switch( sys->getShaderType() ) | ||
| if ( sys->getVolumeParticleDepth() > 1 ) |
There was a problem hiding this comment.
Would it make things simpler/more consistent if volume particles were batched as well?
There was a problem hiding this comment.
volume particles work in a different way as they have multiple surfaces.
The batching only really works with billboarded / flat particles
There was a problem hiding this comment.
Are they really that different though, they appear to use the same input arrays. The only difference is that they call a different render function and render more surfaces
There was a problem hiding this comment.
Would need to find something that uses volume particles, all my current tests don't show any activity down that path
There was a problem hiding this comment.
Found that the microwave tank uses them.
0df2c07 to
0e8506d
Compare
xezon
left a comment
There was a problem hiding this comment.
First review pass. Reference counting needs simplification.
0e8506d to
4b5ec70
Compare
|
Partially addressed review comments, things still appear to give a good 15 - 30% more performance with the tweaks. |
…visibility skip until the next upstream rebase
|
I am going to change this back to a draft for the moment as i have seen some other things to cleanup. |
b773d9e to
7655d62
Compare
|
| Filename | Overview |
|---|---|
| Core/GameEngine/Include/GameClient/ParticleSys.h | Adds a point-particle type predicate, normalizes accessor return types, and avoids copying particle-system names. |
| Core/GameEngineDevice/Include/W3DDevice/GameClient/W3DParticleSys.h | Introduces the texture, shader, and billboard state and helper methods required to manage particle batches. |
| Core/GameEngineDevice/Source/W3DDevice/GameClient/W3DParticleSys.cpp | Implements visibility marking, compatible point-particle accumulation, subtype boundaries, capacity flushing, and final batch rendering. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
S[Visit particle system] --> C{Any visible particles?}
C -- No --> N[Visit next system]
C -- Yes --> T{Point particles?}
T -- No --> F[Flush pending point batch]
F --> D[Render subtype-specific effect]
T -- Yes --> K{Texture, shader, and billboard match?}
K -- No --> F2[Flush previous batch]
F2 --> I[Initialize compatible batch]
K -- Yes --> A[Append visible particles]
I --> A
A --> B{Buffer full?}
B -- Yes --> F3[Flush and resume same system]
B -- No --> N
F3 --> N
N --> E{End of list?}
E -- No --> S
E -- Yes --> L[Flush final batch]
Reviews (8): Last reviewed commit: "Review update" | Re-trigger Greptile
… for further optimisations
0c0ec8d to
2d94e31
Compare
|
This should be functioning properly now after the changes to make sure only normal particles with additive shaders are batched. Also after the volume particle PR changes i added an extra helper function in this PR to check for regular particle types since that makes the check for batching cleaner. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2d94e31d95
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
2d94e31 to
63bec7b
Compare
|
I reverted the gate for additive only particles, after further investigation i believe the issue that was being seen was due to a problem with an earlier implementation of the code. |
…visibility skip until the next upstream rebase
I tested a replay with lots of suicidal toxic tractors and bomb trucks. Based on video material, both before and after look the same. |
|
Updated to allow the batching and rendering of untextured particles. The retail games do not make use of these but the engine still supported them. |
01c479c to
b23a38c
Compare
|
This should be good again now. |
xezon
left a comment
There was a problem hiding this comment.
The munkees will be ecstatic about this.
Caball009
left a comment
There was a problem hiding this comment.
Incomplete review, a few nitpicks.
|
Updated based on most review comments, this PR can be squash merged. |
2294b57 to
3dc2299
Compare
Waiting. |
|
I'll leave an update in a couple of hours. |
| Bool finishedBatch(ParticleSystem* system, const RefCountPtr<TextureClass>& texture); | ||
| void initializeBatch(ParticleSystem* system, const RefCountPtr<TextureClass>& texture); |
There was a problem hiding this comment.
const ParticleSystem& system
(that'll require making the two member functions const).
There was a problem hiding this comment.
I don't think this matters too much and requires a dereference on the pointer being passed to the function anyway.
The particle system list is a list of pointers.
There was a problem hiding this comment.
It's minor, but in general it's a good idea to pass by reference if you're going to dereference the pointer anyway.
…xtures and cleanup batch initialization
…nd streakLine objects
3dc2299 to
17b1687
Compare
|
cleaned up the unnecessary const returns |

This can be squash merged
This PR is separated into two commits to aid reviewing.
The initial commit is a small refactor to make the diff slightly cleaner on the second commit.
The second commit implements the particle batching created by Ronin and cleaned up by myself.
When testing we see a 15-20% performance improvement on average. But this may be higher in some scenarios.
EDIT: An early particle visibility test has added 2 - 5% more performance on top of the original.
The batching works by creating a common texture that the particle effects are drawn to before being sent to the GPU. This reduces the number of draw calls, thus improving rendering performance.
Only particles with the same material and shader type can be batched to the texture, so once particles of a different type are observed. The system will flush the prior batch and start a new one based on the new particle type.
As draw order is preserved, particles adhere to their original layering.
Some performance comparison images
Using the chemical spray as the source of particles, all tractors are using their AoE spray ability when these images were taken.
Before:

After:

Using the firewall and flamethrower effect of the flame tank, a circle of flame tanks are creating firewalls in the centre while extra flamers spray fire into the centre of the inferno.
Before:

After:
