Steel Circus is a futuristic ball sport with MOBA or “Hero Shooter” elements. Each champion has two unique skills, such as placing defensive walls or stunning enemies.

The arena floor is one of the most prominent assets in the game – a giant display that shows player UIs, skills’ areas of effect, and things like goal animations or customizable spraytags. We really like how it ties elements into the game world that would traditionally be presented as UI overlays.

Players spawning from inside the floor at the beginning of a match.

There’s quite a few things going on in rendering the floor, notably raymarched light scattering under its surface, and indirect lighting of the characters. In this post, I’ll break down all the different parts that went into it:

A piece-by-piece breakdown of how we render the floor.

The floor’s reflections are just planar reflections, rendered with a flipped camera and distorted by the floor’s normal map. To reduce noisy details, we do a z-based blur that blurs pixels the farther away they are from the surface.

Floor reflections without (left) and with (right) z-Blur. Since the floor is flat, we can easily render these reflections with a flipped camera and a skewed projection matrix.

The floor’s contents (contained in a render texture) are rendered as if they were emitted from about ten inches below the surface. We refract view rays as they enter the surface and then raymarch to the bottom, simulating a rough approximation of the light scattering inside. As the camera gets close to the floor, we also mask out the contents with a procedural LCD grid. All of this is done in the floor’s shader.

Floor with refractions (left), raymarched scatter (middle) and LCD mask (right)

Here’s an illustration of our light scattering “simulation”:

Since the floor is flat and of fixed size, we can also easily use its contents to do some indirect lighting on objects on top of it. This indirect lighting is part of our standard shader that we use for objects in the arena:

Here’s an old shot of our setup from inside the Unity editor. Note that we’re not only rendering the floor’s emissive texture in realtime, but also its normal map (and originally, to the right, a dirt map, but we’ve removed that feature since).

Rendering the normal map in realtime allows us to do all kinds of fancy effects that interact great with the floor’s reflections and refractions.

An old placeholder asset for health pickups we spawn in the game. We use the stencil buffer to cut a hole in the floor and the real-time normal map to create waves in the floor that interact with the light-scattering and reflection features.