Snowbase Postmortem - 3D Skybox Breakdown

Idolon

they/them
aa
Feb 7, 2008
2,107
6,116
This article is a technical breakdown of how the 3D skybox in Snowbase functions. It covers skybox replicas, skybox water, and the horizon line.

Replicas​

The most notable thing about the Snowbase skybox is that when you are in one stage of the map, you can see the other stage in the distance. Typically a 3D skybox will have a hole where the real map is located. To achieve the effect of stages being visible to one another, we don't do this, and instead build the entire scene in the skybox. In addition, we have skybox-scale replicas of the layout.

1656255816282.png1656255898823.png

These replicas are func_brush / prop_dynamic so that they can be toggled on and off, as we do not want to render the replica of a stage while we are in that stage. Otherwise, you get weird rendering effects where the skybox and real map don't quite line up. These could be solved by ensuring that the two line up exactly, but it is easier to just disable the replicas when we don't need them.

1656256134042.png1656256170277.png

There are a few additional requirements for this method.
  1. Any elements that are not toggled off (displacements), you will either need to ensure that the replica and map line up exactly, or that the skybox version sits completely underneath the real version as to not create any visual bugs.
  2. By default, objects in the 3D skybox can cast shadows onto the real map. You will most likely want to compile with vrad -noskyboxrecuse to disable this.
  3. The different stages of the map cannot be placed in arbitrary locations, and must be correctly placed relative to one another in "real" Hammer units to line up with where they are located in the skybox. This may place some limitations on how far apart your stages can be located.
On the topic of item 1, there was one situation I had where exact replicas were needed. From inside the final point of stage 2, you can see the beginning of the stage through a window. It is impossible to enable/disable the replica per-player depending on where they are standing, so we must render the skybox replica while players are at the real map location it represents. This required turning some brushwork into a model, as the replica could not be exact at 1/16th scale otherwise.

1656256550966.png

One last note: You can use a grate texture to represent stairs at skybox scale.

1656258501261.png

Water​

I used expensive water with real-time reflections (a choice I would later regret after many people complained about framerate issues). This created some issues when trying to get a good seam between the real map water and skybox water, as I was originally under the impression that I would want to use cheap water in the skybox to improve performance. However, there was always a noticeable seam between the two textures, since they use completely different shaders. I tried assigning both waters the same cubemap, but this did nothing, as assigning a cubemap to expensive water with real-time reflections does not actually do anything.

Through some experimentation, I found that using the same expensive water in the skybox removed the visual seam and had no noticeable impact on performance. I believe the reason for this is that real-time reflections are achieved in Source by re-rendering the map from a different viewpoint under the water looking up, producing a texture that is stretched to fit the screen and used as the reflection in the water. As such, having any expensive water in the PVS will cause the performance hit of real-time reflections, and having more expensive water visible does not have much performance impact. This is also why you cannot have multiple levels of expensive water in the PVS at the same time, as this would require rendering a new reflection for each level. (However, since the 3D skybox is not part of the PVS, you do not need to make the water in the real map and skybox line be on the same level.)

An additional quirk of this system is that real-time reflections are only calculated when expensive water is in the PVS. The engine also does not clear the reflection texture when there are no reflections to render. Instead, the last frame of reflections stays in memory. What this means is, if you have expensive water in the 3D skybox, and there is currently no expensive water in the PVS, the water in the skybox will begin reflecting whatever was last in memory, causing weird rendering artifacts (similar to what you see when you have multiple levels of expensive water in the PVS).

To solve this, when you are in the second stage, a large flat color texture appears just above the water in the skybox, hiding the expensive water. I think this looks better regardless, as the waves in the water create a lot of visual noise. It also helps make another visual trick easier to achieve.

1656257518638.png1656257840366.png

One last visual trick: The real map water and skybox water have different texture scales. It becomes pretty obvious when you look closely, but from gameplay space it just appears that the water in the distance is less turbulent, which feels correct and reduces some visual noise.

1656258036818.png

Horizon​

Every map with water stretching out as far as the eye can see has to somehow solve the problem of making the horizon look correct. I went with what I think is a common solution, which is to put a large cylinder around the skybox with a gradient, providing a nice clean horizon line in the distance that fades nicely into the skybox above. The color of the gradient roughly matches the color of the fog.

1656258196665.png

However, this creates an issue when we go to the 2nd stage, as the fake horizon line is visibly below the player, and you begin to see what feels like the curvature of the Earth, if Earth was 20% its original size. The solution is to create a second fake horizon that turns on when we are in stage 2. This horizon has the same gradient cylinder as before, but raised up to appear at player height. Below it is another cylinder with a flat color to match the water, which visually extends the water out to our new fake horizon. There is also a second gradient cylinder below to mimick the reflection of the sky in the water. The second gradient doesn't look great, since that reflection should extend much further out into the water, but it's better than nothing.

1656258675294.png1656258741456.png1656258326593.png



I believe that's more or less all the techniques I used to achieve the skybox in Snowbase. Please let me know if I've missed anything or if you have any questions!