ue-materials-rendering
Use when the user is working with material, shader, MID, dynamic material, material instance, post-process, render target, parameter collection, decal, Nanite, Lumen, or rendering in Unreal Engine. See references/material-parameter-reference.md for parameter patterns and references/post-process-sett
By quodsoler · 861 installs
npx skills add quodsoler/unreal-engine-skills --skill ue-materials-rendering
Source repository · Upstream listing
UE Materials and Rendering
Target engine: UE 5.8 . APIs below are verified against the 5.8 headers; older forms are listed under "Deprecated — do not use".
Runtime material and rendering C++: UMaterialInstanceDynamic , UMaterialParameterCollection , UTextureRenderTarget2D , USceneCaptureComponent2D , FPostProcessSettings , UDecalComponent , plus the 5.8 renderer features (Nanite, Lumen, MegaLights, Substrate, Virtual Shadow Maps, TSR). Material headers live in Runtime/Engine/Public/Materials ; render targets, scene, post process volumes in Runtime/Engine/Classes/Engine ; Blueprint libraries in Runtime/Engine/Classes/Kismet . Build.cs: "Engine" covers everything above; add "RenderCore" and "RHI" only for EShaderPlatform , RDG and global shaders.
Context
Read .agents/ue project context.md if it exists (module names, conventions, enabled plugins, renderer settings). Do not stop if it is missing.
Identify the area from the request and the codebase. Ask only when two plausible readings would produce different code.
Request is about… Go to
Changing material parameters at runtime on a mesh [Dynamic Material Instances]( dynamic material instances)
One value driving many materials (weather, time of day) [Material Parameter Collections]( material parameter collections)
Minimap, mirror, security camera, runtime texture painting [Render Targets]( render targets) / [Scene Capture]( scene capture)
Bloom, exposure, DOF, color grading, Lumen quality knobs [Post Process]( post process)
Full screen effect authored as a material [Post Process Materials]( post process materials)
Bullet holes, blood, projected textures [Decals]( decals)
Nanite mesh/material compatibility, WPO, Nanite override material [Nanite]( nanite)
GI, reflections, many shadowed lights [Lumen and MegaLights]( lumen and megalights)
Layered/multi BSDF material system [Substrate]( substrate)
Outlines, X ray, stencil masks, shadow/AA settings [Shadows, Anti Aliasing and Custom Depth]( shadows anti aliasing and custom depth)
An API wants EShaderPlatform but you have a feature level [Feature Level and Shader Platform]( feature level and shader platform)
Writing an actual HLSL shader pass from C++ [Global Shaders and Render Graph]( global shaders and render graph)
Full signature tables live in [material parameter reference.md](references/material parameter reference.md); the FPostProcessSettings field tables live in [post process settings.md](references/post process settings.md); global shader and RDG code lives in [global shaders rdg.md](references/global shaders rdg.md).
Dynamic Material Instances
A MID is a per instance parameter override on top of a parent material. Three ways to make one:
Need Call
Standalone MID not bound to a slot UMaterialInstanceDynamic::Create(Parent, Outer, Name)
MID assigned to a component's material slot UPrimitiveComponent::CreateDynamicMaterialInstance(ElementIndex, SourceMaterial, OptionalName)
MID from Blueprint facing library code UKismetMaterialLibrary::CreateDynamicMaterialInstance(WorldContextObject, Parent, OptionalName, CreationFlags)
Verbatim signatures:
Create once, cache in a UPROPERTY , update in Tick or on an event:
When dozens of parameters change per frame, swap the name lookup for the index API — InitializeScalarParameterAndGetIndex once, then SetScalarParameterByIndex per frame. Signatures and the vector equivalents are in [material parameter reference.md](references/material parameter reference.md).
Setters ( MaterialInstanceDynamic.h ) — names are case sensitive FName s that must match the material's parameter exactly:
All but the double vector and sparse volume setters have a ByInfo twin — for example SetScalarParameterValueByInfo(const FMaterialParameterInfo& ParameterInfo, float Value) — which is how you reach parameters inside a material layer or function.
Reading values back: K2 GetScalarParameterValue(FName) , K2 GetVectorParameterValue(FName) , K2 GetTextureParameterValue(FName) return the value directly. The typed form on UMaterialInterface is bool GetScalarParameterValue(const FHashedMaterialParameterInfo& ParameterInfo, float& OutValue, bool bOveriddenOnly = false) const — it takes a parameter info , not a bare name.
Copying between instances: CopyParameterOverrides (overridden parameters only), CopyInterpParameters (the source's own scalar, vector, texture and font overrides, no hierarchy walk), CopyMaterialUniformParameters (uniforms, skips static parameters), K2 CopyMaterialInstanceParameters (all non static parameters), CopyScalarAndVectorParameters(const UMaterialInterface&, EShaderPlatform) and K2 InterpolateMaterialInstanceParams(SourceA, SourceB, Alpha) . ClearParameterValues() drops all overrides. Full signatures in [material parameter reference.md](references/material parameter reference.md).
Static parameters (static switch, static bool, static component mask) cannot change on a MID. Author a UMaterialInstanceConstant per permutation in the editor and put the MID on top of it.
Material Parameter Collections
UMaterialParameterCollection is an asset of ScalarParameters / VectorParameters arrays; every material referencing it reads from one uniform buffer per world. Get the per world instance from UWorld :
Both setters return false when the name is not in the collection. Getters are bool GetScalarParameterValue(FName ParameterName, float& OutParameterValue) const and the vector equivalent. ForceReturnToDefaultValues() resets the instance.
The Blueprint facing library does the world lookup for you ( Kismet/KismetMaterialLibrary.h ):
Collections hold no texture parameters. Use a collection for one value read by many materials; use a MID for per actor state.
Render Targets
UKismetRenderingLibrary ( Kismet/KismetRenderingLibrary.h ) owns the runtime render target workflow:
ETextureRenderTargetFormat ( Engine/TextureRenderTarget2D.h ): RTF R8 , RTF RG8 , RTF RGBA8 , RTF RGBA8 SRGB , RTF R16f , RTF RG16f , RTF RGBA16f , RTF R32f , RTF RG32f , RTF RGBA32f , RTF RGB10A2 . Pick the smallest that holds the data — RTF RGBA8 for LDR/UI, RTF RGBA16f for HDR, RTF R16f for a single channel.
Manual creation when you need an exact pixel format:
Canvas drawing batches many draws into one render target transition:
UCanvasRenderTarget2D ( Engine/CanvasRenderTarget2D.h ) wraps that loop: create with CreateCanvasRenderTarget2D(WorldContextObject, CanvasRenderTarget2DClass, Width, Height) , bind OnCanvasRenderTargetUpdate , and call UpdateResource() when the contents must be redrawn.
ReadRenderTargetPixel and friends stall the GPU. Use them in editor tooling or one off captures, never per frame; for a streaming readback use FRHIGPUTextureReadback .
Scene Capture
USceneCaptureComponent2D renders the world into a UTextureRenderTarget2D . Its own fields: TextureTarget , FOVAngle , PostProcessSettings , PostProcessBlendWeight , bMainViewResolution , CaptureScene() , CaptureSceneDeferred() . Inherited from USceneCaptureComponent : CaptureSource , bCaptureEveryFrame , bCaptureOnMovement , PrimitiveRenderMode , ShowOnlyActors , HiddenActors , ShowFlags , ShowOnlyComponent() , ShowOnlyActorComponents() .
ESceneCaptureSource ( Engine/EngineTypes.h ): SCS SceneColorHDR , SCS SceneColorHDRNoAlpha , SCS FinalColorLDR , SCS SceneColorSceneDepth , SCS SceneDepth , SCS DeviceDepth , SCS Normal , SCS BaseColor , SCS FinalColorHDR , SCS FinalToneCurveHDR . SCS Normal and SCS BaseColor are deferred renderer only.
With bCaptureEveryFrame = false and bCaptureOnMovement = false , call SceneCapture CaptureScene() when the view actually needs refreshing — a scene capture is a full extra scene render.
Post Process
FPostProcessSettings ( Engine/Scene.h ) is carried by APostProcessVolume::Settings , UPostProcessComponent::Settings , UCameraComponent::PostProcessSettings and USceneCaptureComponent2D::PostProcessSettings . Every value field has a paired bOverride <Field bit; the value is ignored unless the override bit is true .
APostProcessVolume and UPostProcessComponent both expose Settings , Priority , BlendRadius , BlendWeight , bEnabled , bUnbound and AddOrUpdateBlendable(TScriptInterface<IBlendableInterface InBlendableObject, float InWeight = 1.0f) . Higher Priority wins where volumes overlap; bUnbound makes a volume apply everywhere.
Per camera post process: UCameraComponent::PostProcessSettings with PostProcessBlendWeight , plus AddOrUpdateBlendable / RemoveBlendable . ( AddExtraPostProcessBlend only stores settings — only the editor viewport reads them back, Camera/CameraComponent.h:323 .) From a camera modifier or camera manager, push a transient blend with APlayerCameraManager::AddCachedPPBlend(FPostProcessSettings& PPSettings, float BlendWeight, EViewTargetBlendOrder BlendOrder = VTBlendOrder Base) ; read them back with GetCachedPostProcessBlends . The cache is cleared every frame at the start of ApplyCameraModifiers ( PlayerCameraManager.cpp:289 ), so re add the blend each frame; ClearCachedPPBlends and the PostProcessBlendCache array are both protected ( Camera/PlayerCameraManager.h:371,391 ).
Field by field tables (bloom, exposure, DOF, color grading, film grain, AO, Lumen, SSR, motion blur, lens) are in [post process settings.md](references/post process settings.md).
Post Process Materials
A post process material is a UMaterial whose MaterialDomain is MD PostProcess ( MaterialDomain.h ). Relevant UMaterial fields: BlendableLocation , BlendablePriority , bIsBlendable , UserSceneTexture .
EBlendableLocation ( Engine/BlendableInterface.h ): BL SceneColorBeforeDOF , BL SceneColorAfterDOF , BL TranslucencyAfterDOF , BL SSRInput , BL SceneColorBeforeBloom , BL ReplacingTonemapper , BL SceneColorAfterTonemapping .
FPostProcessSettings::AddBlendable(TScriptInterface<IBlendableInterface InBlendableObject, float InWeight) and RemoveBlendable operate on the WeightedBlendables array directly if you hold the settings struct rather than the volume.
Decals
UDecalComponent ( Components/DecalComponent.h ) projects a material onto whatever its box overlaps:
Fields: DecalSize (local space extent, scales the projection box), SortOrder , FadeScreenSize , FadeStartDelay , FadeDuration , DecalColor .
Spawn at runtime through UGameplayStatics ( Kismet/GameplayStatics.h ):
SpawnDecalAttached(DecalMaterial, DecalSize, AttachToComponent, AttachPointName, Location, Rotation, LocationType, LifeSpan) follows a moving component. LifeSpan = 0 means the decal persists. To change it later call UDecalComponent::SetLifeSpan(float) ( Components/DecalComponent.h:153 , not a UFUNCTION ) or drive fading with SetFadeOut .
DBuffer decals accumulate into a buffer before the base pass, so they correctly affect lightmapped and sky lighting; they need the restart required project setting r.DBuffer ( URendererSettings::bDBuffer , Engine/RendererSettings.h:942 ). Without it, regular deferred decals still write the GBuffer but do not affect baked/sky lighting correctly.
Nanite
UStaticMesh::HasValidNaniteData() reports whether a mesh has Nanite render data ( IsNaniteEnabled() is WITH EDITORONLY DATA , Engine/StaticMesh.h:1049 — editor builds only). Settings go through the accessors, not the raw field: GetNaniteSettings() / SetNaniteSettings(const FMeshNaniteSettings&) / NotifyNaniteSettingsChanged() .
Material rules worth knowing before writing code:
Material property Nanite
Opaque, two sided Supported
Masked Supported; gated by r.Nanite.AllowMaskedMaterials
World Position Offset Supported; per component SetEvaluateWorldPositionOffset(bool) and