Keywords: UE4, Shader Development, Material Optimization

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.
  1. 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.
  1. Add RenderCore, Renderer in your .Build.cs. Maybe RHI is also need to be added.

     PublicDependencyModuleNames.AddRange(new string[] { "RenderCore", "Renderer", "RHI" });
  2. 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);
             BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
                 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)
  3. 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);


Official Documents

Shader Development

Adding Global Shaders to Unreal Engine

Shaders In Plugins


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

Material Optimization

Understanding Shader Permutations

Material Optimization

How the Unreal Engine Translates a Material Graph to HLSL

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