MSDN Documentation

Windows API Reference - DirectX Graphics

Pixel Shaders

Pixel shaders, also known as fragment shaders in OpenGL, are programs that run on the graphics processing unit (GPU) for each pixel (or fragment) that is generated by the rasterizer. Their primary responsibility is to determine the final color of each pixel, including operations like texturing, lighting, and other post-processing effects.

Role in the Graphics Pipeline

Pixel shaders are one of the programmable stages in the modern graphics pipeline. They typically receive interpolated data from the vertex shader (such as texture coordinates, vertex normals, and colors) and process it to output a final RGBA (Red, Green, Blue, Alpha) color value. This output can then be written to a render target (like a texture or the back buffer) after passing through various output merge tests (depth test, stencil test, and blending).

Simplified Graphics Pipeline Flow

(Conceptual Diagram - Actual flow can be more complex)

Graphics Pipeline Diagram

Key Functionalities

  • Texturing: Reading from texture maps to sample colors, normals, or other surface properties.
  • Lighting: Calculating per-pixel lighting effects based on light sources, surface normals, and material properties.
  • Color Interpolation: Using interpolated vertex colors or derived colors.
  • Fog and Atmospheric Effects: Simulating fog, haze, or other environmental effects.
  • Post-processing: Applying effects like bloom, depth of field, or color correction after the main scene is rendered.

Shader Languages

Pixel shaders are typically written in high-level shading languages such as:

  • High-Level Shading Language (HLSL): Microsoft's shading language for DirectX.
  • OpenGL Shading Language (GLSL): The shading language for OpenGL.
  • Metal Shading Language (MSL): Apple's shading language for Metal.

These high-level languages are compiled into intermediate shader code or directly into GPU-specific machine code.

Example HLSL Snippet

A basic pixel shader might look like this:


// Define input structure (matching vertex shader output)
struct PS_INPUT
{
    float4 Pos : SV_POSITION; // Screen-space position
    float4 Color : COLOR0;    // Interpolated vertex color
    float2 Tex : TEXCOORD0;   // Interpolated texture coordinate
};

// Define sampler and texture
Texture2D myTexture;
SamplerState mySampler;

// Main pixel shader function
float4 PSMain(PS_INPUT input) : SV_TARGET
{
    // Sample color from texture using interpolated UV coordinates
    float4 texColor = myTexture.Sample(mySampler, input.Tex);

    // Combine texture color with interpolated vertex color
    float4 finalColor = texColor * input.Color;

    return finalColor;
}
                

Shader Model Versions

Pixel shaders have evolved through various Shader Model versions (e.g., Shader Model 3.0, 4.0, 5.0, 6.0), each introducing new features, instructions, and capabilities. Understanding the target Shader Model is crucial for leveraging the full power of the GPU.