All of these can be seen in my 2014 Tech Art Reel at higher detail.
DYNAMIC SKYBOXESThe basic sky material template was used by most shipping maps in the first half of the game. Level/Lighting artists could tune sky color, lighing direction/color and textures for sun/moon disc and clouds. Clouds used wrapped diffuse lighting based on sun direction input. Initially the intention was to use these templates to get mood and color right, then go back and make a custom material for each map. In the end, the quick iteration these materials allowed was more useful than custom skies.
These templates are based loosely on the skybox material that ships with UDK. One fun difference; because we did not have Light Direction available in materials (because deferred lighting), I did a Euler to Vector conversion in the material, so that the material's Sun Direction input matched that of the Directional Light in the level. This was evaluted on the CPU, you can tell in our editor because of the green outlines around the nodes (cool feature Steve added). The math to convert UDK Euler Angles to a vector is something like...
PBR TEMPLATESSteve Anichini did most of the engine-side work, and dives in to more technical details on his blog.
Collaborating with the art team on this was a lot of fun. Its a big shift in workflow for them, and they did really well with it! We definitely had room for improvement in our PBR, but overall, I think the art team was happy with the new workflow and the end results.
Random PBR Notes:
- Before the engine supported PBR materials had cubemap probe parameters for generic glossy reflections (not tied to any lighting parameters). I was able to use this and unreal's material editor to make prototype PBR templates. They converted specular power to gloss, had energy conserving spec, specular fresnel, mapped gloss to the cube probe parameters, and had a hacky diffuse/spec normalization. We used these prototype templates in production while Steve implemented PBR engine side, then later made the switch to real (engine side) PBR in the templates.
- Like most people we packed multiple material masks into a single texture. Specular mask in the red channel, Gloss in the green, blue was reserved for special case (emissive, color shifting, etc). To save performance and memory we had template variants with flat gloss/spec values that did not use mask textures.
- Fully metallic objects can have their diffuse turned off completely, for us this saved about 1/3 their shader cost.
- All materials had optional specular fresnel term (because everything has fresnel, and everything has fresnel). This looks excellent when it works, but its difficult to make this look right everywhere with basic world space environment mapping, its also relatively expensive on the old hardware. We used this sparingly in the environments, reserved it mostly to hero props, weapons and characters.
- For characters, we masked the specular fresnel term by downward facing normals to reduce a sometimes unnatural looking glow from below.
- For weapons, we baked a static specular fresnel "shadow map" out of 3dsMax. This gave us high detail occlusion of the specular fresnel on weapons when they were in the firing position, this wasn't technically correct when reloading or prone, but wasn't too noticeable.
- Making glass or water in PBR? You really need to consider the Fresnel effect. I've made my share of hacky water and glass materials that have no physical basis. If you want to get more PBR with them...
- TRANSLUCENT SURFACES
Opacity=Fresnel (1.0 at glancing angles, about .03 viewed straight on)
- OPAQUE SURFACES (like a deep body of water or false window)
Specular/Reflections = Fresnel (1.0 glancing to .03 straight on),
Diffuse = Fresnel (black at glancing, diffuse color straight on)
PARALLAX CUBEMAP CORRECTION
VERTEX SHADER MORPH TARGETS
This was proposed to play some minor animation when looting a mesh, without the need of a rig or animation setup, it also allowed the loot to keep static lighting/light maps. A maxscript was used to bake vertex offsets from the unlooted to looted state into additional UV channels. In unreal, a vertex animation shader unpacks the offsets.
SHRINKING PROCEDURAL BUILDINGS
Early in the project, we relied heavily on Proc Building auto generated LODs. With the deep nature of our architecture, it was difficult to bring the LOD transition close enough without seeing a major pop. This vertex animation shader flattened the building out before swapping to the LOD. By the end of the project, level layout and art direction changed enough that we could drop Proc LODs completely to save memory.
SCREEN BASED LENS FLARES
Our tech team implemented a data driven render to texture system. This allowed us to use Unreal's material editor to create texture filters, multiple filters/textures could be chained together. Mathi Nagaragan did most of the tech work for this system, which included a way for us to author loops in the Material Editor. One of his test cases for the system was a basic implementation of SSR, it was pretty amazing to see this done in the material editor.
For my first test of this system, I was working on an implementation of screen based lens flares. I started with Pseudo Lens Flares, hexagonal blurred the final result, and added a star burst at the source of the flare (3 directional blurs).
Sidenote: This paper is an excellent reference for why cameras make specific bokeh and starburst shapes. (around page 30)
BURIAL AT SEA DLC
IES PROFILESThese were added to get a cheap, and more interesting cast of light from the Art Deco light fixtures (we were using multiple spots per light before IES). A 1D texture is used to define a gradient across the lighting vector. This is done in the material function for the light, no built-in engine optimizations like in UE4, but this still may be useful if you want to do colored IES.
LIZ VISION SCENES
I helped out the Narrative Scripting team with a handful of "Liz Sense" scenes with animation, post processing/FX and scripting. Some of these FX were also used in the lockpicking mini game.
Wow, still reading? Thanks!
That's all I have this post, let me know if you have any feedback/questions, I'll try and keep future posts shorter :)