Material System
Tags |
---|
Composition
The shader programs are compiled as a single unit, but there are multiple functionality that needs to be combined together.
Vertex transformation, vertex blending, morphing, tessellation, instancing, and other operations are distinct from surface shading but they need to be executed together when drawing meshes.
A material system is responsible for composing surface shading with geometry processing.
The compositing of multiple functionality can be done at compile-time and at run-time.
Some functionality can be selected at run-time using dynamic branching.
However, when using large shaders with branches that are rarely taken, the lower register occupancy reduce performance.
Another solution is to perform the composition at the source code level by building shader variants.
Multiple shader variants are generated using preprocessor directives (symbols and conditionals).
However, it can produce a large number of shader variants.
A modern material system will use both strategies depending on the functionalities.
Modularity and composability of shader source code is critical.
There are different strategies to write modular shader code.
- Shared sources – Using the preprocessor
#include
directive, some functionality can be reused across multiple shaders.
- Ubershader – A large set of functionality is implemented in a single shader, and disabled using static or dynamic branching.
- Composition – Pieces of source code are plugged together either using text or a visual node graph.
- Templates – An interface is defines, and multiple implementations can be used.
Optimizations
Frequency
Uniform parameters should be grouped by the frequency of their update.
Application
Computations that are constant over the lifetime of the application can be computed on the GPU once and passed as uniform parameters.
For example, the start time.
Per Frame
The view and projection matrices can be calculated and passed as a combined transformation.
Per Model
The lighting parameters are constant for a specific location.
Per Draw Call
The material parameters are specific to each draw call.
A material system can detect the computations that are constant within a draw call, and move them outside of the shader.
Within a Draw Call
Fragment shaders are evaluated more often than vertex shaders.
Some computations can be computed in earlier shader stages, and passed down to other stages as varying data to reduce the number of computations in more expensive shader stages.
- Vertex shaders - Evaluated once per vertex.
- Tessellation control shaders - Evaluated once per patch.
- Tessellation evaluation shaders - Evaluated once per post-tessellation vertex.
- Geometry shaders - Evaluated once per primitive.
- Fragment shaders (or pixel shaders) - Evaluated once per fragment.