As “ Senior Technical Artist” on Rift, my tasks often involved the creation of specialized tool software; helping non-technical people within the art dept (usually) solve specific problems; interfacing between the art, management, and engineering groups… But the part of my job that’s been most-visible to game players is shading.
The funny thing is that while shading is visible everywhere – every pixel you see is a shaded one – shading is a hidden art, like photographic lighting. It rarely has much of a narrative representational thrust of its own. You can make a drawing without shading, just as you can make a photo without any effort or thought about lighting. Yet you’ll be hard pressed to find an un-shaded painting (or drawing) in a gallery or museum, just as you’ll rarely see photos without very deliberate lighting in those venues, or in portrait or advertising studios; or especially in films, where the creators of those media have long learned and understood the value of careful control over tone, grading, and color. Not just on one costume or in one shot, but across the whole of their dramatic/artistic enterprise.
In computer image creation, shading – the assignment of colors to pixels at all levels of detail – is usually accomplished by the use of micro-programs called “shaders.” In the case of Rift, I wrote nearly every shader, re-wrote those I didn’t initially create, or created the shader-writing software that generated the shaders.
The exact meaning of “shader” can be a bit squirrelly for some. Engineers may prefer to call them “streaming processor functions” because they may not be “shading” visible images at all (see Mark Harris’s excellent GPGPU.org for some counter-examples). Most of the time, artists use the term “shader” and “material” interchangeably. The difference between a identically-colored materials that look like chalk, or ice, or plastic, or metal, or glowing ooze? The shader.
Shaders and interactions between shaders are also used to create lighting effects, glows, glints, shadows, depth buffers, and more. We’ll talk about them as they come along in this series.
In the case of Rift, shaders for materials (and other purposes) not only had to look great for the best, high-end computers, they also had to be “heterofunctional”: they needed to work on a wide variety of different PC’s and in different environments. Some players had top-drawer computers with high-dollar GPU cards, while others had rather modest hand-me-down laptops. It was important to provide the best experience possible – both pictorially and in terms of playable frame rate – for all of these many thousands of players, across literally hundreds of material variations.
To complicate matters further, nearly all material shaders needed to have working analogues that run not only in the game as shipped, but also in our art-creation tools. This meant that each material needed its own OpenGL CgFX versions for use in Maya, custom preview modes for model building and animation, special DirectX versions for use in our modified Gamebryo 2.6 toolchain, some experiments with WebGL and Unity, and of course the various editions for player consumption at varying degrees of performance (at least two, sometimes up to five different versions).
As usual, the way to manage vast complexity is to bite off a little at a time and revise/polish as you go. I used to say (to steal a bit of a metaphor from.. Paul Graham? Not sure at this point, but we all steal from the best) that we started by jumping off a cliff and I built an airplane on the way down.