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
.
So how do I use them?
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.
- If a cubemap is meant to be used by a player, say, as the reflection of a weapon scope, the cubemap should be placed 64 Hammer units above the ground. This ensures the perspective of the cubemap will be correct.
- If a cubemap is meant to be used by the surface of a brush, such as a glass pane, place it in the center of the brush 16 units away from the face meant to receive the reflection.
- If two visually distinct areas are next to one another, such as a room lit with blue tones next to a room lit with red ones, two different cubemaps will be needed, or else reflections will appear wrong.
- If the player moves between two cubemaps in the same general area, reflections on surfaces will suddenly pop to using the second one. For smaller rooms and spaces, it's best to place a single cubemap in the center of the room to avoid visual incongruities.
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.
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.
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.
- Open up the Command Prompt.
- 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'sbin
folder, for instance. - 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. - 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.
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.