Graphics and Rendering
Update by Adam Brennecke, Lead Programmer and Executive Producer
Over a year ago, in Update #49, we showed you the first movie of Pillars of Eternity. The movie showcased a beautiful scene in the Dyrwood complete with dynamic lighting, per-pixel occlusion, dynamic water and waterfall, and a day-night cycle. In this update I would like to give you an inside look on how these images are put together and rendered in the game, and I will cover new rendering features that we've added over the past year to address feedback from our backers about how our characters look in the scene. Warning: things might get technical!
We are going to be going on update hiatus for the next three weeks as we prepare for E3 in Los Angeles. After E3, the next update will feature the final classes covering The Front Line (fighters and barbarians).
At E3, the team will be showing Pillars of Eternity at the Paradox booth behind closed doors. To avoid spoiling what we will be showing, we will be saving these moments until you get to play it. Because we want to include you in the experience, we will be taking photos at the booth, and in a future update we will be sharing more screenshots from the demo. To give you a small taste, here's a sneak peek at a scene that will be shown at E3:
As we mentioned previously, our beautiful backgrounds are rendered out of Maya as a 2D image. They are very large images, sometimes over several gigabytes of raw data, and before the images get into the game we run a program that compresses the data. Maya renders out the backgrounds in four layers or "passes": final, depth, normal, and albedo. These passes are combined together in Unity for per-pixel occlusion of 3D objects, and for real-time dynamic lighting. When we bring the backgrounds into the game, they look like a flat 2D plane, and when viewed in Unity's editor the whole world has an awkward skewed look to it. The illusion comes together only when an orthographic camera is placed at the perfect angle.
Next we overlay the 3D world on top of the 2D rendered image. The characters are dynamic 3D skinned meshes that are animated and then rendered into the scene with a variety of shaders and materials. Our default material that we use on most characters includes a normal map (adds tiny variations in surface detail), specular map (adds shininess), and an albedo map (adds the base color). The default material also supports a tint map, which allows our designers and you to customize the colors of armor, hair, and skin.
We have other shaders that can change the look and feel of characters. For example, we have a metal shader for armor that adds an extra level of shininess and can reflect the environment via an environment map. A Cloth shader removes the shininess, and allows the character artists to make outfits made up of cotton, wool, and satin. We have special materials, like an emissive shader that isn't affected by light, used for the fire-godlike, ghosts, spectres, and the windows seen in the screenshots and video.
Because the characters are 3D, they need to be lit differently than the background image. We use a system with two directional lights. The first directional light is the key light and typically matches the sun color and intensity in outdoor scenes, and this light can be modified by the day-night cycle to cast moonlight at night. The second directional light is used as a fill light to make sure the "back side" of a character isn't in total darkness. The two lights are adjusted per scene depending on the pre-rendered light settings to match the sun direction, mood, and desired atmosphere.
In addition to the directional lights, we use dynamic deferred lights that can affect the background and characters. For example, if a torch is placed in a scene, the torch can illuminate both the 2D environment and a 3D character standing nearby. In addition, deferred lights are used for spell effects; a fireball explosion emits a burst of light, brightening up a dark dungeon room.
Bringing it all together
We noticed, and so did many of you, after releasing our first few screenshots, the 3D characters were not matching the 2D rendered scene as much as we would have hoped. So we put our thinking caps on, and we came up with new features since our first batch of screenshots, including dynamic ambient and a shadow control system.
To really make sure the characters fit in the scene, we came up with an ambient system that samples color from the 2D background, simulating a quick and dirty global illumination model. Characters pick up subtle color variations depending on where they are standing and what type of environment they are in. If a character is standing in a lush green jungle, it will pick up a subtle green hue from the light reflected off the environment. Game programmers love fast and cheap methods, and the ambient system gives us great results with little impact on rendering performance.
Ambient before and after:
Another feature that we've added recently to solve the issue of grounding characters into the scene is a system to shadow 3D characters when traversing into dark shadowy areas in the 2D image. The new system samples a low resolution image map which controls the contribution of the directional sunlight on the character, and to avoid double shadows, the same image controls the value of the dynamic shadow map. Lastly, to better match the 2D and 3D shadows, we color the dynamic shadow to match the 2D rendered shadow color (which often has a blue hue to it).
Shadow Blending before and after:
To tie everything together, we can optionally add post process effects. In this scene, we've added a very subtle bloom effect that effects both the environment and characters.
I hope you didn't get lost in all the technical talk! The important thing is that we hope you like the end result. We are satisfied with where we are at, but we always have a few ideas on how to improve the look and quality of the graphics. Improving the look of the game will be an ongoing process until we ship... and beyond. If you have any questions, please ask in our forums! Thanks for reading.