Bare-bones material graph evaluation via Compute Shader in UE5
This template provides an example of linking a custom compute shader to any material defined in the editor. Allowing you to input/output parameters from material graphs defined by developers or artists.
Get the code
Applications
- Drive indirect instancing from a texture sampled in a material graph.
- Sample and find the average color of a material on the GPU.
- Generate & derive height-maps/normals using user-defined graphs.
This workflow opens up a world of possibilities and is one of the coolest features of the Unreal shader pipeline.
Usage
- Generate or download the template using the instructions above
- Rebuild your project
- Create or navigate to an existing Blueprint
- Right-click and add the node called “Execute Base Material Compute Shader”
Helpful reading
Sample snippet
// basemat.usf
#include "/Engine/Generated/Material.ush"
#include "/Engine/Public/Platform.ush"
float2 Position;
RWBuffer<float4> OutputColor;
[numthreads(THREADS_X, THREADS_Y, THREADS_Z)]
void BaseMatExample(
uint3 DispatchThreadId : SV_DispatchThreadID,
uint GroupIndex : SV_GroupIndex )
{
float4 SvPosition = float4(Position.xy, 0, 0);
FMaterialPixelParameters MaterialParameters = MakeInitializedMaterialPixelParameters();
// There are various inputs we can provide to the material graph via FMaterialPixelParameters
// See: https://github.com/EpicGames/UnrealEngine/blob/5.0/Engine/Shaders/Private/MaterialTemplate.ush#L262
MaterialParameters.VertexColor = half4(1, 1, 0, 1);
FPixelMaterialInputs PixelMaterialInputs = (FPixelMaterialInputs)0;
// This is the call to the material graph
CalcMaterialParameters(MaterialParameters, PixelMaterialInputs, SvPosition, true);
// PixelMaterialInputs is a struct that contains the outputs of the material graph
// Use the provided helper methods ( GetMaterialXYZ(...) ) to access the outputs
// See: https://github.com/EpicGames/UnrealEngine/blob/5.0/Engine/Shaders/Private/MaterialTemplate.ush#L2485
OutputColor[0] = float4(GetMaterialBaseColor(PixelMaterialInputs), 0);
// You can also access custom output nodes via their respective names
// e.g. GetMyCustomMaterialOutput0(MaterialParameters)
// See: Custom node example
}