Many reflective materials must be combined with external data so that the Source engine can correctly generate their appearance. This data is stored as a cubemap, a texture which represents a three-dimensional rendering of an area. The Source engine uses env_cubemap entities as sampling points for generating these textures, and saves the cubemaps inside each map's .bsp file. While processing specular and environment-mapped materials, it utilizes them to more accurately generate environments.
In other words, a cubemap creates the textures that a reflective surface will be reflecting.
Declaring areas for cubemaps to cover is simple, just place an env_cubemap point entity inside the space of a map. When the map is compiled with VBSP, world geometry surfaces automatically associate themselves with the nearest env_cubemap and will use the cubemap generated from it. Entities associate themselves with the env_cubemap closest to their origin (alternatively, a cubemap can be applied to specific brush faces in the cubemap's properties); moving entities will dynamically change which cubemap they use. It is important to choose env_cubemap positions properly for both aesthetic and performance issues.
Cubemaps are used in a few specific ways, and should be placed accordingly. Some cubemaps are used for reflections on static world geometry. Others are used with player entities, including NPCs. And the rest are used for any non-player reflective entities. The optimal placement of env_cubemap entities corresponds with each of these uses, to ensure the maximal benefit, visually and in performance. Here are a few simple heuristics to follow:
- If a cubemap is intended for NPCs or the player, the env_cubemap should be placed at head-height (as a rule of thumb, 64 hammer units) above the ground. This way, the cubemap will most accurately represent the world from the perspective of a standing creature.
- If a cubemap is intended for static world geometry, the env_cubemap should be a fair distance (as a rule of thumb, 16 hammer units) away from all brush surfaces.
- A different cubemap should be taken in each area of distinct of visual contrast. A hallway with bright yellow light will need its own env_cubemap, especially if it is next to a room with low blue light. Without two env_cubemap entities, reflections and specular highlights will seem incorrect on entities and world geometry in one of the areas.
Once a map has been compiled and lit by VBSP and VRAD (respectively), the cubemaps can be built. Run the map and allow the any node graphs or other pre-process activities to finish. Then use the
buildcubemaps console command to begin building the cubemaps for the level. In the upper left-hand corner of the screen you’ll be able to see each facet of the cubemap (six per cubemap) render. Depending on your video card, driver and complexity of your scenes, this can take seconds or minutes to complete. Once finished, the map or the game must be restarted for the cubemaps to properly be applied to all surfaces.
Left 4 dead
Team Fortress 2 / Source 2012+ games
Team Fortress 2 does not have a default cubemap applied to reflective surfaces. (There are also similar problems with some installations of Portal 2, except cubemaps will simply not appear.) Everything shiny will shine with a pink and black checkered texture. If you were to build cubemaps now and one of your cubemap is able to see a large shiny surface; the cubemap will register that in its 6 images. That means some objects might shine as if there was something shining next to it with the pink and black texture. To solve this, you need to build the cubemaps with specular turned off. To build cubemaps for your TF2 map, load it up via "Create Server". Then, go to the console and execute the following commands:
Building Cubemaps for LDR or HDR only:
mat_specular 0 buildcubemaps mat_specular 1 disconnect sv_cheats 1 mat_reloadallmaterials sv_cheats 0
Building cubemaps for HDR requires you to repeat these steps after loading your map while HDR is enabled.
sv_cheats 1) before running the
Cubemaps after SteamPipe Update
Due to the SteamPipe update, a recognised problem might be building the cubemaps with no effective results. According to a thread, this problem can be fixed by following those steps:
- Place env_cubemap entities in valid locations in your map, and compile. Important: Name has to shorter than 30 characters (including the .bsp extension), or the .bsp won't be writeable! Also, don't change the map name after compilling, or the cubemaps won't work!
- Use your favorite .bsp pakfile editor (For example, VIDE or Pakrat. Usage of these tools isn't included in this tutorial.), and load your .bsp.
- Delete all files that are a "Texture" or "Texture (HDR) type. (Not "Material" files, only the .vtf's!)
- Save the edited .bsp.
- Copy your map back to your game's maps folder.
- Open console and type: "map -mapname-". (In my case, "ttt_mars_colony_cubemap".)
- Once you're ingame, open the console again and type this: "mat_specular 0" and "buildcubemaps".
- Wait until the cubemaps are built, and then re-enable specular mapping with "mat_specular 1" and reload your materials with "mat_reloadallmaterials".
Cubemaps and HDR
If the map has been compiled with the HDR lighting option enabled in VRAD, cubemaps must be built in both HDR and LDR (non-HDR) modes. Building cubemaps in only one mode will mean that cubemaps will not be present the other mode. For information on how to build cubemaps under HDR, see HDR Lighting Basics.
Cubemaps should be built for LDR and HDR maps. Presuming you are already in HDR mode and have your map loaded fresh from compilation (VRAD must have the '
-both' parameter enabled). Go to the console and execute the following commands:
buildcubemaps mat_hdr_level 0 (to go to LDR) restart (to reload map) buildcubemaps mat_hdr_level 2 (to go back to HDR) restart (to reload map)
This does not apply to CS:GO as HDR cannot be turned off.
Cubemaps are best tested by using the
impulse 81 console command. This replaces the current weapon model with the "cubemap weapon"; a set of spheres, each with different reflective surfaces. By moving around the level it is possible to see what cubemap is being applied at that position in space at any given time, as well as if that cubemap accurately describes the area’s lighting and color. This is the best way to assess the validity of your cubemaps.
For some reason, Team Fortress 2 does not have the "cubemap weapon". The Sniper's primary weapon, however, has a slightly reflective lens on the scope and the Demoman's Bottle, and thus will reflect the cubemap.
The cubemap weapon can be copied from Steam\SteamApps\common\Half-Life 2\hl2\models\shadertest\envballs.mdl to a desired mod which doesn't have it.
env_cubemap entity allows the user to define how large the target cubemap’s texture resolution is. While a larger texture resolution will provide more accurate and “sharp” results when sampled, it also incurs a cost in texture memory. Most cubemaps should only use the default setting in the
env_cubemap entity for their texture resolution (32x32 pixels for each surface). This is generally acceptable in normal conditions. Some exceptions may be necessary for areas of high reflectivity or detail, such as set-pieces for acting.
Because surfaces must approximate their surroundings via cubemaps, using too many cubemaps in a small area can cause noticeable visual discontinuities when moving around. For areas of high reflectivity, it is generally more correct to place one cubemap in the center of the surface and no more. This avoids seams or popping as the view changes.
To determine the cost of cubemaps in any one area, first look at the World Rendering category using the
+showbudget console command. If this category is registering an unusually high cost, it may be due to using too many cubemaps in an area. A simple solution to check for this scenario is to use Hammer to Hide all the cubemaps in the map, and then compile and run the map again. If the performance is noticeably better, cubemap density or resolution may need to be reduced.
Eventually this can also be checked by turning off cubemaps, by using
mat_specular 0 to disable it, however this needs confirmation.