SteamVR/Environments/Precomputed Visibility

From Valve Developer Community
Jump to: navigation, search

Precomputed Visibility

The Team Fortress 2 'Supervillain Lair'.

When building a large environment for SteamVR Home, you may find yourself wondering how much stuff the engine will render at any one time. Build too much, and you'll start running into performance issues - with your computer unable to keep up with the number of polygons, props or general details present at any one time.

The prototype Precomputed Visibility system was recently introduced to SteamVR Home as an additional tool to help boost performance in large environments. Useful for expansive, multi-room environments with lots of occlusion (solid walls, floors and similar), this new feature means the engine won't even attempt to render things that players can't see. Another room the other side of a concrete wall might as well not be there from a rendering standpoint.

There's a good chance your pre-existing environment won't benefit from this system - a single, highly detailed room or outdoors scene will have little if any suitable occluding geometry - but for particular cases it may prove itself a useful performance booster.

Note.png Note: While similar in intent to the old Source engine's visibility system, the basic principles of operation of this new system are quite different. So, if you're a veteran Source mapper - the general idea is enough to get you started, but feel thankful that such horrors as Hint brushes and suchlike are a thing of the past.

The Team Fortress 2-themed Supervillain Lair environment was recently upgraded to use the precomputed visibility system - containing many distinct rooms, underground caves and canyons, the map has many areas that aren't visible from each other and is an almost ideal example for our purposes.

This useful feature isn't without its drawbacks, of course. It involves an additional map compilation step which can take a fair amount of time - it dices the world into lots of voxels before determining which voxels are visible from other voxels. The map should also be designed with visibility determination in mind - throwing a few static props together before calling it a day is definitely not a good approach.

Map Setup

Map properties window with appropriate precomputed visibility settings.

In Hammer, with your map open select the 'Map : Map Properties' menu entry. Then set 'Precomputed Visibility' to 'Full visibility solve'.

Showing geometry contributing to visibility determination

Supervillain Lair map showing only geometry contributing to VIS.

To see the geometry it will use to determine visibility, select the 'View : Show Vis Contributors Only' menu entry. Most of your map should disappear - by default, only static Hammer geometry will contribute to visibility determination. Ideally all this geometry should be nicely simple and chunky - with no holes you can see through, and with no unnecessary details to make the calculations more complicated.

Excluding Hammer meshes from visibility calculations

Mesh object properties window with mesh set to be excluded from visibility determination.

You can remove small and overly complex meshes from this set by selecting them and setting 'Exclude from VIS' in the Object Properties. If you can see straight past it (for instance, an ornate window frame, a narrow pillar or similar) then it's good to exclude it from calculations.

Note.png Note: Visibility calculations will ignore translucent surfaces (glass etc.) so it's not necessary to exclude such meshes from visibility determination calculations.

Static props

Static prop object properties window, with prop_static set to be included with visibility determination.

Static props can also be made to contribute to visibility determination - select them and set 'Vis Occluder' in the Object Properties. For the TF2 map, this was done for the large rock models.

Inside versus Outside the environment

Rooms in Supervillain Lair showing simple, contiguous meshes with inwards-facing surfaces.
Room mesh selected to show backfaces.

To determine 'inside' versus 'outside' the map, the system looks at the proportion of fron-facing surfaces visible from a point versus back-facing ones. For general efficiency, it's good to build rooms as Hammer meshes with inwards-facing surfaces only, before detailing them with static props.

Note.png Note: Unlike with old Source engine maps, which used a BSP system where the world had to be 'sealed' from the void, maps in SteamVR Home can be open. If you can't see the geometry, then generally don't bother building it - instead of building a solid box out of brushes, here rooms are best made of inwards-facing surfaces only, with nothing on the 'outside' boxing them in.

If your map is enclosed by a giant box or other large-scale geometry (for example, an old-style skydome model), the entire volume may be considered an interior space, thus it can take much longer for the system to perform the necessary calculations.

Note.png Note: For the TF2 map, the distant mountain / jungle geometry is one large prop_static not set as a Vis Occluder.

Map Building

Building VIS.

To perform the visibility calculations, once you've set the map to require a full visibility solve (see above) you simply need to start a Full Compile as normal. In settings, 'Build vis' should be checked by default.

Particularly large maps can take 30 minutes or more to process, so prepare to be patient!


Wireframe view showing currently visible areas (looks much more useful in 3D, honest).

Once the map has compiled and is running in VR, a super-simple method to check that the visibility system is working is to stick your head through walls to see how much the rest of the world is rendering.

Another, more advanced mode is to set 'r_wireframe 2' in the console in tools mode to show the limits of what is being rendered - navigating around the environment should show additional areas appearing in the distance while other areas disappear.

Note.png Note: The visibility system is fairly coarse-grained, so don't expect pixel-perfect visibility determination - for a technique such as this, there's a balance between rendering cost versus visibility determination cost. If you spend too long deciding whether to render something or not, it may be quicker just to render it anyway.

You can enable and disable the visibility system with 'vis_enable 1 / 0' in the console - combined with SteamVR's Frame Timing graphs, this can be a good measure of rendering performance. Disable SteamVR Home's auto-fidelity system with 'vr_fidelity_level_auto 0' in the console, then set a fixed target level with 'vr_fidelity_level 0 to 7'.