ue-materials-rendering
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseUE Materials and Rendering
UE材质与渲染
You are an expert in Unreal Engine's material and rendering systems. You provide accurate C++ patterns for dynamic materials, parameter collections, post-process, render targets, decals, and UE5 rendering features (Nanite, Lumen, Virtual Shadow Maps).
您是Unreal Engine材质与渲染系统的专家。您提供动态材质、参数集合、后期处理、渲染目标、贴花以及UE5渲染特性(Nanite、Lumen、虚拟阴影贴图)的准确C++实现模式。
Step 1: Read Project Context
步骤1:读取项目上下文
Read before giving advice. From it, extract:
.agents/ue-project-context.md- Engine version — UE5.0–5.4 APIs differ (e.g., added in 5.x;
SetNaniteOverridesignature changed in 5.7)CopyScalarAndVectorParameters - Target platforms — Mobile requires forward rendering; many post-process features are desktop-only
- Rendering settings — Nanite/Lumen enabled status affects which material features are safe
- Module names — needed for correct paths and
#includedependenciesBuild.cs
If the context file is missing, ask for engine version and target platforms before proceeding.
在提供建议前,请先阅读。从中提取以下信息:
.agents/ue-project-context.md- 引擎版本 — UE5.0–5.4的API存在差异(例如在5.x版本中新增;
SetNaniteOverride的签名在5.7版本中变更)CopyScalarAndVectorParameters - 目标平台 — 移动端需要前向渲染;许多后期处理特性仅支持桌面端
- 渲染设置 — Nanite/Lumen的启用状态会影响哪些材质特性是安全可用的
- 模块名称 — 正确的路径和
#include依赖项需要用到这些信息Build.cs
如果上下文文件缺失,请先询问引擎版本和目标平台再继续。
Step 2: Clarify the Rendering Need
步骤2:明确渲染需求
Ask which area the user needs:
- Dynamic Material Instances (MID) — runtime parameter changes on mesh components
- Material Parameter Collections — global parameters shared across all materials
- Post-Process — bloom, exposure, color grading, DOF, AO via volumes or components
- Render Targets — scene capture, minimap, security camera, canvas drawing
- Decals — deferred decals spawned at runtime, fade, sort order
- Rendering Pipeline / UE5 Features — Nanite, Lumen, Virtual Shadow Maps, custom depth/stencil
Multiple areas can be combined.
询问用户需要以下哪个领域的帮助:
- 动态材质实例(MID) — 网格组件上的运行时参数修改
- 材质参数集合 — 所有材质共享的全局参数
- 后期处理 — 通过体积或组件实现 bloom、曝光、颜色分级、景深(DOF)、环境光遮蔽(AO)
- 渲染目标 — 场景捕捉、小地图、监控摄像头、画布绘制
- 贴花 — 运行时生成的延迟贴花、淡入淡出、排序顺序
- 渲染管线/UE5特性 — Nanite、Lumen、虚拟阴影贴图、自定义深度/模板
可以同时选择多个领域。
Core Patterns
核心实现模式
1. Dynamic Material Instances (MID)
1. 动态材质实例(MID)
Creation
创建
Pattern A — from UMaterialInterface (standalone, not tied to a component slot):
cpp
// 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);Pattern B — via component slot (preferred for meshes):
cpp
// 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
);Source: , . Build.cs: .
MaterialInstanceDynamic.hPrimitiveComponent.h"Engine"模式A — 基于UMaterialInterface(独立存在,不绑定到组件插槽):
cpp
// 头文件
UPROPERTY()
TObjectPtr<UMaterialInstanceDynamic> MyMID;
// 实现部分——调用一次(如BeginPlay或等效函数),缓存结果
UMaterialInterface* BaseMat = LoadObject<UMaterialInterface>(
nullptr, TEXT("/Game/Materials/M_MyBase.M_MyBase"));
MyMID = UMaterialInstanceDynamic::Create(BaseMat, this);模式B — 通过组件插槽(推荐用于网格):
cpp
// UMeshComponent::CreateDynamicMaterialInstance会为指定元素索引创建一个MID,并自动将其分配到插槽中。
// 签名:CreateDynamicMaterialInstance(int32 ElementIndex,
// UMaterialInterface* SourceMaterial = nullptr,
// FName OptionalName = NAME_None)
UMaterialInstanceDynamic* MID = MeshComponent->CreateDynamicMaterialInstance(
0, // 元素索引
nullptr, // nullptr = 使用插槽当前的材质作为父材质
TEXT("MyMID") // 可选调试名称
);来源:、。Build.cs依赖:。
MaterialInstanceDynamic.hPrimitiveComponent.h"Engine"Setting Parameters
设置参数
cpp
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 textureFull setter signatures from :
MaterialInstanceDynamic.hcpp
void SetScalarParameterValue(FName ParameterName, float Value);
void SetVectorParameterValue(FName ParameterName, FLinearColor Value); // Pass FLinearColor; no implicit conversion from FVector
void SetTextureParameterValue(FName ParameterName, UTexture* Value);cpp
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)); // 通过FLinearColor传递XYZ值
MyMID->SetTextureParameterValue(TEXT("DamageMask"), MyTexture);
MyMID->SetTextureParameterValue(TEXT("SecurityFeed"), RenderTargetAsset); // 将渲染目标作为纹理MaterialInstanceDynamic.hcpp
void SetScalarParameterValue(FName ParameterName, float Value);
void SetVectorParameterValue(FName ParameterName, FLinearColor Value); // 传递FLinearColor;不支持从FVector隐式转换
void SetTextureParameterValue(FName ParameterName, UTexture* Value);High-Frequency Updates — Index-Based API
高频更新——基于索引的API
When setting dozens of parameters per frame (rare but valid), use index caching:
cpp
// 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);
}Index is invalidated if the parent material changes. Do not share indices across different MID instances.
当每帧需要设置数十个参数时(少见但合法),使用索引缓存:
cpp
// 在BeginPlay或初始化阶段——每个参数名称仅调用一次:
int32 OpacityIndex = -1;
MyMID->InitializeScalarParameterAndGetIndex(TEXT("Opacity"), 1.0f, OpacityIndex);
// 在Tick函数中——使用索引,无需查找名称:
if (OpacityIndex >= 0)
{
MyMID->SetScalarParameterByIndex(OpacityIndex, NewOpacity);
}如果父材质发生变化,索引会失效。不要在不同的MID实例之间共享索引。
MID Lifecycle and GC
MID生命周期与垃圾回收
MIDs are s — they are garbage collected when unreferenced. To keep a MID alive:
UObjectcpp
// In your class header — must be UPROPERTY to prevent GC
UPROPERTY()
TObjectPtr<UMaterialInstanceDynamic> CachedMID;Never store MIDs in raw pointers or local variables across frames.
MID是——当没有引用时会被垃圾回收。要保持MID存活:
UObjectcpp
// 在类的头文件中——必须使用UPROPERTY以防止被垃圾回收
UPROPERTY()
TObjectPtr<UMaterialInstanceDynamic> CachedMID;永远不要在跨帧的原始指针或局部变量中存储MID。
Additional MID Operations
其他MID操作
cpp
// Lerp between two instances' scalar/vector params
MyMID->K2_InterpolateMaterialInstanceParams(InstanceA, InstanceB, Alpha);
// Assign Nanite-compatible override material (UE5)
MyMID->SetNaniteOverride(NaniteCompatibleMaterial);cpp
// 在两个实例的标量/向量参数之间进行插值
MyMID->K2_InterpolateMaterialInstanceParams(InstanceA, InstanceB, Alpha);
// 为Nanite路径分配兼容的覆盖材质(UE5)
MyMID->SetNaniteOverride(NaniteCompatibleMaterial);2. Material Parameter Collections
2. 材质参数集合
UMaterialParameterCollectionCollectionParameterMaterialParameterCollection.hMaterialParameterCollectionInstance.hUMaterialParameterCollectionCollectionParameterMaterialParameterCollection.hMaterialParameterCollectionInstance.hSetting Parameters at Runtime
运行时设置参数
cpp
// 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);
}
}Both setters return if the parameter name is not found. Names are case-sensitive. Limits: max 1024 scalars + 1024 vectors per collection; no texture parameters; global to the world instance.
falsecpp
// MyCollection是一个UPROPERTY(EditAnywhere),指向MPC资源。
UPROPERTY(EditAnywhere, Category="Rendering")
TObjectPtr<UMaterialParameterCollection> GlobalRenderingCollection;
// 运行时——获取每个世界的实例并设置值:
void AMyActor::UpdateGlobalWeather(float RainIntensity, FLinearColor FogColor)
{
UMaterialParameterCollectionInstance* Instance =
GetWorld()->GetParameterCollectionInstance(GlobalRenderingCollection);
if (Instance)
{
Instance->SetScalarParameterValue(TEXT("RainIntensity"), RainIntensity);
Instance->SetVectorParameterValue(TEXT("FogColor"), FogColor);
}
}如果参数名称不存在,两个setter函数都会返回。名称区分大小写。限制:每个集合最多支持1024个标量+1024个向量参数;不支持纹理参数;参数在世界实例范围内全局生效。
false3. Post-Process Volumes
3. 后期处理体积
APostProcessVolumeFPostProcessSettingsbUnbound = trueFrom :
PostProcessVolume.hcpp
struct 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 positionAPostProcessVolumeFPostProcessSettingsbUnbound = true来自:
PostProcessVolume.hcpp
struct FPostProcessSettings Settings; // 设置负载
float Priority; // 重叠时优先级更高的体积生效(优先级相同时顺序未定义)
float BlendRadius; // 世界空间混合距离(单位:厘米,仅当bUnbound = false时生效)
float BlendWeight; // 0 = 无效果,1 = 完全生效
uint32 bEnabled:1;
uint32 bUnbound:1; // true = 无论相机位置如何,全局生效Modifying a Post-Process Volume from C++
通过C++修改后期处理体积
cpp
// 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)Every field in has a corresponding bool that must be set to for the value to take effect. See for a full field reference.
FPostProcessSettingsbOverride_*truereferences/post-process-settings.mdcpp
// 假设PostProcessVolume已分配或找到:
APostProcessVolume* PPV = /* 查找或生成 */;
// 启用并配置
PPV->bEnabled = true;
PPV->bUnbound = true; // 全局效果
PPV->BlendWeight = 1.0f;
// Bloom效果
PPV->Settings.bOverride_BloomIntensity = true;
PPV->Settings.BloomIntensity = 0.5f;
// 自动曝光
PPV->Settings.bOverride_AutoExposureMinBrightness = true;
PPV->Settings.AutoExposureMinBrightness = 0.1f;
PPV->Settings.bOverride_AutoExposureMaxBrightness = true;
PPV->Settings.AutoExposureMaxBrightness = 2.0f;
// 景深(电影级DOF)
PPV->Settings.bOverride_DepthOfFieldFstop = true;
PPV->Settings.DepthOfFieldFstop = 2.8f;
PPV->Settings.bOverride_DepthOfFieldFocalDistance = true;
PPV->Settings.DepthOfFieldFocalDistance = 300.0f; // 单位:厘米
// 环境光遮蔽
PPV->Settings.bOverride_AmbientOcclusionIntensity = true;
PPV->Settings.AmbientOcclusionIntensity = 0.5f;
// 暗角效果
PPV->Settings.bOverride_VignetteIntensity = true;
PPV->Settings.VignetteIntensity = 0.4f;
// 颜色分级
PPV->Settings.bOverride_ColorSaturation = true;
PPV->Settings.ColorSaturation = FVector4(1.2f, 1.0f, 0.8f, 1.0f); // 按RGBA通道设置
PPV->Settings.bOverride_FilmSlope = true;
PPV->Settings.FilmSlope = 0.88f; // 0–1(默认值0.88)FPostProcessSettingsbOverride_*truereferences/post-process-settings.mdPost-Process Materials (Blendables)
后期处理材质(Blendables)
Material Domain must be "Post Process". Add via:
cpp
PPV->AddOrUpdateBlendable(PostProcessMaterial, 1.0f); // weight 0.0–1.0材质域必须设置为“Post Process”。通过以下方式添加:
cpp
PPV->AddOrUpdateBlendable(PostProcessMaterial, 1.0f); // 权重范围0.0–1.0UPostProcessComponent (Actor-Owned)
UPostProcessComponent(Actor所属)
cpp
// Constructor
PostProcessComp = CreateDefaultSubobject<UPostProcessComponent>(TEXT("PostProcess"));
PostProcessComp->bUnbound = true;
PostProcessComp->Priority = 5.0f;
// Runtime
PostProcessComp->Settings.bOverride_BloomIntensity = true;
PostProcessComp->Settings.BloomIntensity = 1.5f;Includes: , , .
"Components/PostProcessComponent.h""Engine/PostProcessVolume.h""Engine/Scene.h"cpp
// 构造函数
PostProcessComp = CreateDefaultSubobject<UPostProcessComponent>(TEXT("PostProcess"));
PostProcessComp->bUnbound = true;
PostProcessComp->Priority = 5.0f;
// 运行时
PostProcessComp->Settings.bOverride_BloomIntensity = true;
PostProcessComp->Settings.BloomIntensity = 1.5f;包含头文件:、、。
"Components/PostProcessComponent.h""Engine/PostProcessVolume.h""Engine/Scene.h"4. Render Targets
4. 渲染目标
Creating a Render Target in C++
通过C++创建渲染目标
cpp
#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 |
cpp
#include "Engine/TextureRenderTarget2D.h"
#include "Kismet/KismetRenderingLibrary.h"
// 选项A — 使用UKismetRenderingLibrary(自动处理资源初始化)
UTextureRenderTarget2D* RT = UKismetRenderingLibrary::CreateRenderTarget2D(
this, // WorldContextObject
512, // 宽度
512, // 高度
RTF_RGBA16f, // 格式(参考ETextureRenderTargetFormat)
FLinearColor::Black,
false // bAutoGenerateMipMaps
);
// 选项B — 手动创建
UTextureRenderTarget2D* RT = NewObject<UTextureRenderTarget2D>(this);
RT->InitCustomFormat(512, 512, PF_FloatRGBA, /*bInForceLinearGamma=*/true);
RT->UpdateResourceImmediate(/*bClearRenderTarget=*/true);ETextureRenderTargetFormatTextureRenderTarget2D.h| 格式 | 通道 | 每通道位数 | 使用场景 |
|---|---|---|---|
| RGBA | 8位固定精度 | LDR颜色、UI |
| RGBA | 8位固定精度 | sRGB颜色 |
| RGBA | 16位浮点 | HDR颜色(默认) |
| RGBA | 32位浮点 | 高精度数据 |
| R | 16位浮点 | 单通道数据 |
| RGB+A | 10+2位 | 显示输出 |
Scene Capture (Security Camera / Minimap)
场景捕捉(监控摄像头/小地图)
cpp
#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);cpp
#include "Components/SceneCaptureComponent2D.h"
// 在Actor构造函数中
SceneCapture = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("SceneCapture"));
SceneCapture->SetupAttachment(RootComponent);
SceneCapture->FOVAngle = 90.f;
SceneCapture->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR; // 或SCS_SceneColorHDR
SceneCapture->bCaptureEveryFrame = true; // 持续更新
// 分配渲染目标资源或运行时创建的渲染目标
SceneCapture->TextureTarget = MyRenderTargetAsset;
// 限制捕捉内容以提升性能
SceneCapture->ShowFlags.SetAtmosphere(false);
SceneCapture->ShowFlags.SetFog(false);Drawing a Material to a Render Target
将材质绘制到渲染目标
cpp
// 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*
);cpp
// 将材质应用到全屏四边形并渲染到TextureTarget。
// 此操作开销较大(每次调用都会设置渲染目标);批量处理请使用画布API。
UKismetRenderingLibrary::DrawMaterialToRenderTarget(
this, // WorldContextObject
RT, // UTextureRenderTarget2D*
MyMaterial // UMaterialInterface*
);Canvas Drawing (Batched)
画布绘制(批量处理)
cpp
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);UCanvasRenderTarget2DUTextureRenderTarget2DOnCanvasRenderTargetUpdateBeginDrawCanvasToRenderTargetcpp
UCanvas* Canvas;
FVector2D CanvasSize;
FDrawToRenderTargetContext Context;
UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(this, RT, Canvas, CanvasSize, Context);
// 在此处向Canvas绘制图元...
Canvas->K2_DrawMaterial(MyMaterial, FVector2D(0, 0), CanvasSize, FVector2D(0, 0), FVector2D(1, 1));
UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(this, Context);UCanvasRenderTarget2DUTextureRenderTarget2DOnCanvasRenderTargetUpdateBeginDrawCanvasToRenderTargetReading Pixels (GPU Stall — Offline Only)
读取像素(GPU阻塞——仅离线使用)
cpp
// 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);cpp
// 警告:会阻塞GPU管线。仅用于编辑器工具/截图,绝不要每帧调用。
FColor Pixel = UKismetRenderingLibrary::ReadRenderTargetPixel(this, RT, X, Y);
TArray<FColor> Pixels;
UKismetRenderingLibrary::ReadRenderTarget(this, RT, Pixels); // 读取整个渲染目标,8位sRGB
FLinearColor Raw = UKismetRenderingLibrary::ReadRenderTargetRawPixel(this, RT, X, Y);5. Decals
5. 贴花
UDecalComponentDecalComponent.hcpp
void 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)UDecalComponentDecalComponent.hcpp
void SetDecalMaterial(UMaterialInterface* NewDecalMaterial);
UMaterialInstanceDynamic* CreateDynamicMaterialInstance(); // 贴花的MID
void SetFadeOut(float StartDelay, float Duration, bool DestroyOwnerAfterFade = true);
void SetFadeIn(float StartDelay, float Duration);
void SetSortOrder(int32 Value); // 值越大,绘制层级越靠上
void SetLifeSpan(float LifeSpan);
FVector DecalSize; // 局部空间范围(不是组件缩放)Spawning Decals at Runtime
运行时生成贴花
cpp
// 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);cpp
// 生命周期为0.0f表示永久存在;>0.0f表示N秒后自动销毁
UDecalComponent* Decal = UGameplayStatics::SpawnDecalAtLocation(
this, DecalMaterial, FVector(200.f), HitLocation, HitNormal.Rotation(), 0.0f);
// 为贴花设置动态参数
UMaterialInstanceDynamic* DecalMID = Decal->CreateDynamicMaterialInstance();
DecalMID->SetScalarParameterValue(TEXT("Opacity"), 0.8f);DBuffer vs Non-DBuffer Decals
DBuffer与非DBuffer贴花
- DBuffer (Translucent + DBuffer enabled): writes before lighting, affects diffuse/normals/roughness. Enable via .
Project Settings > Rendering > DBuffer Decals - Non-DBuffer: rendered after lighting, emissive/opacity only; cheaper but limited.
For level-placed decals, use (a wrapper around ). For runtime-spawned decals, prefer or .
ADecalActorUDecalComponentUGameplayStatics::SpawnDecalAtLocationSpawnDecalAttached- DBuffer(半透明+启用DBuffer):在光照前写入,影响漫反射/法线/粗糙度。通过启用。
项目设置 > 渲染 > DBuffer贴花 - 非DBuffer:在光照后渲染,仅支持自发光/透明度;性能开销更低但功能有限。
对于关卡中放置的贴花,使用(的封装)。对于运行时生成的贴花,优先使用或。
ADecalActorUDecalComponentUGameplayStatics::SpawnDecalAtLocationSpawnDecalAttached6. Nanite and Lumen (UE5)
6. Nanite与Lumen(UE5)
Nanite
Nanite
Nanite is UE5's virtualized geometry system. Material compatibility rules:
| 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 at runtime:
cpp
// Check if a static mesh component is using Nanite (IsNaniteEnabled is on UStaticMesh, not on the component)
bool bIsNanite = StaticMeshComponent->GetStaticMesh() && StaticMeshComponent->GetStaticMesh()->IsNaniteEnabled();Override material for Nanite path:
cpp
MyMID->SetNaniteOverride(NaniteCompatibleMaterial);Nanite是UE5的虚拟化几何体系统。材质兼容性规则:
| 特性 | 是否兼容Nanite |
|---|---|
| 不透明材质 | 是 |
| 双面材质 | 是 |
| 遮罩材质 | 是(需设置 |
| 半透明材质 | 否 — 回退到非Nanite路径 |
| 世界位置偏移(WPO) | UE 5.1+支持(在网格上启用 |
| 像素深度偏移 | 否 |
| 通过着色器自定义顶点法线 | 有限支持 |
运行时检查:
cpp
// 检查静态网格组件是否使用Nanite(IsNaniteEnabled属于UStaticMesh,而非组件)
bool bIsNanite = StaticMeshComponent->GetStaticMesh() && StaticMeshComponent->GetStaticMesh()->IsNaniteEnabled();为Nanite路径覆盖材质:
cpp
MyMID->SetNaniteOverride(NaniteCompatibleMaterial);Lumen
Lumen
Lumen is UE5's dynamic GI and reflections system. Emissive surfaces can act as lights. Translucent surfaces are not traced by default. Control quality via post-process settings:
cpp
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;Performance: controls cache update rate.
r.Lumen.SurfaceCache.UpdateDownsampleFactorLumen是UE5的动态全局光照与反射系统。自发光表面可作为光源。半透明表面默认不被追踪。通过后期处理设置控制质量:
cpp
PPV->Settings.bOverride_LumenReflectionQuality = true;
PPV->Settings.LumenReflectionQuality = 1.0f; // 0–4
PPV->Settings.bOverride_LumenSceneDetail = true;
PPV->Settings.LumenSceneDetail = 1.0f; // 表面缓存分辨率乘数
PPV->Settings.bOverride_LumenSceneLightingQuality = true;
PPV->Settings.LumenSceneLightingQuality = 1.0f;性能优化:控制缓存更新速率。
r.Lumen.SurfaceCache.UpdateDownsampleFactorDeferred vs Forward Rendering
延迟渲染与前向渲染
Deferred vs Forward: UE5 desktop uses deferred rendering by default — geometry writes to GBuffer, then lighting is computed per-pixel. Forward rendering (mobile, VR) processes lighting per-object, supports MSAA, but limits dynamic light count. Set via .
Project Settings > Rendering > Forward ShadingScalability: Use (in ) or console commands such as to adjust rendering quality at runtime. Configure presets in .
Scalability::SetQualityLevels()Scalability.hsg.PostProcessQuality 0-3BaseScalability.ini延迟渲染 vs 前向渲染:UE5桌面端默认使用延迟渲染——几何体写入GBuffer,然后按像素计算光照。前向渲染(移动端、VR)按对象处理光照,支持MSAA,但限制动态光源数量。通过设置。
项目设置 > 渲染 > 前向着色可伸缩性:使用(位于)或控制台命令(如)在运行时调整渲染质量。在中配置预设。
Scalability::SetQualityLevels()Scalability.hsg.PostProcessQuality 0-3BaseScalability.iniVirtual Shadow Maps (VSM)
虚拟阴影贴图(VSM)
- WPO materials: enable "Evaluate World Position Offset" in the material's Details panel (material editor setting, not a C++ property) for correct VSM shadows.
- Masked materials: opacity masks respected correctly.
- Decals do not cast VSM shadows.
- WPO材质:在材质的细节面板中启用“Evaluate World Position Offset”(材质编辑器设置,非C++属性),以确保VSM阴影正确。
- 遮罩材质:透明度遮罩会被正确识别。
- 贴花不会投射VSM阴影。
Custom Depth / Stencil (Outlines and Effects)
自定义深度/模板(轮廓与特效)
cpp
MeshComponent->SetRenderCustomDepth(true);
MeshComponent->SetCustomDepthStencilValue(1); // 0–255
// Sample CustomDepth / CustomStencil nodes in a post-process material for outlines, X-ray, highlight effects.Enable: .
Project Settings > Rendering > Custom Depth-Stencil Pass > Enabled with Stencilcpp
MeshComponent->SetRenderCustomDepth(true);
MeshComponent->SetCustomDepthStencilValue(1); // 0–255
// 在后期处理材质中采样CustomDepth / CustomStencil节点,实现轮廓、X光、高亮等特效。启用方式:。
项目设置 > 渲染 > 自定义深度-模板通道 > 启用模板Common Mistakes and Anti-Patterns
常见错误与反模式
Creating MIDs every frame — Each call allocates a new GPU resource. Create once in , cache, update in :
CreateDynamicMaterialInstanceBeginPlayTickcpp
// BeginPlay
CachedMID = MeshComponent->CreateDynamicMaterialInstance(0);
// Tick
if (CachedMID) { CachedMID->SetScalarParameterValue(TEXT("Time"), GetWorld()->TimeSeconds); }Not caching MID as UPROPERTY — Raw is invisible to GC and collected on the next GC pass. Use .
UMaterialInstanceDynamic*UPROPERTY() TObjectPtr<UMaterialInstanceDynamic> CachedMID;Wrong parameter names — Names are case-sensitive exact matches. , , and all silently fail if the material uses .
"basecolor""Base Color""Base_Color""BaseColor"Render target resolution — Match resolution to use: 256–512 for minimap/security camera, 512 max for mirrors; use planar reflections for large mirrors. Full-screen: use on .
bMainViewResolutionUSceneCaptureComponent2DReading render target pixels per frame — stalls the GPU pipeline. Never call per frame. Use for async non-stalling reads.
ReadRenderTargetPixelFRHIGPUTextureReadbackMIDs on replicated actors — MIDs are client-local. Do not replicate the MID pointer. Replicate the scalar/vector values and re-apply via functions on each client.
OnRepPost-process bOverride not set — Every field requires its paired bool set to . Setting a value without the override is a silent no-op.
FPostProcessSettingsbOverride_*trueNanite translucency fallback — Translucent materials on Nanite meshes revert the full mesh to non-Nanite rendering. Split into separate opaque and translucent components.
每帧创建MID — 每次调用都会分配新的GPU资源。在中创建一次并缓存,在中更新:
CreateDynamicMaterialInstanceBeginPlayTickcpp
// BeginPlay
CachedMID = MeshComponent->CreateDynamicMaterialInstance(0);
// Tick
if (CachedMID) { CachedMID->SetScalarParameterValue(TEXT("Time"), GetWorld()->TimeSeconds); }未将MID缓存为UPROPERTY — 原始对垃圾回收不可见,会在下一次垃圾回收时被回收。使用。
UMaterialInstanceDynamic*UPROPERTY() TObjectPtr<UMaterialInstanceDynamic> CachedMID;参数名称错误 — 名称需完全匹配且区分大小写。如果材质使用,那么、和都会静默失败。
"BaseColor""basecolor""Base Color""Base_Color"渲染目标分辨率 — 根据使用场景匹配分辨率:小地图/监控摄像头使用256–512;镜子最大使用512;大型镜子使用平面反射。全屏场景:在上启用。
USceneCaptureComponent2DbMainViewResolution每帧读取渲染目标像素 — 会阻塞GPU管线。绝不要每帧调用。使用进行异步无阻塞读取。
ReadRenderTargetPixelFRHIGPUTextureReadback在复制Actor上使用MID — MID是客户端本地的。不要复制MID指针。复制标量/向量值,并在每个客户端通过函数重新应用。
OnRep未设置后期处理的bOverride — 的每个字段都需要将对应的布尔值设置为。仅设置值而不启用覆盖会静默无效。
FPostProcessSettingsbOverride_*trueNanite半透明回退 — Nanite网格上的半透明材质会使整个网格回退到非Nanite渲染。将网格拆分为独立的不透明和半透明组件。
Required Build.cs Dependencies
必需的Build.cs依赖项
csharp
PublicDependencyModuleNames.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.csharp
PublicDependencyModuleNames.AddRange(new string[]
{
"Engine", // 材质、渲染目标、UTextureRenderTarget2D
"RenderCore", // 底层渲染工具
"RHI", // RHI类型(如EPixelFormat等)
});
// 对于UKismetRenderingLibrary:
// 已通过"Engine"模块提供——无需单独添加模块。Related Skills
相关技能
- — UObject management, UPROPERTY, TObjectPtr, garbage collection
ue-cpp-foundations - — setting up components (UDecalComponent, USceneCaptureComponent2D, UPostProcessComponent)
ue-actor-component-architecture - — particle materials use MIDs; parameter passing into Niagara from C++
ue-niagara-effects - — engine version, target platforms, rendering feature flags
ue-project-context
- — UObject管理、UPROPERTY、TObjectPtr、垃圾回收
ue-cpp-foundations - — 组件设置(UDecalComponent、USceneCaptureComponent2D、UPostProcessComponent)
ue-actor-component-architecture - — 粒子材质使用MID;从C++向Niagara传递参数
ue-niagara-effects - — 引擎版本、目标平台、渲染特性标志
ue-project-context