One of the greatest things about being in the computer graphics industry is the sheer helpfulness of people. Almost without fail people are willing to help each other out, overcome difficulties, and take the time to share experiences, successes, and failures.
I got the idea for this book when I was chatting with Phil Taylor, the product manager of the DirectX SDK team at Microsoft. He was his usual ebullient self, going on about the new "shader" stuff that was coming out with the next version of DirectX. He was also lamenting about how tough it was to get people to understand what the advantage of shaders was, particularly when using textures as data. At one point, he said something like, "I mean, it's not an image, it's just a matrix of four element values—it could hold anything." It was at that point that I decided he was on to something. Only a small minority of graphics programmers have actually done tricks with data masquerading as textures, and fewer possess a solid understanding of how specifying a light, a material, and a triangle gets turned into a rendered object. Shaders let you do that and more, but in order to use them to good effect, you have to understand the power they place in your hands. To do that, you need knowledge.
My original vision for this book was along the lines of "a little book of shaders," but it didn't turn out that way. The further I got involved in the writing, the more I discovered that you did need extensive knowledge of not only the commands that were available to you and what they did, but how to assemble them to suit your needs. I knew that I'd have to include a little section to discuss the math, but when I started writing about the math involved with shading and illumination, with materials and lights, I knew I had to back up and start from the beginning.
My goal is to provide you with the foundations that you need to write your own shaders. There's not only a lot of theoretical stuff out there, but there's a golden opportunity to do your own thing and create your own custom style. My goal is to give you enough knowledge so that you can feel comfortable writing your own shaders. You should be able to feel free to go beyond the bounds of creating diffuse and specular lighting, and write your own with three kinds of diffuse and five kinds of specular and an emissive term based upon the proximity of the object to a power source. That is exactly what writing a shader is all about. There's no mystery to it. There are a few conventions that you should follow, but the one thing that I hope you'll learn is that what's "accepted," is just someone else's hack that got perpetuated.
There's a story that Mike Abrash related once while he was working on Quake II. He and John Carmak had gone to a convention and saw a competitor's game. The game had dynamic lighting effects—something they hadn't thought necessary to implement at the time. Seeing it in action, however, made them change their minds. So it got put on Mike's "to-do" list. A few weeks later, John asked if Mike had gotten around to putting it in yet. "Nope. I bet I can do it in an hour," says John, and he goes away. (John is known for some ferocious coding habits.) According to Mike, 54 minutes later, John says he's done. He brings up the game, and fires a rocket down a long corridor. The corridor illuminates and it follows the rocket down the length, and it looks great! John had taken the rocket's location, cast rays up, down, left, and right, and pasted a spotlight texture at the intersection of the ray with any wall it found. It wasn't realistic, but in the short time you got to see it, it was enough to give you the illusion of real lighting. It was a hack, it looked good, and they shipped it. The moral of graphics programming is once it looks good enough, it's good enough.
As my deadline for this book approaches, there's been no small upheaval in the shader world. Higher level shading languages came too late for me to write about with any depth, so I focused on the low-level language and how to construct shaders. In the last weeks before I finished writing, there's not one but three competing high-level shader languages. It's still very much up in the air as to what the standard language will look like, and there's considerable pressure building to make the language independent of the hardware—that is, there'll be a software fallback—so that any shader program will run on any modern hardware. We'll be free from "checking the caps bits" to see if we can use our favorite shader. But now's not the time to wait! No matter what language you learn to write shaders in, it's the experience and understanding from writing shaders that will carry over into any shading language of the future. So let's get started!
My first contact with Phil was when someone was (I thought) heckling me during an OpenGL course at the Computer Game Developers Conference. Even in those early days of the API wars, Phil was one of the few with hearty integrity.