AMD Logo AMD Developer Central

Illuminating Shaders: Getting Started Developing Pixel Shaders for Lighting 

Skip Navigation LinksHome > Docs & Articles > Articles & Whitepapers
The biggest change in the world of gaming is the rise of the programmable graphics pipeline.
Larry O'Brien  3/22/2007 

While browser-based games may continue to rely solely on the CPU for calculating shape and color, standalone games, whether professionally produced or the work of amateurs using tools such as Microsoft's XNA Game Studio Express, absolutely require the understanding and development of shaders. Showcase games may have more than 1,000 shaders, but even the simplest arcade-style game requires a handful if it is to have any sparkle.

With the advent of Microsoft's free XNA Game Studio Express and the widespread adoption of high-powered GPUs, such as those in AMD's ATI product line, game development has become approachable by any enthusiast. Shader programming is required for even simple games, but AMD's RenderMonkey environment makes these tasks easy. This article will discuss shader basics and the development of some minimal pixel shaders for lighting, and a follow-up will go into vertex shaders. As GPUs have increased in capability, shader writing has evolved from an assembly-language task to a higher-level one. With the increase in the number of shaders used in a given project, a language such as the C-like High-Level Shader Language (HLSL) for DirectX or its OpenGL counterpart GLSL becomes almost mandatory in order to accommodate workflow and schedules.

The ideal tool for developing shaders is AMD's ATI RenderMonkey (the latest version, 1.62, is available for free download at http://ati.amd.com/developer/rendermonkey/index.html). As you can see in Figure 1, RenderMonkey is a complete development environment for shaders. The Workspace panel along the left-hand side of the screen allows you to interactively manipulate the shader parameters that will ultimately be passed in from the game, effectively decoupling the development of shaders from game source (at least initially). In this case, for a pixel shader that Phong-lights a textured surface, we need such things as the position vectors for the light and the eye, the View and ViewProjection matrices, and the texture and model to use.

The Shader Editor is the main workspace and shows just how simple HLSL can be, with intrinsic functions for common linear algebra functions. In addition to functions such as normalize() and dot(), notice the use of operator overloading to make vector and matrix multiplication simple (these operations are actually available at the assembly-language level, which goes to show how different GPU capabilities are!). Aside from the texture-mapping assignment in tex2D(), this function is essentially straight out of a textbook on Phong shading. Notice also that the ASM-level instruction count of the shader is shown in the status bar of the Shader Editor - this is very handy, since instruction counts can be very low in GPUs that are only a few years old.

While RenderMonkey is a great development environment, programming a 3D game has always been difficult. The release of Microsoft's XNA Framework has shattered that barrier, allowing enthusiasts to easily create games that are limited only by their imagination and their hardware. Further, the combination of RenderMonkey and XNA Game Studio Express provides a complete "free beer" tool chain, opening the door to the development not just of games but of graphically intense "demos" and visualizations of such things as physics, fluid dynamics, fractals, and AI.

Listing 1 shows a Microsoft .FX file, including the world's simplest vertex and pixel shaders: Every pixel is set to be the same color of red (Line 54). The vertex shader requires a single parameter passed in from the application: matViewProjection. Listing 2 shows the world's simplest XNA demo, which shows a cube sitting in space, rendered with the "red" pixel shader. The InitializeCamera() function (lines 39-54) is boiler-plate: the view Matrix is set as the cameraPos when it is pointed at the origin (Vector3.Zero) and oriented normally (Vector3.Up). The projection matrix combines the field of view, aspect ratio, and near and far clip planes. These matrices are multiplied to create the viewProjection matrix, which defines the "view frustrum" we will be rendering.

The LoadGraphicsContent() function (lines 70-88) loads the cube model and then the "red" Effect. An Effect contains a collection set of Passes, each of which contains vertex and pixel shaders. In this case, we have a single pass that contains our simple "red" shader. Line 77 shows how we set the shader variable matViewProjection to the value of the game variable viewProjection:

effect.Parameters["matViewProjection"].SetValue(viewProjection);

The effect is then Cloned to all the parts of the model. When the game runs, the Draw() function (lines 128-161) steps over all the meshes in the model, the Effects in the mesh, the Passes in the Effect, and the ModelMeshParts in the Mesh and, well, draws them. The output is essentially a cube-shaped red stencil.

The power of shaders begins to be apparent in Listing 3, a pixel shader that implements unlit texture-mapping. As you can see, a new parameter base_Tex is required. Listing 4 shows the only code changes needed in the source code: the loading of a Texture and the passing in of that to the effect. The output changes dramatically - it's not "Gears of War" but it does show how RenderMonkey can decouple the development of shaders from the development of game code and how shaders are the core of modern rendering.

Finally, to bring us full circle, Listing 5 shows the (again, trivial) code changes required to support the textured Phong shader shown in Figure 1. Of course, in a real application, you don't use instance variables of the Game object to store and associate matrices, models, effects, textures, and parameters, but rather you use structs and objects to encapsulate them and update them over time. The ease with which RenderMonkey-created HLSL shaders and variables can be loaded and manipulated in source code, though, is the key to a high productivity workflow. You can download the source for these demos at http://developer.amd.com/assets/152-demos.zip.

There are many ubiquitous pixel shaders: Phong and Blinn-Phong lighting, bump mapping, reflections, and so forth. There are also many less-used algorithms that may or may not be implementable as high-framerate shaders. You can find these algorithms in graphics texts, popular sources such as Game Developer Magazine and the Gamasutra Website, and discussion forums. However, you'll generally find that source-code recipes need some amount of tweaking to fit your games' matrices and naming styles. RenderMonkey is the ideal environment for working through these kinds of tweaks, since changes can be made and tested so rapidly.

In my next article, I'll discuss the use of RenderMonkey to develop vertex shaders to really give your application that pro-game glow.

Larry O'Brien founded Game Developer magazine, worked in the game industry developing middleware for MMORPGs and as a performance consultant, and has taught game programming at the Computer Game Developer's Conference and Berkeley University Extension. He now lives in Hawai'i and blogs at http://www.knowing.net/

Back to top
© 2009 Advanced Micro Devices, Inc. AMD, the AMD Arrow logo, AMD Opteron, AMD Athlon, AMD Turion, AMD Sempron, AMD LIVE!, and combinations thereof, are trademarks of Advanced Micro Devices, Inc. Microsoft and Windows are registered trademarks of Microsoft Corporation in the United States and/or other jurisdictions. Linux is a registered trademark of Linus Torvalds. Other names are for informational purposes only and may be trademarks of their respective owners.

This website may be linked to other websites which are not in the control of and are not maintained by AMD. AMD is not responsible for the content of those sites. AMD provides these links to you only as a convenience, and the inclusion of any link to such sites does not imply endorsement by AMD of those sites. AMD reserves the right to terminate any link or linking program at any time.