FMaterialShaderType are pass specific shaders which need access to some of the material's attributes, and therefore must be compiled for each material, but do not need to access any mesh attributes. The light function pass shaders are an example of
FMeshMaterialShaderType are pass specific shaders which depend on the material's attributes AND the mesh type, and therefore must be compiled for each material/vertex factory combination. For example,
TBasePassPS need to evaluate all of the material inputs in a forward rendering pass.
A material's set of required shaders is contained in a
FMaterialShaderMap. It looks like this:
FLightFunctionPixelShader - FMaterialShaderType
FLocalVertexFactory - FVertexFactoryType
TDepthOnlyPS - FMeshMaterialShaderType
TDepthOnlyVS - FMeshMaterialShaderType
TBasePassPS - FMeshMaterialShaderType
TBasePassVS - FMeshMaterialShaderType
FGPUSkinVertexFactory - FVertexFactoryType
Vertex factories are included in this matrix based on their ShouldCache function, which depends on the material's usage. For example, bUsedWithSkeletalMesh being
true will include the GPU skin vertex factories.
FMeshMaterialShaderType's are included in this matrix based on their ShouldCache function, which depends on material and vertex factory attributes. This is a sparse matrix approach to caching shaders and it adds up to a large number of shaders pretty quick which takes up memory and increases compile times. The major advantage over storing a list of actually needed shaders is that no list has to be generated, so needed shaders have always already been compiled before run time on consoles. UE4 mitigates the shader memory problem with shader compression, and the compile time problem with multicore shader compilation.