At a very high level, data enters the graphics pipeline as per-vertex data, is processed by each of the three stages, and generates pixel colors. Briefly, each stage of the pipeline performs a series of steps:
Part 1 blends texture samples with per-pixel colors, completely replacing the fixed function multi-texture blender. This processing includes: iterating colors and texture coordinates, sampling textures, and blending texture samples with lighting and material colors.
Part 2 includes all the operations that determine what is written out to the frame buffer. This includes: alpha testing, depth testing, stencil testing, calculating per-pixel fog, alpha blending, dithering, and making gamma adjustments.
By making vertex processing and the first part of pixel processing programmable, the user can now dramatically extend the functionality of the pipeline by implementing custom functionality in each of these stages.
Programmable high-level shader language (HLSL) shaders use the HLSL compiler to generate asm shader code from HLSL source code.
To program this enormous variability, a shader language called HLSL was created to design these programmable shaders. Simply design and build shaders in HLSL and compile each shader into an Asm shader.
Here is an example of a vertex shader that implements the minimum vertex processing. This shader transforms vertex position from object space to projection space and assigns per-vertex color from the vertex input.
float4x4 mWorldViewProj; // World * View * Projection transformation struct VS_OUTPUT { float4 Position : POSITION; // vertex position float4 Diffuse : COLOR0; // vertex diffuse color }; VS_OUTPUT Vertex_Shader_Transform( in float4 vPosition : POSITION, in float4 vColor : COLOR0 ) { VS_OUTPUT Output; // Transform the vertex into projection space. Output.Position = mul( vPosition, mWorldViewProj ); // Output the diffuse color. Output.Diffuse = vColor; return Output; }
Here is an example of a simple pixel shader. This shader simply copies the interpolated per-vertex color data, and outputs a pixel color.
float4 Pixel_Shader( VS_OUTPUT in ) : COLOR0 { float4 color = in.Color; return color; }
These shaders looks very much like C code and contain one global variable, one data structure, and two functions. By browsing these shaders you can see that: