This is a summary of a longer post on polyknightgames.com.
For InnerSpace, we wanted a whole new look that not only added to our unique world, but also made us stand out from the crowd. Our solution for this was by creating our own custom shader.
What is a Shader?
Put simply, a shader is a script that defines how an object will be drawn and shaded in a 3D scene. Different materials, such as glass and stone, affect light very differently, so they must be treated differently. This is where shaders come into play. We use shaders in games to mimic these different type of materials in our 3D space, without the limitation of reality.
We knew from the beginning that we would be limited on manpower, so realistic textures and materials wouldn’t be possible. We wanted to create a unique feel for the game that was stylized and new. To do so, we created a shading style that combined a more realistic, almost otherworldly silhouette, with controlled but expressive bursts of color.
How We Made It
There are 3 elements that went into our shaders:
1. View-Direction Based Shading
2. Colored Shadows
3. Shadows Masking and Fresnels
View-Direction Based Shading allows us to achieve a flat shaded appearance, while allowing objects to respond to scene lighting.
Colored Shadows is where our shaders really stand out from the crowd. On a per-object basis, we’re able to control the color, saturation, and brightness of the shadows in our scenes. This gives us complete control over the aesthetics of our game. And if that wasn’t enough, we decided to replace the greyscale data normally used for shadows with color data, allowing for shading that saturates the base colors without dimming or muting them.
Shadowing Masking and Fresnels helps give our scenes depth. We’re using a similar technique to Image-based lighting, which is popular in the gaming industry currently, but with a few unique twists and turns. By using greyscale shadows as masks for the colored Fresnel, we're able to selectively add dimension to objects, while maintaining a "flat" and consistent look in our scene.
All of this technical work has produced two shaders: one for specular/conductive surfaces, like metal, and one for matte surfaces, like wood. By approaching our design in this manner, we drastically lightened the per-object workload, as our shaders offer a wide range of customizability, and don’t require specific specular, normal, or diff maps.