Niagara performance on updating single particle

Hi there everyone! :smiley:
I am using Niagara to render the ground of my game, for that, I am spawning thousands of GPU particles in a grid like this 200x200 tile grid:


for a static particle, the performance up to the millions is pretty chill (top down camera so it will never show milions), but I need to control each particle and update them according to interactions. Simple example: interactions makes that single tile number change to number + 1 and the rest is intact.

As far as I have tested, the only way to do that is sending to the emitter the entire tile array with the new data and updating ALL particles
29-08_105820_UnrealEditor

So my question is, what would be the optimal way to do that?

  • Breaking it in chunks like minecraft? Making smaller grids and spawning a lot of niagara systems to update only chunks
  • Leave it be with only one system and update them all
  • Another magic solution to just update a single particle that I don’t know yet :mage:

TLDR: I need to update a single particle data, spawn single system with lots of particles or spawn multiple systems less particles?

1 Like

I might be wrong but I don’t think there is a standard to something like this. The best solution, I think would be to use the debug and optimization tools built into Niagara and in the Unreal Editor to see the impact of the various options available to you. Testing things out and seeing how they affect performance.

1 Like

I haven’t tested it, but my guess would be the following :
instead of using an array, use 2 RTs and update it through niagara stage which writes the RT1 = RT2 + some operation mask, then swap RT1 and RT2 assignment.
The when displaying the floor, spawn particles in a grid (so assign x and y values) then read the current RT1 at that grid value.

Since you’re working on the gpu, you want to avoid random access operations and instead write things in ways that are easy to batch and execute on gpu cores.

wouldn’t using Render Textures limit too much the size of the grid because of resolution and memory issues and also limit the readable data to 4 floats per texture? Is it possible to sample an unfiltered pixel-perfect RT using niagara?

wouldn’t using Render Textures limit too much the size of the grid

The size of the grid shouldn’t be too much of a problem since we’re only looking at a 200x200 grid.
Niagara Array’s of this size will be difficult to maintain + access each field manually on the gpu is slow.

limit the readable data to 4 floats per texture?

This is a valid concern, but frankly, you can just add more textures if you need more information about the grid, typical games have thousands of textures loaded at once, I don’t think using 4-5 small 200x200 textures for the ground is going to be much of an issue.

Is it possible to sample an unfiltered pixel-perfect RT using niagara?

I might be mistaken, but I believe if you sample on the center of the “pixel” it always returns a non interpolated value, no matter how it’s actually being setup.

1 Like

ohh sorry, I wasn’t clear on that, the 200x200 is only an example, the real grid does not have a fixed size (a map of only 200 tiles would be too small for some parts of the game like a dungeon or a race track) I think I probably wouldn’t go bigger than 1000x1000 but I am trying to make it scalable :sweat_smile:

I am testing the render texture way though

1000x1000 is still ok, as long as you don’t go over 8K I believe the engine still supports it, beyond that you’d have to start fragmenting it

Worked like a charm :star_struck:
I had to make a Texture2D using C++ though, RT and blueprint draw nodes were too slow :tired_face:

498x498 grid, 1000 random cells being updated with new values per frame

1 Like

I believe Niagara is also capable of building the RT and it’s supposedly a lot quicker than BP, so it might be worth looking into that as well

I saw that but I thought it was only used by fluids and simulation

You should be able to use it with any kind of stage, not just fluid sims

using niagara’s grid and its render texture is indeed the best way! Tank you a lot for the help~ :star_struck:

2 Likes

Oooh nice!

Are you running marching squares or wave function collapse or something?

Just a basic BP random and 2-corner wang tiles autotiling for now

1 Like