Keywords: UE4, Shader Development, Material Optimization

Common Case

Environment Setup

1, Set LoadingPhase as PostConfigInit, default is Default.
e.g. TestProj.uproject:

    "FileVersion": 3,
    "EngineAssociation": "4.25",
    "Category": "",
    "Description": "",
    "Modules": [
            "Name": "TestProj",
            "Type": "Runtime",
            "LoadingPhase": "PostConfigInit"

Otherwise there’s error on building:

Shader type was loaded after engine init, use ELoadingPhase::PostConfigInit on your module to cause it to load earlier.

2, Turn on r.ShaderDevelopmentMode in \Engine\Config\ConsoleVariables.ini.

; Uncomment to get detailed logs on shader compiles and the opportunity to retry on errors

Otherwise there’s error on building:

Failed to compile global shader XXXX. Enable `r.ShaderDevelopmentMode` in ConsoleVariables.ini for retries.

3, Add RenderCore, Renderer in your .Build.cs. Maybe RHI is also need to be added.

PublicDependencyModuleNames.AddRange(new string[] { "RenderCore", "Renderer", "RHI" });

4, Now you can setup your shader source in your game source, and these shader would be compiled on editor starting.
MyActor.cpp (quoted from Engine\Source\Runtime\Renderer\Private\PostProcess\PostProcessVisualizeBuffer.cpp):

    class FVisualizeBufferPS : public FGlobalShader
        SHADER_USE_PARAMETER_STRUCT(FVisualizeBufferPS, FGlobalShader);

            SHADER_PARAMETER_STRUCT(FScreenPassTextureViewportParameters, Output)
            SHADER_PARAMETER_RDG_TEXTURE(Texture2D, InputTexture)
            SHADER_PARAMETER_SAMPLER(SamplerState, InputSampler)
            SHADER_PARAMETER(FLinearColor, SelectionColor)

        static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
            return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::ES3_1);

    IMPLEMENT_GLOBAL_SHADER(FVisualizeBufferPS, "/Engine/Private/PostProcessVisualizeBuffer.usf", "MainPS", SF_Pixel);

    FScreenPassTexture AddVisualizeBufferPass(FRDGBuilder& GraphBuilder, const FViewInfo& View, const FVisualizeBufferInputs& Inputs)
        FVisualizeBufferPS::FParameters* PassParameters = GraphBuilder.AllocParameters<FVisualizeBufferPS::FParameters>();
        PassParameters->Output = GetScreenPassTextureViewportParameters(OutputViewport);
        PassParameters->RenderTargets[0] = Output.GetRenderTargetBinding();
        PassParameters->InputTexture = Tile.Input.Texture;
        PassParameters->InputSampler = BilinearClampSampler;
        PassParameters->SelectionColor = SelectionColor;
        TShaderMapRef<FVisualizeBufferPS> PixelShader(View.ShaderMap);
    void Test_RenderThread(FRHICommandListImmediate& RHICmdList)
        TShaderMapRef<FDownsamplePS> PixelShader(ShaderMap, PermutationVector);

    [](FRHICommandListImmediate& RHICmdList)

5, If want to specify the Shader Type (Global, Material, MeshMaterial, Niagara etc.), use IMPLEMENT_SHADER_TYPE instead of IMPLEMENT_GLOBAL_SHADER, see the example of PostProcessMaterial.cpp in engine.
quoted from Engine\Source\Runtime\Renderer\Private\PostProcess\PostProcessMaterial.cpp:

IMPLEMENT_SHADER_TYPE(,FPostProcessMaterialVS, TEXT("/Engine/Private/PostProcessMaterialShaders.usf"), TEXT("MainVS"), SF_Vertex);
IMPLEMENT_SHADER_TYPE(,FPostProcessMaterialPS, TEXT("/Engine/Private/PostProcessMaterialShaders.usf"), TEXT("MainPS"), SF_Pixel);
How to dump shader statistics of all materials

UE5 solution:

"D:/UE_5.2/Engine/Binaries/Win64/UnrealEditor-Cmd.exe" "D:/TestProj/TestProj.uproject" -run=DumpMaterialShaderTypes  -targetplatform=Windows

Then results output to [MyProj]/Saved/MaterialStats/.txt.

DumpMaterialShaderTypes only works for UE5.

UE4 solution:
Turn on follows switch in Engine\Config\ConsoleVariables.ini and restart editor (if want to build package from editor):


Then execute cook command:

D:/UE4/Engine/Binaries/Win64/UE4Editor-Cmd.exe D:/TestTP/TestTP.uproject -run=Cook -TargetPlatform=WindowsNoEditor -fileopenlog -ddc=DerivedDataBackendGraph -unversioned -abslog=D:/UE4/Engine/Programs/AutomationTool/Saved/Cook-2023.06.09-17.05.16.txt -stdout -CrashForUAT -unattended -NoLogTimes -UTF8Output

This cook command also will be executed automatically while building Development package.

Then statistics data output to directory: [MyProj]/Saved/MaterialStats/*.csv.
UE4’s cook command only output sum of shader count, UE5’s command output shader count and shader type.


Official Documents

Shader Development
Adding Global Shaders to Unreal Engine
Shaders In Plugins

Render Dependency Graph. An immediate-mode API which records render commands into a graph data structure to be compiled and executed.


Extend the UE4 Shading Model

Unreal Engine 4 Rendering Part 1: Introduction
Unreal Engine 4 Rendering Part 2: Shaders and Vertex Data
Unreal Engine 4 Rendering Part 3: Drawing Policies
Unreal Engine 4 Rendering Part 4: The Deferred Shading Pipeline
Unreal Engine 4 Rendering Part 5: Shader Permutations
Unreal Engine 4 Rendering Part 6: Adding a new Shading Model

剖析虚幻渲染体系(08)- Shader体系

Add custom render pass in UE5 (Recommended)

Material Optimization

Material Optimization

How the Unreal Engine Translates a Material Graph to HLSL

Shader Permutation

Understanding Shader Permutations

The Shader Permutation Problem - Part 1: How Did We Get Here?
The Shader Permutation Problem - Part 2: How Do We Fix It?

Vertex Shader

Rotating meshes using Vertex Shaders

The “Normal”-pin runs on the pixel-shader while the “World Position Offset”-pin runs on the vertex shader.

Customized UVs: Feature that allows running calculations in the vertex shader to increase performance over running them per-pixel.


Compiling Shaders Manually


Unreal Official Shaders

A tutorial project that shows how to implement HLSL Pixel and Compute shaders in UE4

A compute shader plugin that is capable of sorting positional data in parallel directly on the GPU.

The minimal source code for adding and using a custom compute shader in Unreal Engine 4

Business has only two functions — marketing and innovation. ― Peter Drucker