Today we wanted to dive into getting the most out of the GPU. Source is a decently CPU limited engine, (growing out of that shell with each incremental Valve release). Compared to most engines out there, Source isn't really utilizing the GPU the best it can, or could be. There's a lot of free performance there because a lot of stock Source engine effects are mostly CPU driven.
Throughout the year we've been moving effects entirely onto the GPU and removing CPU cost. This has been critical in freeing up CPU performance for the things that the CPU should really be taking care of like AI or physics. Previously, most shader operations mostly if not entirely were handled by the CPU. Such as movement, scrolling, texture scaling, and UV operations. Some of the stock shaders still are CPU driven, thanks to their internal nature.
All of the shaders listed today are completely driven by the GPU, and only the physical costs are handled by the CPU, such as applying said shader to a brush surface, or a model and rendering calls.
Skydome and Sun Shader
One of our main design goals like stated yesterday has been improving visual fidelity, without sacrificing performance. A min goal of that goal has also just been making the world feel alive, and less static/flat. The sky was one of the main elements in the world to get a nice face lift. Previously we spent some time on making the 3d skybox just look better. Adding effects like scrolling clouds on a brush face, distant smoke plumes, etc. That didn't prove to be all to noticable though. We wanted to make sure the player could see a big visual difference from Valves 3d skyboxes, to ours.
So to combat this problem, we just made a whole new shader. The skydome shader procedurally generates clouds on the fly. Consistent to the name we now use actual sky dome models in our 3d skyboxes and apply the shader to that model. The skydome shader completely creates unique cloud movement, and can also create any variation of cloud density as well as wind intensity and direction. The skydome shader is the beginning of our long list of shaders that are entirely GPU instanced and driven.
Along with that, the skydome shader (and a few others) are Depth tested. Doing this allows shaders to effect other various shaders such as the sun and sun rays. A separate shader that's part of the overall skydome effect is also a revamped sun effect. The stock sun effect has also been turned into it's own shader (versus being a sprite effect like Valves). The new sun shader illuminates the hemisphere of the sky it's located in, like it should. In the video below we've recorded a time-lapse in game speed up by 3 times. Clouds automatically occlude the sun as they scroll by, and also effect sun rays.
The skydome shader also features a couple of other nifty things such as:
- Can be edited and changed real time
- Always dynamic
- Can create a ton of clouds and tint their color to create a stomry scene
- Can turn day to night, thus creating day to night cycles real time
- Can generate stars for a night sky on the fly, or even for a space game.
Flowmaps and Realtime Puddles
Flowmaps aren't an entirely new thing to Source, for instance games like Left 4 Dead 2 and beyond heavily make use of flowmaps. Flowmaps are three channel based images that define water movement speed and flow. For source 2007 we've added flowmap support to the stock water shader. Flow simulation and direction is entirely handled by the GPU as well. While we don;t really have that much water in city17, we've added this feature for any modders that might.
In order to create flowmaps we take and overview screenshot of the worlds geometry (directly around the body of water), grab that, then go into Photoshop and hand paint flow over.
While importing the geometry into a special program is much more accurate, hand painting flowmaps has a pretty big upside. While we lose some accuracy we no longer have to spend as much time creating flowmaps, secondly we can easily iterate flowmaps because of the layer fucntionality Phostoshop provides. If flow needs to be changed or adjusted we can easily resave the flowmap and reload textures while in-game.
Our future plans are for objects to directly effect flow. For instance: instead of creating particles to simulate splashes and ripples; instead, we'd have physical objects such as debris and NPC's including the Player directly manipulating the flowmap real time using both movement speed and object size and density.
Back in one of our really old media updates we talked about using realtime puddles. Puddles back then used a stock shader valve released in the Orange Box. Puddles back then completely re-rendered the world, like water, making them pretty expensive to have in a scene (including that only one per scene could be visible at once.) We've created an entirely new shader that takes what the player sees, flips it upside down, then warps it using normal maps. This effect is much cheaper because we're grabbing the framebuffer and then just copying it and doing some minor edits to it in UV space. Because of this, we can also have as many puddles in a scene we want. The shader is also procedurally driven.
For instance we use two texture sheets, (green channel) to define the warp offset of the frambuffers UV. We then take those two effects down the road and mask them off if needed.
Doing this creates an entirely random effect, almostly entirely simulating an always unique effect per puddle. The shader supports using any texture thanks to using only the green channel. You could even use a grass texture to warp the effect, making it feel like grass was actually floating on the puddle.
VIDEO OF PUDDLE SHADER INCOMING
The puddle shader goes beyond just puddles though. We heavily use it for most of our water effects now. For example, the puddle shader can be applied to a displacement surface, then warped by the displacement verts to simulate a river bending and twisting. Scrunching the texture closer slows down flow speed, while stretching it speeds up flow speed. Due to the nature of the shader, the frambuffer follows it's own unique UV scale, meaning you can stretch the heck out of the effect without it looking terrible in-game.
All of our water effects (and stock shaders too) now support basetexture lookup. Effects like debris and/or froth can be placed on the surface of the water and be effected by flow. This brings the shader closer to that of effects seen in other engines like UDK. Water performance had been an issue fans brought up in previous updates (as well as playtests) Performance wise, puddles run pretty great, being 1/14th the cost of the stock puddle shader effect. Flowmaps also add no additonal cost to the water shader since it's all handled by the GPU.
We've added a few extra optimization features to various entities such as:
- Toggeling whether or not an object creates reflections or refractions (huge performance boost!).
- Refraction and reflection effects no longer reflect and refract each other
- Water particles use variation code to generate cheaper versions randomly.
- Water particles in general can be completely turned off and reverted to stock.
- Certain effects are excluded from reflecting in water such as sun rays (this was a huge performance waster before).
With our sun rays, previously we re-rendered the world to find out what was opaque, and what was not, and then tested that against the sky being visible. Mostly, that was a prototype version of sun rays, though that we did plan to ship with. We've made a lot of improvements to Source's Depth buffer, and now instead use that. No longer do we have to re-render the world. Sun ray cost has been cut in half, making it a 0.5-1ms effect whereas before it was anywhere between 3-5ms. Regardless of well it runs now, we still have definable settings in our custom video options to define quality/cost.
That's it for today! Follow us on Twitter for updates on what's going on in development, as well as our blog for City 17 and other development news from us. If you'd like to get in contact with us, be sure to email us at firstname.lastname@example.org.