Optimizing Animated Flames

I am trying to optimize animations for Thrust Flames on a spaceship:

294389-small.jpg

Here is the problem I am running into.
I have 12 flames in a line however they are offset from each other in a manner in which I cannot simply scale them as a single static mesh according to the amount of thrust
Currently, I am using a for loop to loop through all the individual flame static meshes to scale them according to the amount of thrust. This is not efficient.
Previously, I had made each flame an actor which updates every tick if thrust is being applied, and then put that as a child actor inside the spaceship actor. I used an event dispatcher to turn on/off and set visibility of child actor as well as update it’s scale when needed. This was a bit better as I avoided a loop, however still not very efficient.

Now, I am trying to implement each row as a single static mesh with animation for the scaling and then use a float curve to set the frame of the animation according to the current thrust. I have discovered that you can only animate a skeletal mesh (The animation was created in Blender 2.81 by creating key-frames and moving the vertices of the mesh, no bones). I have been unable to figure out how to export/import this type of animation into Unreal.

The question is if someone can lead me to resources explaining how to export/import this type of animation, or to provide a more efficient way of animating this.

The only other method I can think of would be to make a dynamic material instance using world offset and a scalar parameter to control the amount displacement of the vertices driven by the scalar value. However, this gives me far less animation capabilities and quick editing capabilities as to the animation of the flame.

Ihave come across morphing but have not yet figured out how that works to understand if it is a good solution to the problem.

I was trying to avoid bones because frankly they are not needed, just simple vertex animation, and from what I know, using bones would be less optimal unless it is required due to engine not supporting the type of animation I am trying.

Thank for any leads or advice.
Tyler

How about creating a series of emitters that has several modules controlling for scale, color / brightness if necessary beyond the base module, and timing / sequence of animation. It can be connected to an event node in BP, probably, which would initiate the particle emitter scale change for each emitter (flame) mathematically dependent on thrust applied (via an input node and thrust property / physics force or whatever is being used?).

Huh, thanks, did not think of using emitters. Unfortunately, will not be very optimized having this many individual emitters. And the way the flames are arranged, if I combine a row into one mesh or emitter, scaling will not work properly. None the less though, you have definitely given me something to remember and think about with future problems I run into!

You can create one emitter that spawns a number of meshes. I think 12 meshes probably wouldn’t be bad optimization…but I could be wrong. It probably depends on how it’s done. Having the meshes’ material be “unlit” in Material Editor, and then adding bloom would probably suffice for the glow of the flames, and would be lower in memory and such. Or having those meshes (to be spawned in the 1 singular emitter) be “Lit” and adding a bloom, while maintaining the scalar value according to thrust applied within a set range, would probably also not take up too much in resources. Sorry I can’t give a more thorough suggestion of how to set it all up. I’m new to UE4. A different person would be better to listen to regarding how to do things with the exactitude necessary.

What is the memory usage in Blender of the animation you’re currently using? any other stats that are important to optimize in the case of the flames?

Hmmm, I will have to experiment with this. I have no experience with cascade or niagara, but am some what familiar with how emitters work. would be interesting to see if it is faster than the method I am trying now. I am not concerned with the material cost, that is easily adjusted, what the issue is draw calls (individual meshes) and updating the scale of several individual meshes pretty much every tick or close to every tick. What I am trying now is each flame being a child actor that hooks to an event dispatcher that passes on the thrust vector, the child then scales itself accordingly. I did something like this before except each flame child actor was doing a dot product calculation, now I am doing the calculation once, and passing the result to the flames (the scale). An emitter though, might be faster since they both use individual meshes and I think most of it would run on GPU?. Ideally I would like to combine the flames into a single mesh for each thrust direction and have an animation. The problem I am finding is that UE4 only supports vertex animation through World Displacement, which seems like it would be intensive. I have not found a way to import a vertex animation any other way.

Here’s 3 links about Cascade, one a reference for the various modules, another an overview of the editor with information on key particle concepts and terms, and the last one about Mesh Type Data:

Particle System Reference

Key Particle Concepts

Mesh Type Data

You should consider using a distribution curve to interpolate the thrust to scale dynamic. And also interpolating between ticks, which would likely optimize the system from the start.

Thanks, I will check these out, although I am probably going to just jump in and learn niagara. I will also look up info on interpolating between ticks, I have not heard of this. As for interpolating the Thrust, I calculate the percentage of Max Thrust and use the percentage value for time input into curves for various material parameters, such as changing color gradient and emissive boost etc. Appreciate the info!

Hi, why can’t you scale them?

If you would make one mesh in blender containing all the 12 flames, then rotate it in unreal engine (not in blender) so they fit on the spaceship and then scale them, as far as I see it would do what you want it to.

