Valve Developer Union

Cubemaps: What They Do, and How to Use Them

(October 10, 2017)


If the Source engine were to calculate reflections in real time for every piece of metal and glass in a scene, it would make all but the most competent computers crack under the pressure of rendering it. Instead, Valve implemented a tradeoff that looks the part but is much less expensive to run: cubemaps.

What is a cubemap?

A cubemap is a set of six images, one for each face of a cube, that can be rendered in place of the scene itself in the reflection of shiny materials. Cubemaps are completely static. Whatever props, lights, and scenery around are baked into the cubemap. Players, changes in scenery, decals, and anything not present at time of rendering will not appear in a cubemap when the map is played. The following cubemap can be seen in the plate glass window of cs_office.

The cubemap that the window in cs_office is reflecting The plate glass window's resulting reflection
Left: The cubemap that the window in cs_office is reflecting
Right: The plate glass window's resulting reflection

So how do I use them?

env_cubemap

Cubemaps will be rendered wherever an env_cubemap exists. Shiny materials on brushes and models will look for the nearest cubemap and render it as their reflection. This process is known as building cubemaps. With smart placing, cubemaps look like live reflections, but are far cheaper to render. To build your cubemaps in the game, run buildcubemaps in the console after loading your map. A series of images will flash on the screen and the map will reload. If necessary, restart the game to view the results.

Each cubemap gets embedded in your BSP and increases the file size and the memory your map uses when it runs. The goal is to find the lowest amount of env_cubemap entities that'll work for your map, as well as the ideal places to place them in your level.

Info

The price of beauty

The time it takes for cubemaps to render is measured in the "World Rendering" meter on your Showbudget panel. If that bar seems unusually high, you may have to lower cubemap density.

To look to one of Valve's maps, here is the placement of a few of the cubemaps at the CT spawn of de_tides. They've been highlighted to make spotting them easier. Note in particular the use of two env_cubemap entities, one in the rocky pathway and another in the hallway behind it. This prevents the reflections of player's weapon scopes from showing the darkness of the hallway when they're out in the open air.

env_cubemap entities on de_tides
env_cubemap entities on de_tides

Two important things to remember with cubemaps are that any changes in the map post-building, either through recompiling it or through renaming the BSP file, will result in reset or broken cubemaps. Only build when you're sure the map can go through no further revisions. Cubemaps can also only be built if your game resolution is higher than 512x512. This is because of the way cubemaps are built; if they don't have enough space to render on your screen, the game will crash.

Testing your cubemaps

Though not all games support it, a good way to test your cubemaps is through the use of impulse 81, or the weapon_cubemap. The weapon_cubemap replaces your current weapon with a set of six spheres, each reflecting the nearest cubemap in a different way. weapon_cubemap works in the earlier Source games, including Half-Life 2, Half-Life 2: Deathmatch, and Counter-Strike: Source. (Cheats must be on before you give yourself weapon_cubemap.)

If your specific game doesn't have it, use the scope of a sniper rifle or any other weapon with an obvious reflection. Garry's Mod mappers can use this addon, which contains the weapon_cubemap, to test their reflections.

weapon_cubemap being used to test reflections on de_dust2
weapon_cubemap being used to test reflections on de_dust2

What to do if your cubemaps won't build

Placement is generally the easier part of working with cubemaps; building them in the engine is a little more complicated. Source games since The Orange Box often have major issues building cubemaps unless special precautions are taken. Sometimes, without workarounds, games will refuse to build cubemaps altogether. If your map falls into one of the following use cases, place your cubemaps as normal and follow the instructions below to get them working.

If your map uses HDR

If you've compiled your map for HDR, you'll need to build cubemaps twice (once for HDR being on, and once for HDR being off). Run the following commands in the console in the order that they're listed, or write a custom config file to simplify the process.

mat_hdr_level 0
reload
buildcubemaps
mat_hdr_level 2
reload

Counter-Strike: Global Offensive only runs in HDR mode, so you only need to worry about building cubemaps for it once.

If buildcubemaps seemingly does nothing

Sometimes, buildcubemaps will appear to do absolutely nothing. You'll build, but the default cubemaps will still be in the map. The issue comes from the filesystem DLL the game uses, so barring being able to recompile the game's code, you'll need to delete the defaults before you build. Cubemaps are embedded into your map like any custom texture or model, and you can use a tool like Pakrat or VIDE to delete them. We'll be using BSPZIP for the purposes of this guide.

Deleting the cubemaps from a map using BSPZIP
Deleting the cubemaps from a map using BSPZIP
  1. Open up the Command Prompt.
  2. Navigate to the bin folder of the game you're building for. cd C:\Program Files (x86)\Steam\steamapps\common\Half-Life 2\bin is Half-Life 2's bin folder, for instance.
  3. Run bspzip -deletecubemaps [bsp], replacing [bsp] with the path to your map. -deletecubemaps will delete all VTF files stored in the map, so if you've embedded any custom content in the map, make sure you have a backup or extract it first.
  4. Load the game and run the following commands in the console, in the order listed.
mat_specular 0
map [your map]
sv_cheats 1
buildcubemaps
disconnect

Cubemaps should now be properly built. If you need to embed custom textures or models into a map, it's recommended that you do so after building cubemaps.

If your map is for Left 4 Dead or Left 4 Dead 2

The Left 4 Dead games need to be fully restarted before newly-built cubemaps will render.

If your map is for Source 2013 MP Base or Team Fortress 2

Team Fortress 2 has no default cubemaps. If you see missing textures in your reflections, that will get captured when you build cubemaps. As a result, you'll have to turn mat_specular off in the console before you build. Run these commands:

mat_specular 0
map [your map]
sv_cheats 1
buildcubemaps
disconnect
mat_specular 1
map [your map]

If you're building for HDR, remember to repeat the process with mat_hdr_level set to 2.

If your map is for Portal 2

If your map is located in the Portal 2\portal2\maps directory, the game will crash when you try to build cubemaps. As a workaround, move the BSP to Portal 2\portal2_dlc2\maps and build there.

If your map is for Source Filmmaker

Source Filmmaker will only render one side of the cubemaps. To properly build cubemaps for Source Filmmaker, copy your map and its assets to Alien Swarm and build in that game. Source Filmmaker requires your map be HDR in order to use it in a scene, so switch mat_hdr_level to 2 before building.

If your map is for Counter-Strike: Global Offensive

Counter-Strike: Global Offensive needs to be started with the -insecure launch option, or else it'll refuse to build cubemaps.

The -insecure flag set for Counter-Strike: Global Offensive's launch options
The -insecure flag set for Counter-Strike: Global Offensive's launch options

Cubemaps are an important part of getting the look of your map right. Never release a map without building them, arduous as they may be.