Shader
Introduction
A shader is a program that runs on the graphics hardware (GPU) rather than the CPU. There are two variations of shaders, Pixel shaders and Vertex shaders, each of which performs a different task in the rendering pipeline. Shaders form a replacement for the fixed function pipeline and allow developers greater control over rendering output by providing the ability to modify pixels and vertices dynamically.
There are currently three main shader languages, HLSL, CG and GLSL. The Source Engine uses HLSL based shaders, however CG is so similar that most CG shaders can be quickly and easily ported to HLSL.
For information on authoring shaders for use in the Source Engine, please see here.
Vertex Shaders
Vertex shaders are applied for each vertex run on a programmable pipeline. It's most basic goal is to transform geometry into screenspace coordinates so that the Pixel shader can rasterize an image. On a more complex scale, Vertex shaders are responsible for mesh deformation, lighting, shadowing and general vertex displacement. Vertex shaders cannot create vertices.
Pixel Shaders
Pixel shaders are applied for each pixel rendered to the screen. A pixel shader expects input from interpolated vertex values, which it then uses to rasterize the image.
Applications of Shaders in Source
The Source Engine provides for two seperate forms of shaders, Postprocess and Per-Object, the majority of the effects and materials used within the Source Engine rely heavily on their Pixel shader components.
Postprocess
A Postprocess shader is typically a Pixel shader that works on a quad rendered across the entire screen. The quad is textured with a copy of the frame buffer, the Pixel shader can than alter and modify the rendered output to create a variety of effects, such as basic colour modification to more advanced processes such as motion blur and bloom.
The Source SDK provides an example of this form of shader in the sdk_postprocess files (sdk_postprocess.cpp
, sdk_postprocess_vs20.fxc
, and sdk_postprocess_ps20.fxc
)
Per-Object
A Per-Object shader in the Source Engine is used on any object with the shader referenced in the relevant VMT file, such as a model or piece of brushwork. A Per-Object shader could be used to create a refractive material, modify a models vertices dynamically or other advanced rendering effects.
The Source SDK provides an example of a Per-Object shader in the sdk_lightmap files ( sdk_lightmap.cpp
, sdk_lightmap_vs20.fxc
, and sdk_lightmap_ps20.fxc
)