Been re-learning some 3D Graphics work, reading through ‘Real-Time 3D Rendering with DirectX and HLSL’ by Paul Varcholik.
The Graphics pipeline is the process of taking points in 3D coordinate space and projecting them onto a 2D screen. The pipeline is simply a list of steps, starting with the Input-Assembler stage.
This is where you collate all your 3D data, vertices and indices, and the IA assembles the data into primitives. Primitives could be points, lines but most commonly triangles. Vertices and indices are provided to the IA through a vertex buffer and index buffer respectively. Vertices can contain more than just positional data (things like colours and normals) but this extra data must be presented to Direct3D in the form of an input layout.
The VS processes the primitives provided by the IA on a per-vertex basis. VS is a small program generally used to transform vertices, most commonly out of their own object space into camera space using the World-View-Projection matrix, but this is a programmable aspect of the pipeline that can be used for many things.
Tessellation is a more recently added process that can dynamically add detail to objects directly on the GPU. In the past, LODs (levels of detail) were provided by an artist and essentially different models would be rendered based on distance from the camera. Tessellation allows this task to be done on the GPU without the cost of providing additional vertices to the IA. Tessellation has two programmable stages (the Hull Shader and the Domain Shader) either side of the Tessellator stage. Tessellation is entirely optional, though.
The GS operates on primitives rather than vertices and it can also add or remove geometry from the pipeline. A good example of using the GS would be a particle effects system, where each primitive is a single vertex. Each primitive could then create a quad around itself to map a texture to and thus you have point sprite particles. The GS then feeds into the stream-output stage, which stores the output from the GS in memory. At this point, this data can be read back into the pipeline at the start for another pass or it can be read CPU-side. Like Tessellation, the GS stage is optional.
The Rasterizer stage ‘converts’ the primitives into a raster image/bitmap. Image is represented as 2D array of pixels/colours that make up an area on a computer screen. It determines which pixels should be rendered (using clipping, whereby pixels off-screen won’t be rendered) and also, before sending data to the pixel shader, it computes interpolated values of vertex data. e.g. if the vertex data contains a colour and 2 vertices in a primitive have different colours, pixels between those two vertices will contain colours interpolated between the two vertex colours. So if one vertex colour was RGB(255,0,0) and another was RGB(0,255,0), the mid-point pixel colour would be something like RGB(128,128,0).
The PS is another programmable shader which runs over each pixel provided from the rasterizer. This then tends to output a colour for each pixel on the screen. Thanks to the interpolated values provided from the Rasterizer, this can provide the exact colour and texture data needed to create the expected output. You can then use something like global variables to provide something a bit different to the output. For example, if you wanted to provide the output with just the red colours in your regular output, you could multiply it with a value representing RGB(255,0,0).
The OM stage produces the final rendered pixel. Though this stage isn’t programmable the way shaders are, you can control how it behaves through customizable pipeline states. The final pixel is generated through a combination of these states, the output from the pixel shader and the existing contents of the render target (what is already on screen at this stage). For example, this could use something like colour blending to implement transparent objects.
The OM stage also determines which pixels are visible through depth testing and stencil testing. Depth testing is the means of only drawing pixels closest to you. In other words, if there is a wall between the camera and an object completely covering the object, the object’s pixels will not be drawn, only the wall’s. Stencil testing is very similar, whereby only pixels within a given range will update, quite like how you can only draw in the area inside of a physical stencil.