Adventures with Unreal's Niagara Emitters (Particle Meshes, LODs, and Boundary Constraints)
I've been very busy with building the next intallment to BlueSuburbia which will be the open world part.
Building an open world is an extra load of work because you have to put a lot of care into optimizing, loading, and just making sure that things are performative.
I learned a lot about the importance of propper LODs for everything, especially landscape elements like grass or trees.
I also learned that lighting and shadows can be a heavy performance hog that you have to invest more care into getting right... lol I can't even keep track of the amount of tutorials and reading that I've done to learn about how to make large open world spaces the right way.
I thought that maybe I should log some of the things I figured out in this devlog. At least this will help me keep track of things I learned... It's easy to forget and then have to dig up "how do you do this again?"
So much stuff to know...
The latest series of problems to solve was working with Niagara to populate parts of the level with jellyfish (it could be any floating, flying, gravity defying creature... in this case jellyfish!)
There are large bodies of water in this open world. I wanted one body of water to have something that's unique and beautiful to look at. Jellyfish are fun because they are more like a ghost than an animal so it would add a unique presence to the space.
The open world is meant to feel abandoned and lonely. Jellyfish would help accomplish this.
My first issue was figuring out how to have a Mesh be generated by a Niagara system (easy enough!), instead of just a simple particle. From my understanding (as it is and as I haven't found any resrouces about it) you can't really have skeletal meshes in Niagara... so that would constrain my workflow of animating my jellyfish in Blender and just dropping it into the Niagara system. (Again, I'm more or less new to this so these statements are still limited to my understaning.)
Thankfully jellyfish are easy to animate and you don't really need to do much other than a fluctuating movement.
Generally this is how the blueprint for it looks. It's hooked into World Position Offset:
I got them working in no time.
I love World Position Offset. I was over the moon to know that World Position Offset in landscapes (from material) works with collision too. There's a checkbox in UE5 that I'm sure wasn't there in UE4... maybe it was... either way. It's pretty cool!
I wanted my Niagara System to spawn once and each Mesh/Particle to loop indefinitely. They don't die. They stay and spawning just happens on initiating.
I've done this a bunch of times but every time I forget how it's done so I'll post that here... If not for any other reason but for my own reference lol...
Single Burst Permanent Particles in Niagara (The particle or mesh should only spawn once and never die)...
Make a "Hanging Particles Emitter" (could be any but I prefer to start with this)
Delete "Spawn Rate" and make a "Spawn Burst Instantaneous" in the emitter update with these settings (change "Spawn Count" to whatever amount you need):
These are the "Emitter State Settings"...
Life Cycle Mode = Self
Loop Behavior = Once
Loop Duration Mode = Infinite
The most important settings for "Initialize Particle" are setting Lifetime Mode to "Direct Set" and Lifetime needs to be "EMITTER CurentLoopDuration"...
You will want to turn off "Scale Sprite Size" and "Scale Color" unless you tweak those to remove references to things like "Scale Alpha" because the particle should not be allowed to fade out. It should last forever.
Done. The particles are permanent. That's the first thing to log here...
Box Constraints in Unreal 5 Niagara??
Another issue I ran into with Niagara Particles is that controlling the boundaries can be really hard, depending on what your settings are and what forces are applied to it. Each system is different so most information for doing something doesn't always apply to what you need for a specific case.
I want animals that float around in an area.
My jellyfish quickly became an infestation that took over the entire map because there were no boundaries and I could not figure out a clear way of making them. As of now I still am unsure if I'm missing something and there is some easy checkbox somewhere that will do this...
There were a number of Youtube Tutorials I tried that didn't seem to work with Unreal 5 anymore.
NOTHING that I tried was working when I followed these tutorials. I even made the fixes recommended to get it to work with Unreal 5...
I eventually tried this tutorial and I got it to work...
NOTE that even following that tutorial was not working for me and I couldn't figure out what I was doing wrong! When I restarted my computer it suddenly worked so I have a feeling that the other tutorials would have worked too. I make note of that because it's happened a few times where Unreal was behaving erratically. I thought I did something wrong or broke something. Then restarting the computer fixed everything.
Good to know!
Here's the blueprint for the box boundary Scratchpad Module...
Like the tutorial suggests... To make sure the particles fade in and out when near the boundary (to get rid of particles flickering) you need another variable called "NormalizedDistanceFade"... this is how that set up looks:
So now my jellyfish were contained to the ocean areas. The infestation was no longer...
There's another issue that I was kind of blindsided by in that Niagara Systems "don't really" support LOD's for the Meshes that you use. Meaning... I set up my LOD's in my mesh but when I set the mesh as the desired mesh to use in my Niagara system the LOD's were not working.
I found out that Niagara systems do support that but you have to set that up yourself in the system... It's a bid more complicated. You have to have separate meshes with the geometry reduced, and put those meshes into Niagara, then select each (from the array) based on distance.
There were two tutorials that helped with that.
The first one was...
* LOD \ Scalability in UE5 Niagara Tutorial
And here is a tremendously helpful Twitter thread that also breaks that down:
I will not be posting images here because it's more involved... those are good resources tho.
Niagara also has some great support for setting how your system looks based on distance. You can optimize them fairly specifically. This was a relief to know. This is an open world project after all. I was worried about how I would get such effects to work in it, but it seems intuitive and natural to figure out.
I easily figured out distance culling on my own (without youtube! yay! no ads!) but I did get hung up on how to make my meshes fade in with the culling... instead of just popping in.
My material blueprint approach for getting that to work the same way that I was using for foliage or trees was not working. I got this tip and eventually got this working with my system beautifully.
I do appreciate the system Unreal has for materials and how that seems to work well together with other aspects like Niagara particles, or Widgets. So far I haven't had any major roadblocks where I was stuck with a "Oh god now what do I do?"... So far everything has been easy to figure out.
That all said... My Jellyfish are beautiful! They are culling. The LOD's work. It's perfect for this part of the world.
It's been easy to work with Unreal because for literally any issue you have there's an abundance of resources out there from the community to help figure out "this very specific and niche use case".
Today I just came across World Machine and I WISH I knew about it before creating the landscape for my open world. I used to use terrain.party but it no longer works. I would use heightmaps generated with terrain.party and combine those with generated landscape noise in Unreal.
Knowing about World Machine would have saved a lot of time so I have to add that here!
There's also 3D-Map Generator.
There's also this wonderful Unreal Engine 5 Open World tutorial series that ended up on my radar. I'm comforted to know that most of what is mentioned is stuff I figured out on my own... so that means I did do it right!
The series also covers weather effects, water bodies, and wet surfaces from water bodies... I'll be referring to it a lot.
I'm at a point right now where I know that I will have to create my own sky system for my open world because the one I am using right now is way to performance heavy and I'm not even using half the features.
I figured out that it does make a big difference if you make all your elements (widgets, shaders, water, sky, textures...) yourself. I decided to do that on the outset and I'm glad that it payed off. Troubleshooting when something doesn't work is much easier because I usually know why it doesn't work.
The BlueSuburbia teaser demo is available on both itch.io and Steam: http://bluesuburbia.com/
Leave a comment
Log in with itch.io to leave a comment.