How to Prebake Reflections into Materials in the Source Engine

By: Shy - [08/23/2021]

Here is a bit of a text article to go along with the above video. Sometimes in the world of source mapping you run into situations where auto-baked cubemap reflections just won't cut it. The typical solution to this is assigning brush faces to a specific env_cubemap entity, however this does not always work. In my experience when working on large projects, you can never rely on this manual face assignment to function properly. At some point brush face id’s will randomly change for whatever reason and your cubemaps will suddenly start being assigned to different faces across the map. If your map uses instances? You are pretty much SOL.

So that is where material specific reflections come into play. I know I use the term ‘texture’ in the video for simplicity sake, but a material is what is actually being applied to the game world. Textures are the images that materials are made of. Essentially we are assigning a cubemap to a specific material that can be used around the map. This method can create some very interesting effects, from mini 2d skyboxes, semi dynamic baked reflections using brush entities to swap between states, weird model effects, and probably more I cant think of off the top of my head! These material specific reflections are most useful for fixing large problem areas like in my new map rp_hogsmeade_sbs where the road texture needed to maintain a decent reflection across its entire surface to look good.

There are a few methods to achieve this. The quick and dirty way is to take your map, ideally with all env_cubemaps removed except for the ones placed where you wish to generate the reflections from. You can do this with multiple env_cubemaps but you need to sort through them to find the right ones you want. Next you simply build your cubemaps in game as your normally would, then using a bsp packfile extractor like vide you extract the cubemaps from the map. Congrats you now have a working cubemap texture, this will be used later. This method is also the best way to generate HDR cubemaps, if you want those. I think lightprobe 'filename' 'resolution' can also generate HDR cube prb files. This is also an easier way of getting a single quick cubemap vmt.

The other way to do this is my preferred method but is a lot more hands on. But also allows for more control over the result IE: you get raw pngs you can edit yourself. This really only applies to gmod. The above video documents this process pretty well but I will try and cover the important parts here. First you need the gmod cubemap screenshot tool. If you are using a different game, you can do this other ways but ideally you just load the map or a part of the map into gmod. Navigate to the location you wish to generate the reflection from, point your camera SOUTH and take the cubemap screenshot. What direction is south? Oh boy here we go….

The above image says it all and makes the most sense, but surely someone will flip their lid over it being this simple. Want an explanation about how MY coordinate system is the superior one and why all others are absolutely shit? Click HERE! This article explains fully what NORTH in source engine really is and why. But for simplicity’s sake open the console, type ‘cl_showpos 1’ and set the second number in the angles section to -90 and the others to 0, this will ensure you are facing perfectly level and south. Take your cubemap screenshot now. The files will be found inside this folder “STEAMFOLDER\steamapps\common\GarrysMod\garrysmod\data\cubemaps”. All other file paths in this tutorial I will shorten to this kind of format: “$\garrysmod\data\cubemaps” These folders all live inside of the root GarrysMod game folder. Assume the $ in the beginning is “STEAMFOLDER\steamapps\common\GarrysMod”!

Inside of that cubemap folder you will find another folder named “mapname_#” the number being the screenshot you took. Inside will be your six individual cubemap images. Now is a good time to convert these six images into targas (.TGA). I personally prefer using xnconvert but you can use photoshop or any other program that supports tga exporting. Or skip this part and convert it later after you edit. This step is required as Vtex only takes tga’s or allegedly psd files. Open a new explorer window and navigate to your materialsrc folder, located at “$\garrysmod\materialsrc”. If this folder does not already exist you need to create it. The inside of this folder is essentially the exact same structure as your existing materials folder. Any folder you create in here will be created inside of your actual materials folder when compiling a texture.

In the video I create a folder called ‘test’ you don't need to do this but for this article I will be following the video. You now need to move the six cubemap tga’s into this folder, which for me will be “$\garrysmod\materialsrc\test”. Next right click in the folder, go to new, and select ‘Text Document’. Give this text file a simple name, this will be the name of your actual cubemap texture in the end. For the video, I used ‘tempname’ the text file itself is just left blank for normal cubemaps, typically these files are used to define parameters for the final texture but in this case we don't need any unless you want to create an hdr cubemap. In which case you need to add pfm 1, pfmscale 1, and nocompress 1 to the text file each on their own line. I also assume the files need to be PFM and have no clue how to do this so GL! However I am unsure if this is really needed. I have not tested this but I am pretty sure that even on maps with HDR ONLY lighting, the reflections will still use non hdr versions if they exist. I assume he HDR cubemaps are just so reflections can trigger the HDR iris.

Now we need to rename the images to work properly. The gmod cubemap screenshot tool will have these files named things like ‘left’, ‘right’, ‘up’, etc…. Rename the files with the name of your text file followed by the two letter direction designation, in my case it will be “tempname%%.tga”. The two letter direction designations are UP, DN, LF, RT, FT, and BK. HOWEVER… You need to SWAP your left and right names, meaning the file named ‘left.tga’ will become ‘tempnameRT.tga’ and the file named ‘right.tga’ will become ‘tempnameLF.tga’. There are no spaces or underscores between the name of the file and the direction designation. Now open up an image editor that supports targas, import your ‘tempnameUP.tga’ image and rotate the image 90 degrees COUNTER CLOCKWISE. Save the image and do the same exact thing for ‘tempnameDN.tga’. At this point you could also use your image editor to modify your cubemap images as I do in the video.

Open another explorer and navigate to the “$\bin” folder. Inside of the bin folder you will find a program called “vtex.exe”. Drag your text file from the materialsrc folder onto vtex.exe and it will begin creating a proper cubemap for you. Once finished, you will have a file named testname.vtf inside of your “$\garrysmod\materials\test” folder. Feel free to rename this and move it somewhere more useful if you did not set it up originally. If you did everything right, opening the file in vtfedit and setting the ‘face’ value to 6 (located near the top left under the image tab) will show you a seamless perfect cubemap image.

To apply this to a material, I would recommend first making a copy of the material. Simply copy and paste JUST the VMT file of said material and give it a new name. Now open it up and add or change the $envmap parameter to point to the location of your cubemap vtf. This works in the same way $basetexture or any other texture parameter works inside of a material. This may seem a little strange because typically all reflective materials just use env_cubemap as the parameter for $envmap but you can also point it to an arbitrary texture. Now simply apply this new material somewhere in your map and boom you are done! It may seem complicated at first but the main challenge is simply file processing and that could be automated. This isn’t limited to just world textures either, you can use these cubemap textures on models too! I actually used this in my map rp_republic_base in the elevators. I had to have static cubemaps so that way there would be minimal visual change when players are teleported between the elevator areas, giving them the illusion of actually traveling. I know this method seems a little conviluded, use one of the easier ways explained above if you just want a quick cubemap vtf. I mostly do it this way to show that its possible to MODIFY the images that make up the final result.

Thanks for checking this out! Be sure to Subscribe to my youtube!!

The elevator in rp_republic_base