Setting Up Precomputed Visibility (Killing Floor 2)
This documentation aims to explain what Precomputed Visibility is, the benefits of using it, when it should be implemented and miscellaneous things to consider when approaching and tweaking it. The official documentation is important to read to grasp a stronger understanding of it (https://api.unrealengine.com/udk/Three/PrecomputedVisibility.html) however this page will tend to cover aspects not covered in the documentation and aspects more specific to Killing Floor 2.
What is Precomputed Visibility?
As a means to increase performance, most game engines try to reduce the amount of things rendered on the screen by using a technique called Occlusion Culling. In a general sense, when a user is not looking at something, or an object is fully hidden/obscured behind another, it should not be rendered as the user cannot see it. Unreal Engine 3 has an automatic system set up for this called the Dynamic Occlusion System. By default all maps made for Killing Floor 2 will use this in some form or another. This is fine in a generally speaking but it does require additional performance cost in determining what should be rendered and may encounter some problems and fps drops when rapidly moving the camera or moving around corners.
Precomputed Visibility (PCV) aims to increase performance by statically saving the occlusion culling to the map. Doing so allows the engine to determine immediately what should be rendered instead of requiring iterations and queries used by the Dynamic system, ultimately reducing rendering time and increasing FPS.
Traditionally PCV is used on mobile games and some consoles. It is used in KF2 since we use a deferred renderer instead of the front renderer typically used in Unreal engine based games. The function is to keep the draw calls in a manageable area and squeeze as much performance as possible out of the maps.
It should be mentioned that PCV is a different rendering system from the Distance Rendering you can set for individual actors in your map. Further discussion on Distance Rendering can be found here. However both should be used to improve your map's performance.
TL;DR: Its a method to increase performance in the map.
Should I and When Should I?
Ideally, all maps for KF2 should try and be as optimized as possible - This means that eventually, yes, you should do it. However, depending on your map size and even your PC hardware, you may want to consider some things:
How do I set it up?
To enable PCV go to View > World Properties. From here expand the Precomputed Visibility Tab and enable the option 'Precompute Visibility'. See Figure 1.2. You do not need to edit any of the values here.
From this point you can use the builder brush to encompass the playable areas of the map and generate 'PrecomputedVisibilityVolume's. When you build your map's lighting you will be given the option to build the PVC. Any meshes within the volume will generate 'Visibility Cells' ontop of them if they are walkable.
Visibility Cells are small cells that enable PCV when the players are in them. If the player is not in a Cell, PCV will not be active. As such, cells ONLY need to be generated in the playable area. It is not needed to have PCV Volumes outside the map or having the whole map encompassed in cells as it will not serve any benefit and will only increase build time. Cells are only generated on walkable surfaces and they do not stack on top of each other to fill empty space. Knowing this, we can generate volumes that are small and efficient to reduce build time (see below).
If you have enabled and built PCV, you can view the Visibility Cells by going to View > Browser Windows > Log. When the log window appears type 'ShowPrecomputedVisibility'. This will toggle the cells on in the editor.
Best Practices for Volumes
There are 3 ways to shape volumes for PCV:
- VERY BAD: Encompass the Entire Map in one Volume
- This is the worst and least efficient method to create PCV Volumes. The build time is enormous using this method is not recommended.
- You will also create visibility cells that are outside the playable area and never used. Essentially resulting in wasted build time.
- OKAY: Split the map into different 'sectors' or 'fragments' based on room and general layout of the map
- A much more efficient and logical approach to the volumes; shaping the volumes to conform to the shape of the rooms. Build time is better but not the best.
- This will have more accurate visibility cells but may still create them outside the playable area and on top of ceilings the player will never be in.
- BEST: Use multiple small volumes to encompass the entire playable area of the map.
- This will result in the fastest build times
- This will also provide more accurate visibility cells as you are not encompassing large areas.
- This is the best option to start off with initially
The Official maps do not have a standard for how volumes are set up; different maps use all the different options. This does not mean it is the 'best' practice because it is in the Official maps. TWI have stated they use Option 2 as Option 3 may cause undesirable culling in some locations; however through my own testing, areas with undesirable culling are not fixed by encompassing affected area in one larger volume, it is usually a result of something different. Basically there is no real benefit to using Option 2 over Option 3.
|Note:||Regardless of what method you use, theoretically the performance will be same across the board. Therefore it is in your's and the computer's best interest to utilize Option 3 initially due to smaller build times, and if any undesirable culling occurs utilize option 2 in those areas.|
Below are the results of carrying out PCV builds using the 3 methods on Zed's Diner with an i7 8700k @ 4.3GHz:
|1. Single Volume Encompassing Whole Map||2. Fitted Volumes to Playable Area||3. Multiple Small Volumes within Playable Area|
|Description||1 giant volume encompassing a majority of the map. After 4:37 hours this was the progress bar. At this point I quit the build as it would be estimated to take too long.||4 medium volumes that were fitted to the playable area of the map split up into different 'zones' of the map||102 small volumes (640 Width x 1600 Length x 640 Height) encompassing only the playable area.|
|Build Time||Estimated 50+ hours||1:11:49 hours||1:03:21 hours|
As an additional example for build time, Desolation which is approximately the same size and mesh density as Outpost took 9:16:58 hours with Option 2, and took 7:15:19 hours with Option 3; Shaving a significant 2 hours off the build time.
Debugging and Troubleshooting
Make sure your Log window is available by selecting View > Browser Windows > Log, you can use the following commands to evaluate and debug PCV:
The two lines we are concerned with are 'Statically Occluded Primitives' and 'Occluded Primitives'. See Figure 1.3:
Ideally we are interested in how much performance we gain from it, to see this:
From a very basic performance look, we are interested in FPS changes as we toggle PCV. In the case of the above example of Zed's Diner. I was getting anywhere from 1-3 & 5-7 additional frames with PCV turned on depending on the area I was in. However, as mentioned earlier PCV does not perform that well on open maps/areas; which Zed's Diner is. Either way, we have noticed an increased in FPS performance, which will more likely be better when we run the map in game.
The UDK Documentations states:
- PCV will automatically detect materials with a Blend Mode of 'BLEND_Translucent' (see-through materials) and not cull objects when looking through something like glass. However it is not reliable, always double check to make sure that the final build doesn't mess with hiding some meshes or lights that shouldn't be hidden.
- In a similar sense, meshes that are 'Hidden in Game' and are not translucent will still be viewed as a visibility blocker. This can result in things being culled that shouldnt be when in game - simple solution is to use a BLEND_Translucent material so PCV acts as if it is glass (eg: get the standard glass material, swap the textures and give it 100% opacity to make it look opaque/solid).
- If there is a part of the map with undesirable culling I recommend copy and pasting only that segment of the map into a new map, testing different options for PCV volumes and do a full rebuild of the PCV. This should hopefully only take a couple of minutes instead of hours to change and test possible options. EG: 5-10 min build vs Hours. Once you find a solution just copy it into your actual map.
- Precomputed Visibility Override Volumes do not work, if anyone has managed to successfully implement them, please provide some details.
- Do not use the 'Incremental Build' build option - the results are not accurate and are full of errors. Only stick with 'Full Rebuild'