Shader (realtime, logical)

A shader is essentially a computer program executed on special environment<ref name="exeEnviron>ARB_vertex_program clarifies the meaning of execution environment on issue (2) as "A set of resources, instructions, and semantic rules used to execute a program".

. This article specifically covers realtime shaders which are shaders meant to execute on consumer GPUs. Although shaders were introduced for graphics related tasks which still hold a major part of their applications, shaders can also be used for more generic computation, just as generic programs can be used to compute arbitrary data. As the computational power of GPUs continue to raise faster than conventional CPUs, the interest in shader programming catalizes more and more attention. This actually requires to rethink algorithms or problems to fit the stream processing paradigm.
The goal of this article is to provide a look at the most important concepts concerning shaders in most important APIs such as OpenGL and Direct3D. The reader is assumed to be ProFicient with 3D graphics, a graphics API and fourth generation shading pipelines.
Shaders alone control a large part of the working of a programmable graphics pipeline and thus the final appearance of an object. However, they are not the only entities involved in defining an accurate behaviour. The resources being used, as well as settings of other pipeline stages, still has a great influence upon the final result.

Generic shader

A generic shader replaces a specific stage of the shading pipeline with an user-defined program to be executed on need - thereafter, kernel. Shaders GeneRally run in parallel with limited inter-communication between different executions - thereafter instances - usually limited to simplified first-derivative computation and cache optimizations. Being simply a sequence of operations, kernels are defined using special programming languages tailored to match the needs for explicit parallelization and efficiency. Various shading languages have been designed for this purpose.

Depending on the stage being replaced, a shader fetches specific data while its output is handed to successive stages. Input data is typically read-only and can be categorized in two main types:

  • uniform input does hold constant between different kernel instances of the same draw call. The application can set these uniform values with ease between different draw calls, but there is no way to change a uniform value on a per-instance basis. Uniform values can be loaded by calling specific API functions.
    • samplers are special uniforms meant to be used to access TEXtures. Typically, sampler identifiers themselves specify a texture sampling unit in the pipeline (to be used for texture-lookups operations) which is then bound to a texture. Samplers are usually employed by kernels similarly to objects. The intended Usage model presents some differences depending on the shading language being used.
  • varying input is typically the result of a previous computational stage, sometimes bound to some special, context-dependant semantics. For example, vertex positions are typical varying inputs for vertex shaders (named attributes in this context), pixel texture coordinates are typical varying inputs to pixel shaders.

The output is ideologically always varying (although two instances may actually output the same value). Fourth generation shading pipelines allow to control how output interpolation is performed<ref name="interpolationModes>Cool OpenGL tips (Khronos Group presentation at GDC 2007) is likely the easiest document to read on interpolation methods for OpenGL. Comes with a few screenshots. MSDN features a D3D10 specific page.

when primitives are rasterized and pixel shader's varying input is generated.

Vertex shader

A vertex shader replaces part of the geometry stage of a graphics pipeline. Vertex shaders consume vertices filled by the Input Assembly stage by applying the specified kernel "for each vertex". The result, which usually include an affine transform, is then fetched by the next state - the Primitive Assembly stage. A vertex shader always produces a single transformed "vertex" and runs on a vertex processor.

Producing vertex position for further rasterization is the typical task of the vertex shader.

Note the current meaning of "vertex" may or may not match the intuitive idea of a vertex. In general, it is better to think at a "vertex" as the basic input data set. This is especially important for generic processing, in which a vertex may hold attribute which does not map to any "geometrical" meaning.

Although vertex shaders were the first hardware accelerated shader type with a high degree of flexibility (see GeForce3, Radeon R200), their feature set was considerably different from other stages for a long time. Even if the exposed instruction set can be considered unified, the performance characteristics of vertex processing units can be considerably different from other execution units. Historically, branching has been considerably more efficient and flexible on vertex processors. Similarly, dynamic array indexing was possible only on vertex processors up to fourth generation pipelines.

Geometry shader

Geometry shaders replace a part of the geometry stage subsequent to Primitive Assembly stage and prior to Rasterization. Differently from other shader types, which replaced well-known tasks, the notion of a geometry shader have been only recently introduced to realtime systems so they currently don't map to anything possible before. Additionally, the problem being solved is conceptually very different so a generic geometry shader will be considerably different from a typical shader (both vertex and fragment).

Pixel shader

Pixel shaders consume interpolated fragment data mapping it to pixel's colors. Many architectures nowadays allow to write multiple colors for each output pixel, a feature known as Multiple Render Targets (MRT).

Pixel shaders determine (or Contribute to the determination of) the color of a pixel. Typically these calculations are performed in the RGB (Red Green Blue) color-space used in motion pictures and video, but shaders can also use the CMYK (Cyan Magenta Yellow Black) color-space of printed media.