Open mbalfour-amzn opened 1 year ago
Hi, thanks for the detailed explanation
This is usually fixed using the Camera Sort Offset
of renderer nodes. If the O3DE plugin doesn't support it, it's a bug, we'll look into it. How it works is PKFX just offsets draw call bboxes along the camera forward axis (world unit offset)
This is the main issue with PopcornFX batching sim units. Internally PopcornFX does not simulate these two emitters separately (simplifying it to one one layer in that effect for this example). Particles are evaluated in "waves" of 512/1024/.. particles depending on the platform (wave size can be specified per layer). Because of that, the memory layout of particle storage (positions/sizes/..) needed for rendering isn't location dependent but spawn-order dependent (positions of emitter A and B are stored in the same positions array, depending on particle spawn order).
We built on top of this two systems:
Other solutions to mitigate sorting issues:
We'll let you know our findings with slicing in the O3DE plugin
Hi,
After investigating this issue, this is what I found:
GlobalSortOverride
had no effect, this is fixed in upcoming releasep_PopcornFXMaxSlices
has no effect (enable slicing), PR: #54 that will allow us to investigate slicing results in that levelAs you can see in the following image, without talking about PKFX not correctly sorting with O3DE transparent objects, we can see the smaller sphere in this image that is technically behind, is drawn on top:
This is due to this effect using a "sort by custom value" with a key that is invalid:
Reverting the effect to use CameraDistance
sort instead, I suspect the artefacts seen in video (1) will be resolved. It is also possible to mitigate further with a CameraSortOffset
value different on some renderers from that effect.
About (2), PR #54 re-enables experimental slicing in the plugin, here are some initial results: https://github.com/PopcornFX/O3DEPopcornFXPlugin/assets/15339931/3f4abd49-1020-4622-b042-1a1e450e2bc0
There's definitely some flickering, and sorting result will differ depending on the camera angle. Once the PR is merged, it would be interesting to test this in the level, and see if slicing helps. The slicing algorithm can also be customized in the Gem so it's possible to try various approaches. One of the main problem is within the slicing code itself, it currently ignores game engine geometry:
If we were to consider slicing to be working properly with all O3DE transparent geometry, the merge pass would need to take into account both PKFX slices & O3DE transparent objects draw calls somehow (ideally, before the draw packets are built to reduce overhead of rejected/merged slices)
We could also disable the draw calls merge pass, but that would mean that for each draw batch, there can be up to p_PopcornFXMaxSlices
sliced draw calls..
Food for thought, let's see the results of #54 once merged (by default, slicing is disabled).
Wow, that's some great progress! Slicing controls definitely seem like they'll go a long way towards giving the designers some ability to tune performance vs sorting correctness. One other possible idea for slice controls would be exposing some sort of "manual slice bins" on each emitter, where by default they would auto-group together into one or more auto-binned slices, but if there are a few problematic emitters on the outskirts of the level or something, they could be manually placed into their own slice.
Definitely looking forward to seeing the results of this change! Are you also going to submit a change to the effect itself to correctly use CameraDistance, or is that something that someone else (me?) needs to do?
Wow, that's some great progress! Slicing controls definitely seem like they'll go a long way towards giving the designers some ability to tune performance vs sorting correctness. One other possible idea for slice controls would be exposing some sort of "manual slice bins" on each emitter, where by default they would auto-group together into one or more auto-binned slices, but if there are a few problematic emitters on the outskirts of the level or something, they could be manually placed into their own slice.
Yes the issue is particles positions/sizes/colors/.. aren't written into GPU buffers based on their world locations but based on their spawn order. So we're left with slicing the index buffer basically, but this will be a good thing to experiment with the slicing algorithm and expose additional CVARs that can help fix problematic situations
In this specific example, the dark/marine-blue orb could very well be alpha tested particles, they seem to be alpha blended with an alpha set to 1..
Just saw another artefact in the video:
Do the gems have a transparent material too ?
Definitely looking forward to seeing the results of this change! Are you also going to submit a change to the effect itself to correctly use CameraDistance, or is that something that someone else (me?) needs to do?
I'll take a look asap and push a fix for this effect on the MPS repo, I also saw another effect (I don't remember the name) that doesn't play where spawned but at world origin (one of the effects when firing). Will do a small cleanup pass by the end of the week
You can find two PRs here: https://github.com/o3de/o3de-multiplayersample/pull/421 https://github.com/o3de/o3de-multiplayersample/pull/422
Once these are merged (and #54) we'll take a look at the result of slicing in the level
Short version: In the MultiplayerSample project, we've run into multiple particle sorting issues, and there doesn't seem to be a way to work around or fix it. This is a request to at a minimum provide a way to "unbatch" particle emitters for specific emitters to make it possible to fix sorting issues when problems arise.
Long version: Atom sorts transparent draw calls first by sort key, and then by depth. By default, everything uses a sort key of 0. PopcornFX is also currently hard-coding a sort key of 0 in CPopcornFXFeatureProcessor::Render(). In the case of MultiplayerSample, we need depth sorting since the particles appear in a level that has translucent walls everywhere, so this is OK. It would also be nice if sort key controls were exposed instead of hard-coded, but that wouldn't help for this situation anyways.
The problems show up due to particle batching. The particle effects we're using have multiple layers to them, and each layer has different-sized particles. For simplicity, let's just say there are 2 layers, one with a 1 meter particle and one with a 5 meter particle. We also reuse the effects multiple times around the level, so the same effect can draw hundreds of meters apart. These two factors are affecting the sorting in negative ways:
https://user-images.githubusercontent.com/82224783/232830259-4a82b918-7423-492a-8a93-e46926438b52.mp4