UE4 - Improve Smoke Performance/Overdraw

Hey guys,
i’m optimizing performance for our game right now and i’m not quite sure how to improve the smoke in our menu scene. The smoke is covering the entire screen, which results in massive overdraw. This is notable performance-wise, especially on XBox. The smoke itself consists of only a few particles.
How do you guys approach effects like this? How could i improve performance?


1 Like

Hey man,

Personally I would try with a shader on a single plane.

If you dont want to test on a single plane, maybe reduce the texture resolution size and/or reduce the spawn rate :sweat: .

This is what I would’ve try, but maybe there is a better solution.


Yeah I agree with @Alexandre_GM. I would do it with a single fullscreen quad and a slick material. You can pan several layers of cloud and possibly use the depth buffer with different range for each layer. As a quick test put difference clouds in each channel of your diffuse map and pan them at different speeds. Then get fancy with the depth buffer and some distortion.

1 Like

I just did something similar for the mobile game I’m working on. We fade out some smoke particles on a vehicle over 3 seconds and fade in a single quad with a looping smoke animation that covers the entire screen. UI is rendered on top of the smoke.

For your scene, I would try making three planes with a looping smoke/cloud animation on each one. One foreground, one midground and one background. The foreground would be just a single smoke cloud, midground maybe three, and background six or more. This will maintain the illusion of depth you currently have. This is basically the multi-plane camera technique Disney used on movies like Bambi.

Another alternative is just to render your entire background with looping animation to a single movie or sprite sheet. I mean everything, clouds, mountains etc. Might as well since camera isn’t moving. Render UI on top of that.


Thank you guys! It seems going for one quad with a smoke animation is the best solution. I will either use three different layers of quads or the depth buffer for the illusion of depth. I’ll report back what the outcome was performance wise…

It seems odd that a scene as simple as this and that amount of overdraw would be having a noticeable hit on performance. This is literally just a title screen - almost nothing is going on compared to what normally goes on in a game, so I’m confused as to why this would be slowing the framerate that much. What exactly is the hit on performance that this is causing?

Among other good approaches described above, for some other situations you can reduce overdraw trimming away the transparent areas around the particle, using an n-gon fan instead of just a quad sprite. It’s a new feature in UE4. And some common way for games with big amount of particles is drawing particles into a smaller-resolution buffer.

1 Like

Best approach is render your particles at a lower resolution than the main screen

1 Like

Is there an easy method to do this in UE4?

Might be a stupid idea but when the smoke does not have to cover the UI/Logo, you could directly put it into the material of the background graphic. So basically a the idea of the fullscreen single-quad but directly processed in the material of the background.

p.s. I saw too late that it’s not just an image in the background but a real 3D scene :smiley:

Have no idea in UE4. Was pretty simple to do in Unity

Unfortunately, not really. We implemented a half res translucency buffer, but it was a ton of work, and as far as I can see Epic hasn’t done it in vanilla.

Sorry, but I haven’t done that in Unreal yet. They have captureComponent2D component for rendering into a texture. You can find some interesting about that here:

This approach will give you a texture with rendered your particles into. After that, you can draw it before your post-process pass. But for reducing forward geometry overdraw (which means and particles too) you need to render it with prepared z-buffer which contains information about deferred geometry, and unfortunately, I have no idea how it could be done in UE4. =( I believe Ryan, it could be not so easy.