He was saying that he’s trying to avoid scaling them in one static mesh because they wouldn’t scale correctly that way. Each one scales according to the amount of thrust applied, as far as I understand it, and it could be in a sequence or scale happens per flame, while all flames scale simultaneously. I’m not anywhere near an expert at optimizing an animation, and whether a mesh or 12 meshes would be the most efficient. But it’s pretty obvious there’s an issue with getting it to animate correctly and it not being inefficient. It’s why I suggested a mesh emitter in Cascade / Niagara, probably Cascade because it’s likely more stable. But utilizing GPU sprites, an event module or two (for connecting the material aspects to the particle/mesh aspects in a blueprint), and several other modules would likely not be a performance heavy object.

as preston mentioned, I cannot do this as they are not properly aligned on one plane, so when scaling as a single mesh, they do not scale properly. Having an animation and calling the proper frame of animation for the given thrust percentage would allow me to overcome this, however the only way I have found to do a mesh vertex animation is through a material and using World Offset. Using bones to animate would not work as the shape of the Mesh changes. I have looked into Morph Targets somewhat, but from what I can tell, that would not really work either, or perhaps it will, I just don’t know how. The thing I see with Morph Targets is that you have to call which shape key-frame or target when inputting a frame step, and I would need 2 or 3 Morph targets and it would get complicated tying to properly animate using a float curve to drive the animation (I am using a float curve to easily control/change the rate of the scaling and different thrust %).

Ah, ok then I misunderstood something cause from your image and description I thought you wanted to do something like this.

Even the flames would be of different sizes it would still work the same with one mesh (two meshes, one for the flames on the left and one for the flames on the right)

294499-different-size.png

294500-different-size-high.png

So I think I still fail to understand what the goal is… :slight_smile:

which kind of mesh does each flame consist of? a cone, an extruded 2d circle (lol), something else?

1.7, and even 3.9 ms is really good!

I mostly understand the ideas of the setup. Last night I read about beam emitters and thought it could work in this case. However, it is probably easier to use either mesh emitter(s) or GPU sprites. Mesh has the graphics aspect of rendering in 3D, while GPU is highly efficient. I don’t know how efficient the mesh system would be for the 12 flames, but I suspect not inefficient if developed correctly. Event modules could be used for the thrust and flame update functionality, and in conjunction with the size, velocity, and time modules. The difficulty I see in the mesh particle system is getting the individual meshes to scale exactly as intended according to thrust being applied. It’s probably going to be easier than I think though, since you already have the event connections set in Blueprints. Transpose that to particle system somehow and it’ll work well I think, no need for GPU sprites. There’s a setting for having a system be processed by the GPU, regardless if it uses the GPU sprites type data. So the mesh type data should work.

Here are the details of what I did:
Here are the flame meshes:

294536-primary-flame.jpg

294538-tertiary-flame.jpg

294540-shader-complexity.jpg

As you can see in the pattern, the flames are offset on different planes, so scaling them as a group or a single combined mesh is not possible as they would not scale properly and need to be scaled individually (the other option would have been a single mesh with a vertex animation)
You can also see that the shader complexity is extremely simple (the flames are the brighter green which means they are the cheapest thing rendering on screen)

Here is the setup:
I created one blueprint for the flame with a single static mesh component, and these variables: Static mesh (to set the static mesh for each flame from one of the 3 meshes), Thrust Vector ((each vector component is a % of max thrust for each direction of travel), 3 Float curves driven by the thrust vector, and a material instance dynamic to control the material parameters.
The flame blueprint is added as a child actor to the spaceship blueprint for each flame, and when calculations are done for thrust in the spaceship blueprint, it then calls the event dispatcher “update flames” on itself and passes the thrust vector.
The flame blueprint has a custom event bound to the “update flames” event dispatcher on the spaceship blueprint, and given the thrust vector, updates the scale and material parameters accordingly. The event dispatcher is called every tick as the calculations are done every tick (which those calculations I assume are the bulk of the processing in milliseconds for each tick).

Later in development, when I get into adding VFX and learning Cascade/Niagara, I will attempt to convert this to a mesh emitter which will hopefully be faster, but I am not certain as I do not think static meshes run as GPU sprites which is what would help speed it up. I also do not know what attributes are editable for static mesh particles.

Here is a link to a youtube vid showing final result and “stat game” running stats.

Video Link: Spaceship Flame Test - YouTube

BTW, the time in miliseconds was 3.9 when I was looping through each static mesh, and using this method dropped to 1.7 or less

Hmmm, good to know you can force GPU, did not know that. Will look into that. I believe I can control the scale of the particles using a variable, I started setting up the particle system, but ran into a problem of spawning a specific number of particles which last for ever in an exact location. I have to use meshes as my material depends on a mesh for proper rendering (fresnel effect) as well as it cannot always be facing camera.

I marked this as answer, because I tried using mesh particles and was unable to gt a set number of mesh particles to spawn an evenly distributed distance. Which in cascade using spawn distribution NPoints seems like it should work, but spawns mesh particles with gaps. So using particles did not work.

I have tried these and have not been able to get them to work. The gaps I am referring to are where flames should be spawning and they do not, because they spawn on top of other points.

I have posted another question in regards to this: https://answers.unrealengine.com/questions/941095/view.html

What do you mean “gaps”? Aren’t there gaps in the system you’re creating, between flames?