Loading...
Loading...
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-settings.md for post-process settings. For particle rendering, see ue-niagara-effects.
npx skill4agent add quodsoler/unreal-engine-skills ue-materials-rendering.agents/ue-project-context.mdSetNaniteOverrideCopyScalarAndVectorParameters#includeBuild.cs// Header
UPROPERTY()
TObjectPtr<UMaterialInstanceDynamic> MyMID;
// Implementation — call once (BeginPlay or equivalent), cache the result
UMaterialInterface* BaseMat = LoadObject<UMaterialInterface>(
nullptr, TEXT("/Game/Materials/M_MyBase.M_MyBase"));
MyMID = UMaterialInstanceDynamic::Create(BaseMat, this);// UMeshComponent::CreateDynamicMaterialInstance creates a MID for the given
// element index and assigns it to the slot automatically.
// Signature: CreateDynamicMaterialInstance(int32 ElementIndex,
// UMaterialInterface* SourceMaterial = nullptr,
// FName OptionalName = NAME_None)
UMaterialInstanceDynamic* MID = MeshComponent->CreateDynamicMaterialInstance(
0, // element index
nullptr, // nullptr = use the slot's current material as parent
TEXT("MyMID") // optional debug name
);MaterialInstanceDynamic.hPrimitiveComponent.h"Engine"MyMID->SetScalarParameterValue(TEXT("Opacity"), 0.5f);
MyMID->SetVectorParameterValue(TEXT("BaseColor"), FLinearColor(1.f, 0.2f, 0.1f, 1.f));
MyMID->SetVectorParameterValue(TEXT("Offset"), FLinearColor(0.f, 0.f, 100.f, 0.f)); // XYZ via FLinearColor
MyMID->SetTextureParameterValue(TEXT("DamageMask"), MyTexture);
MyMID->SetTextureParameterValue(TEXT("SecurityFeed"), RenderTargetAsset); // RT as textureMaterialInstanceDynamic.hvoid SetScalarParameterValue(FName ParameterName, float Value);
void SetVectorParameterValue(FName ParameterName, FLinearColor Value); // Pass FLinearColor; no implicit conversion from FVector
void SetTextureParameterValue(FName ParameterName, UTexture* Value);// In BeginPlay or initialization — call once per parameter name:
int32 OpacityIndex = -1;
MyMID->InitializeScalarParameterAndGetIndex(TEXT("Opacity"), 1.0f, OpacityIndex);
// In Tick — use index, no name lookup:
if (OpacityIndex >= 0)
{
MyMID->SetScalarParameterByIndex(OpacityIndex, NewOpacity);
}UObject// In your class header — must be UPROPERTY to prevent GC
UPROPERTY()
TObjectPtr<UMaterialInstanceDynamic> CachedMID;// Lerp between two instances' scalar/vector params
MyMID->K2_InterpolateMaterialInstanceParams(InstanceA, InstanceB, Alpha);
// Assign Nanite-compatible override material (UE5)
MyMID->SetNaniteOverride(NaniteCompatibleMaterial);UMaterialParameterCollectionCollectionParameterMaterialParameterCollection.hMaterialParameterCollectionInstance.h// MyCollection is a UPROPERTY(EditAnywhere) pointing to the MPC asset.
UPROPERTY(EditAnywhere, Category="Rendering")
TObjectPtr<UMaterialParameterCollection> GlobalRenderingCollection;
// At runtime — get the per-world instance and set values:
void AMyActor::UpdateGlobalWeather(float RainIntensity, FLinearColor FogColor)
{
UMaterialParameterCollectionInstance* Instance =
GetWorld()->GetParameterCollectionInstance(GlobalRenderingCollection);
if (Instance)
{
Instance->SetScalarParameterValue(TEXT("RainIntensity"), RainIntensity);
Instance->SetVectorParameterValue(TEXT("FogColor"), FogColor);
}
}falseAPostProcessVolumeFPostProcessSettingsbUnbound = truePostProcessVolume.hstruct FPostProcessSettings Settings; // The settings payload
float Priority; // Higher priority wins on overlap (undefined order when equal)
float BlendRadius; // World-space blend distance in cm (only when bUnbound = false)
float BlendWeight; // 0 = no effect, 1 = full effect
uint32 bEnabled:1;
uint32 bUnbound:1; // true = applies globally regardless of camera position// Assume PostProcessVolume is assigned or found:
APostProcessVolume* PPV = /* find or spawn */;
// Enable and configure
PPV->bEnabled = true;
PPV->bUnbound = true; // global effect
PPV->BlendWeight = 1.0f;
// Bloom
PPV->Settings.bOverride_BloomIntensity = true;
PPV->Settings.BloomIntensity = 0.5f;
// Auto Exposure
PPV->Settings.bOverride_AutoExposureMinBrightness = true;
PPV->Settings.AutoExposureMinBrightness = 0.1f;
PPV->Settings.bOverride_AutoExposureMaxBrightness = true;
PPV->Settings.AutoExposureMaxBrightness = 2.0f;
// Depth of Field (Cinematic DOF)
PPV->Settings.bOverride_DepthOfFieldFstop = true;
PPV->Settings.DepthOfFieldFstop = 2.8f;
PPV->Settings.bOverride_DepthOfFieldFocalDistance = true;
PPV->Settings.DepthOfFieldFocalDistance = 300.0f; // cm
// Ambient Occlusion
PPV->Settings.bOverride_AmbientOcclusionIntensity = true;
PPV->Settings.AmbientOcclusionIntensity = 0.5f;
// Vignette
PPV->Settings.bOverride_VignetteIntensity = true;
PPV->Settings.VignetteIntensity = 0.4f;
// Color Grading
PPV->Settings.bOverride_ColorSaturation = true;
PPV->Settings.ColorSaturation = FVector4(1.2f, 1.0f, 0.8f, 1.0f); // per-channel RGBA
PPV->Settings.bOverride_FilmSlope = true;
PPV->Settings.FilmSlope = 0.88f; // 0–1 (default 0.88)FPostProcessSettingsbOverride_*truereferences/post-process-settings.mdPPV->AddOrUpdateBlendable(PostProcessMaterial, 1.0f); // weight 0.0–1.0// Constructor
PostProcessComp = CreateDefaultSubobject<UPostProcessComponent>(TEXT("PostProcess"));
PostProcessComp->bUnbound = true;
PostProcessComp->Priority = 5.0f;
// Runtime
PostProcessComp->Settings.bOverride_BloomIntensity = true;
PostProcessComp->Settings.BloomIntensity = 1.5f;"Components/PostProcessComponent.h""Engine/PostProcessVolume.h""Engine/Scene.h"#include "Engine/TextureRenderTarget2D.h"
#include "Kismet/KismetRenderingLibrary.h"
// Option A — via UKismetRenderingLibrary (handles resource init automatically)
UTextureRenderTarget2D* RT = UKismetRenderingLibrary::CreateRenderTarget2D(
this, // WorldContextObject
512, // Width
512, // Height
RTF_RGBA16f, // Format (see ETextureRenderTargetFormat)
FLinearColor::Black,
false // bAutoGenerateMipMaps
);
// Option B — manual creation
UTextureRenderTarget2D* RT = NewObject<UTextureRenderTarget2D>(this);
RT->InitCustomFormat(512, 512, PF_FloatRGBA, /*bInForceLinearGamma=*/true);
RT->UpdateResourceImmediate(/*bClearRenderTarget=*/true);ETextureRenderTargetFormatTextureRenderTarget2D.h| Format | Channels | Bits/Channel | Use Case |
|---|---|---|---|
| RGBA | 8 fixed | LDR color, UI |
| RGBA | 8 fixed | sRGB color |
| RGBA | 16 float | HDR color (default) |
| RGBA | 32 float | High precision data |
| R | 16 float | Single channel data |
| RGB+A | 10+2 bit | Display output |
#include "Components/SceneCaptureComponent2D.h"
// In actor constructor
SceneCapture = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("SceneCapture"));
SceneCapture->SetupAttachment(RootComponent);
SceneCapture->FOVAngle = 90.f;
SceneCapture->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR; // or SCS_SceneColorHDR
SceneCapture->bCaptureEveryFrame = true; // continuous update
// Assign a render target asset or a runtime-created one
SceneCapture->TextureTarget = MyRenderTargetAsset;
// Limit what's captured for performance
SceneCapture->ShowFlags.SetAtmosphere(false);
SceneCapture->ShowFlags.SetFog(false);// Renders a full-screen quad with Material applied to TextureTarget.
// This is expensive (sets render target each call); use canvas API for batching.
UKismetRenderingLibrary::DrawMaterialToRenderTarget(
this, // WorldContextObject
RT, // UTextureRenderTarget2D*
MyMaterial // UMaterialInterface*
);UCanvas* Canvas;
FVector2D CanvasSize;
FDrawToRenderTargetContext Context;
UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(this, RT, Canvas, CanvasSize, Context);
// Draw primitives to Canvas here...
Canvas->K2_DrawMaterial(MyMaterial, FVector2D(0, 0), CanvasSize, FVector2D(0, 0), FVector2D(1, 1));
UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(this, Context);UCanvasRenderTarget2DUTextureRenderTarget2DOnCanvasRenderTargetUpdateBeginDrawCanvasToRenderTarget// WARNING: stalls GPU pipeline. Editor tools / screenshot only, never per-frame.
FColor Pixel = UKismetRenderingLibrary::ReadRenderTargetPixel(this, RT, X, Y);
TArray<FColor> Pixels;
UKismetRenderingLibrary::ReadRenderTarget(this, RT, Pixels); // whole RT, 8-bit sRGB
FLinearColor Raw = UKismetRenderingLibrary::ReadRenderTargetRawPixel(this, RT, X, Y);UDecalComponentDecalComponent.hvoid SetDecalMaterial(UMaterialInterface* NewDecalMaterial);
UMaterialInstanceDynamic* CreateDynamicMaterialInstance(); // MID on the decal
void SetFadeOut(float StartDelay, float Duration, bool DestroyOwnerAfterFade = true);
void SetFadeIn(float StartDelay, float Duration);
void SetSortOrder(int32 Value); // higher = draws on top
void SetLifeSpan(float LifeSpan);
FVector DecalSize; // local-space extent (not component scale)// 0.0f lifespan = persistent; >0.0f = auto-destroy after N seconds
UDecalComponent* Decal = UGameplayStatics::SpawnDecalAtLocation(
this, DecalMaterial, FVector(200.f), HitLocation, HitNormal.Rotation(), 0.0f);
// Dynamic parameters on the decal
UMaterialInstanceDynamic* DecalMID = Decal->CreateDynamicMaterialInstance();
DecalMID->SetScalarParameterValue(TEXT("Opacity"), 0.8f);Project Settings > Rendering > DBuffer DecalsADecalActorUDecalComponentUGameplayStatics::SpawnDecalAtLocationSpawnDecalAttached| Feature | Nanite Compatible |
|---|---|
| Opaque materials | Yes |
| Two-sided materials | Yes |
| Masked materials | Yes (with |
| Translucent materials | No — falls back to non-Nanite path |
| World Position Offset (WPO) | Supported in UE 5.1+ ( |
| Pixel Depth Offset | No |
| Custom vertex normals via shader | Limited |
// Check if a static mesh component is using Nanite (IsNaniteEnabled is on UStaticMesh, not on the component)
bool bIsNanite = StaticMeshComponent->GetStaticMesh() && StaticMeshComponent->GetStaticMesh()->IsNaniteEnabled();MyMID->SetNaniteOverride(NaniteCompatibleMaterial);PPV->Settings.bOverride_LumenReflectionQuality = true;
PPV->Settings.LumenReflectionQuality = 1.0f; // 0–4
PPV->Settings.bOverride_LumenSceneDetail = true;
PPV->Settings.LumenSceneDetail = 1.0f; // surface cache resolution multiplier
PPV->Settings.bOverride_LumenSceneLightingQuality = true;
PPV->Settings.LumenSceneLightingQuality = 1.0f;r.Lumen.SurfaceCache.UpdateDownsampleFactorProject Settings > Rendering > Forward ShadingScalability::SetQualityLevels()Scalability.hsg.PostProcessQuality 0-3BaseScalability.iniMeshComponent->SetRenderCustomDepth(true);
MeshComponent->SetCustomDepthStencilValue(1); // 0–255
// Sample CustomDepth / CustomStencil nodes in a post-process material for outlines, X-ray, highlight effects.Project Settings > Rendering > Custom Depth-Stencil Pass > Enabled with StencilCreateDynamicMaterialInstanceBeginPlayTick// BeginPlay
CachedMID = MeshComponent->CreateDynamicMaterialInstance(0);
// Tick
if (CachedMID) { CachedMID->SetScalarParameterValue(TEXT("Time"), GetWorld()->TimeSeconds); }UMaterialInstanceDynamic*UPROPERTY() TObjectPtr<UMaterialInstanceDynamic> CachedMID;"basecolor""Base Color""Base_Color""BaseColor"bMainViewResolutionUSceneCaptureComponent2DReadRenderTargetPixelFRHIGPUTextureReadbackOnRepFPostProcessSettingsbOverride_*truePublicDependencyModuleNames.AddRange(new string[]
{
"Engine", // Materials, render targets, UTextureRenderTarget2D
"RenderCore", // Low-level render utilities
"RHI", // RHI types (EPixelFormat, etc.)
});
// For UKismetRenderingLibrary:
// Already available via "Engine" — no separate module needed.ue-cpp-foundationsue-actor-component-architectureue-niagara-effectsue-project-context