Search public documentation:
UE3 Home > Particles & Effects > Particles Systems > VFX Optimization in UE3 > VFX Optimization: Getting Results
UE3 Home > FX Artists > VFX Optimization in UE3 > VFX Optimization: Getting Results
UE3 Home > FX Artists > VFX Optimization in UE3 > VFX Optimization: Getting Results
- VFX Optimization: Getting Results
- Core Systems in Cascade - GPU/Game Thread/Render Thread
- Overdraw - GPU
- LODs - Level of Detail - GPU/Game Thread
- Draw Calls - Render Thread
- Mesh Emission - Game Thread/Render Thread
- Collisions - Game Thread
- Spawn Per Unit - GPU/Game Thread
- Memory Costs
- Tick Time - Game Thread
- Non Directional Lighting Costs - Game Thread
Cascade creates robust particle systems which have dynamic costs spread across three core engine systems in UE3. Game Thread, Render Thread, and GPU.
- Particle simulation times (Tick) are calculated on the Game Thread (gamethread)
- Particle data finalization (Packing Geometry, Draw calls) are calculated on the Render Thread
- Particle visuals (Shader complexity, overdraw) are calculated on the GPU
If you are a seasoned effects artist, or if you have only been an effects artist for 2 weeks you have already heard about Overdraw. In its simplest form, overdraw can be described as:
Overdraw = Pixel shader cost = Number of layers * avg number of pixels affected by a layer * avg number of instructions for a layerEssentially, when you add a material to the surface of a sprite, that material has a cost in instruction count, which UE3 displays in the content browser and material editor. For translucent objects this instruction cost adds up as translucency stacks up, creating overdraw. The more layers of translucency, the higher the cost. You can easily see this cost in the shader complexity mode. Bright Red = 300 instructions, pink = 600 instructions, and white = 900 instructions. Press F5 to view shader complexity on PC. Shader complexity outputs an approximation of what the cost of a system will be, however it is also dependent upon the scene since translucency is calculated against opaque objects which also have a cost. Checking the usage of your effects is critical. An effect which may be called in any given scenario (weapon impact) will generally need to be lighter than an effect you can custom build to match a specific scenario, since it will be drawn in fluctuating cost scenarios. Some steps that can be taken to get overdraw impact under control are:
- Reduce emission rates
- Reduce material instruction count
- Reduce particle scale (fill less of the screen)
- Create LODs for near/far particle emissions to reduce cost at different view distances
- Check for emitters placed in a line stacking against each other (static placed effects)
LODs in Cascade provide users the ability to control modules and behavior based upon the distance from the player to the emitter. Any attribute in a particle system can be modified to make use of the LOD system. Refer to the Particle System Level of Detail (LOD) section of the Cascade User Guide for more technical information on setting up LODs It is important to keep in mind when creating LODs, there are memory costs associated with unshared modules. Sharing as many modules across LODs as possible reduces memory footprint. Only create unique module settings for the attributes you wish to modify. The preview modes in Cascade and the editors perspective view behave in different ways. In order to get proper viewing in Cascade make certain the editor preview mode is disabled. (circled in the image below) Cascade allows for a switch between LODs and displays the LOD specified. Be certain to disable the Editor LOD view mode in order to see Cascade update correctly. Enabling the editor preview grants the ability to fly through the scene and see the particle systems switch between LODs as you move around. (circled in the image above) It is important to measure the scene and get a realistic idea of just how many units are needed to see effects in the proper state. In the case of ambient particle systems it is possible to emit 0.00 particles and reduce tick time when the particle systems might not be visible. Measuring distance can be done by holding down the middle mouse button and dragging in any orthographic view (front, side, top.)
Draw calls within particle systems can be tricky to track at times. There are several combined factors to keep in mind when determining draw call costs. Particle emission is 1 draw call per emitter, regardless of screen orientation. Mesh emission is 1 draw call per mesh emitted. So if you have 2 emitters in your effect, each emitting 10 meshes, you have a total cost of 20 draw calls associated with that particle system. Material passes also determine draw call costs. The more passes in your material, the more draw calls in your effect. For Instance:
- Particle System A consists of: 1 emitter, spawning 12 sprites, using a material with 1 Pass, the entire system costs 1 draw.
- Particle System B consists of: 1 emitter, spawning 12 sprites, using a material with 2 Passes, the entire system costs 2 draws.
- Particle System C consists of: 1 emitter spawning 12 meshes, using a material with 2 Passes, the entire system costs 24 draws. (2 passes per call * 12 meshes since each mesh is a single draw call = 24 draws)
- Particle System D consists of: 1 emitter spawning 6 meshes, using a material with 2 Passes, and 1 emitter spawning 10 sprites with 1 pass the entire system costs 13 draws. ( 2 passes per call * 6 meshes since each mesh is a single draw call = 12 draws, 1pass * 10 sprites = 1 draw call)
Translucent material = 1 pass base
- +2 for distortion
- +1 for bUseLitTranslucencyDepthPass
- +1 for bUseLitTranslucencyPostRenderDepthPass
- +2 for bUsedWithFogVolumes
DumpParticleFrameRenderingStats. This command outputs a spreadsheet which lists draw call costs in detail. Impact from draw calls increases proportionally to the number of views being rendered. This means that in split-screen, the effects are multiplied. See the VFX Optimization: SplitScreen page for more detailed information on optimizing effects for splitscreen. It is important to keep these costs in mind when constructing your effects, and when optimizing effects. If your render thread is high due to draw calls, and the environment is within budget this is the place to start looking.
Mesh emission is one of the more powerful features of Cascade, and is a feature which can be accidentally abused. Keep in mind when using meshes the figures listed above relating to draw calls. the emission rate equates to the number of draw calls. It is also a good idea to keep the vert count on your meshes low. In some cases a single mesh emission can be used to fake a large volume of objects without the cost of calculating the positions all of the sprites which would be needed to create a volume of debris for instance.
Typically there is a high cost associated with doing particle collision in UE3 so they should be used only when needed. In some cases collisions can be made cheaper by specifying which objects in the world to collide against using the Collision Actor module. This is typically done when spawning effects through a Kismet action, or script where an emiterActor is placed in the world and it is possible to define specific objects in the scene to collide with through the instanceParameters of the actor. See the Per Actor Particle Collision page for instructions on setting up this type of collision. Several settings can be used to minimize collision costs these include:
- MaxCollisions: keep this value as low as possible
- Collision Completion Option: set this to HaltCollisions/Freeze to stop doing collision checks against the scene once MaxCollisions is reached.
- The Damping Factor determines the bounce of objects following collision, lower values may result in objects coming to rest faster (lower Max Collisions value.)
Spawn Per Unit is a feature in Cascade which is helpful for filling in gaps when particle systems are moving. While this feature is handy for creating great looking trails of particles it is important to balance visual with performance limitations when using Spawn Per Unit. There are a few tricks to controlling emission
- Keep the Unit Scalar to a value as high as possible, and balance it with the emission rate to get the fill you need, without making the effect too heavy
- Try and use lower instruction count materials if you know you are going to have high emission rates using Spawn Per Unit
- Adjust the Max Frame Distance to limit how many particles can be emitted. If the emitter goes above this Max Frame Distance Spawn Per Unit will cease emission until it returns below the distance. This prevents the emitter from dumping large amounts of sprites into the scene.
Cascade offers the ability to display large amount s of valuable information relative to particle system creation. It is often helpful to turn these displays on to get a good idea of just how many particles your system is allocating, and how many particles your system is emitting. Particle Allocation determines how many particles it is possible for the emitter to place in the world at any given time, this plays a large part in determining how much memory your particle system will consume. You can see a memory estimation by enabling the particle memory overlay in the View drop down menu in Cascade. By adjusting settings it is possible to see memory cost increase and decrease. Several ways to reduce memory footprint include:
- Reduce the number of modules in a system to the essential modules required for a given behavior
- For looping effects reduce Loop Time/Duration (allocates fewer particles per loop)
- Reduce Lifetime (fewer particles overall)
- Share as many modules as possible
Tick Time represents the amount of time spent updating particle systems in the scene. Tick Time can be viewed with the stat particles command which lists out all relative information required to assess particle evaluation costs. There are many methods which can be used to reduce Tick costs. Tick Time is directly influenced by the number of active emitterActors in your scene, the more active emitters in the scene the higher Tick Time will be. Emitters should only be set to autoActivate if they are required to loop when the level starts. If large amounts of sprites/explosions/burst effects are visible on level load in the editor, these effects are automatically evaluated at run time and can cause visible hitching when a level is loaded. A Particle Parameter can be used in an effect to allow for position offsets once the effect is placed in the world. By using a particle parameter it is possible to reduce emitter counts, which reduces tick cost overall. Particle Parameters can be setup by selecting particleParameter from the distribution list in the module for the individual setting. It is possible to stream out and disable emitterActors when they are not in view, or if they are associated with an area of a level which is no longer in memory. Streaming emitterActors with level geometry is a good practice to reduce tick overhead. In some cases where atmospheric effects are heavy kismet actions can be used to toggle atmosphere off and on during combat sequences to lower tick time and overdraw. Particle Systems loaded into memory, but out of view (say on the floor above you) can also be toggled with kismet actions and streaming volumes to reduce evaluation costs. In some cases a mesh effect can be a good replacement for a particle system. A placed static mesh does not have an evaluation cost on the Game Thread, in many cases it is more beneficial to place a static mesh as a replacement for a particle system. This includes vista effects, fog effects etc. Particle counts play directly into evaluation cost. The more particles in a scene, and the longer they live, the more evaluation is required. Limiting lifespan to the duration required for the effect is good practice all around. Enabling LODs in particle systems allows for lower particle emissions when a system is not within optimal viewing range. It may help to think of your effect in terms of a hero state, and an acceptable level of lower quality for longer viewing distances. Tightening LODs to required distances can go a long way to lowering evaluation costs in a scene without dramatically losing visual quality. Check your effects for expensive evaluation costs which can be lowered such as Collisions, non-fixed bounds, and spawn per unit counts which are too high. Setting bounds to a fixed state can increase performance significantly and should be used whenever possible.
Non Directional lighting adds depth and realism to particle effects by doing a trace within the world to determine lighting information around emitters spawned into the scene. Non Directional Lighting comes at a Game Thread evaluation cost. Non directional lighting is often used for weapon effects, impact effects, character effects, ambient fog effects, and Binked cinematic effects . Another option for matching particle color to a light environment would be to utilize a Particle Parameter to control color and alpha per actor. By using a particle parameter on a placed ambient effect which never moves, several costs are eliminated.
- Cost to store a unique color variant of an effect in memory
- Cost to load a unique color variant at run-time
- Cost to create each color variant in Cascade
- Cost to light the effect to match the environment with Non Directional Lighting on the Game Thread