claude-code-arcane 2.2.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (144) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +104 -55
  3. package/agents/career/career-strategist.md +88 -0
  4. package/agents/career/cv-reviewer.md +81 -0
  5. package/agents/career/hiring-manager.md +68 -0
  6. package/agents/career/mock-interviewer.md +76 -0
  7. package/agents/freelance/client-screener.md +84 -0
  8. package/agents/freelance/discovery-call.md +65 -0
  9. package/agents/freelance/pipeline-strategist.md +99 -0
  10. package/agents/freelance/proposal-reviewer.md +82 -0
  11. package/agents/game/ue-blueprint-specialist.md +125 -0
  12. package/agents/game/ue-gas-specialist.md +133 -0
  13. package/agents/game/ue-umg-specialist.md +131 -0
  14. package/dist/cli.js +57 -13
  15. package/docs/RELEASE-SETUP.md +1 -1
  16. package/docs/SKILLS-CATALOG.md +67 -4
  17. package/docs/USER-GUIDE.md +77 -72
  18. package/docs/agent-hierarchy.md +21 -1
  19. package/docs/presentations/build_arcane_deck.py +2 -2
  20. package/docs/presentations/build_arcane_deck_12.py +2 -2
  21. package/hooks/detect-unreal.sh +90 -0
  22. package/package.json +2 -2
  23. package/profiles/freelance.yaml +43 -0
  24. package/profiles/job-hunt.yaml +5 -2
  25. package/profiles/unreal-dev.yaml +97 -0
  26. package/rules/drafter-reviewer.md +16 -3
  27. package/rules/freelance-guardrails.md +53 -0
  28. package/rules/gamedev/unreal-code.md +125 -0
  29. package/skills/career-registry/SKILL.md +95 -0
  30. package/skills/career-registry/scripts/career_registry.py +488 -0
  31. package/skills/client-screen/SKILL.md +83 -0
  32. package/skills/client-screen/references/red-flags.md +95 -0
  33. package/skills/cover-letter/SKILL.md +4 -3
  34. package/skills/cv-tailor/SKILL.md +11 -2
  35. package/skills/freelance-deliver/SKILL.md +90 -0
  36. package/skills/freelance-hunt/SKILL.md +126 -0
  37. package/skills/freelance-hunt/references/templates/Connects.md +39 -0
  38. package/skills/freelance-hunt/references/templates/Contrato.md +60 -0
  39. package/skills/freelance-hunt/references/templates/Propuesta.md +66 -0
  40. package/skills/freelance-kickoff/SKILL.md +94 -0
  41. package/skills/freelance-pipeline/SKILL.md +109 -0
  42. package/skills/freelance-pipeline/scripts/import_history.py +425 -0
  43. package/skills/freelance-profile/SKILL.md +93 -0
  44. package/skills/freelance-proposal/SKILL.md +112 -0
  45. package/skills/freelance-scan/SKILL.md +196 -0
  46. package/skills/freelance-scan/references/dedup.md +35 -0
  47. package/skills/freelance-scan/references/platforms.md +167 -0
  48. package/skills/freelance-scan/scripts/freelance_search.py +1077 -0
  49. package/skills/install-mcp/SKILL.md +135 -46
  50. package/skills/install-mcp/references/unreal-operations.md +55 -0
  51. package/skills/interview-prep/SKILL.md +11 -3
  52. package/skills/job-aplicar/SKILL.md +5 -1
  53. package/skills/job-hunt/SKILL.md +17 -0
  54. package/skills/job-outcome/SKILL.md +15 -1
  55. package/skills/job-upskill/SKILL.md +10 -2
  56. package/skills/ue-actor-component-architecture/SKILL.md +509 -0
  57. package/skills/ue-actor-component-architecture/references/actor-lifecycle.md +301 -0
  58. package/skills/ue-actor-component-architecture/references/component-types.md +592 -0
  59. package/skills/ue-ai-navigation/SKILL.md +526 -0
  60. package/skills/ue-ai-navigation/references/behavior-tree-patterns.md +392 -0
  61. package/skills/ue-ai-navigation/references/behavior-tree-workflow.md +107 -0
  62. package/skills/ue-ai-navigation/references/custom-bttask.md +104 -0
  63. package/skills/ue-ai-navigation/references/eqs-reference.md +423 -0
  64. package/skills/ue-animation-system/SKILL.md +521 -0
  65. package/skills/ue-animation-system/references/anim-notify-reference.md +486 -0
  66. package/skills/ue-animation-system/references/locomotion-setup.md +550 -0
  67. package/skills/ue-async-threading/SKILL.md +433 -0
  68. package/skills/ue-async-threading/references/thread-safety-guide.md +213 -0
  69. package/skills/ue-async-threading/references/threading-patterns.md +345 -0
  70. package/skills/ue-audio-system/SKILL.md +527 -0
  71. package/skills/ue-audio-system/references/audio-setup-patterns.md +700 -0
  72. package/skills/ue-blueprints/SKILL.md +134 -0
  73. package/skills/ue-blueprints/references/communication.md +82 -0
  74. package/skills/ue-character-movement/SKILL.md +475 -0
  75. package/skills/ue-character-movement/references/cmc-extension-patterns.md +335 -0
  76. package/skills/ue-character-movement/references/movement-pipeline.md +189 -0
  77. package/skills/ue-cpp-foundations/SKILL.md +533 -0
  78. package/skills/ue-cpp-foundations/references/components-and-gc.md +107 -0
  79. package/skills/ue-cpp-foundations/references/container-patterns.md +544 -0
  80. package/skills/ue-cpp-foundations/references/delegate-patterns.md +497 -0
  81. package/skills/ue-cpp-foundations/references/gameplay-classes-cpp.md +136 -0
  82. package/skills/ue-cpp-foundations/references/property-specifiers.md +306 -0
  83. package/skills/ue-data-assets-tables/SKILL.md +527 -0
  84. package/skills/ue-data-assets-tables/references/asset-loading-patterns.md +306 -0
  85. package/skills/ue-data-assets-tables/references/data-driven-design.md +378 -0
  86. package/skills/ue-editor-tools/SKILL.md +523 -0
  87. package/skills/ue-editor-tools/references/detail-customization-patterns.md +395 -0
  88. package/skills/ue-editor-tools/references/editor-module-setup.md +480 -0
  89. package/skills/ue-game-features/SKILL.md +477 -0
  90. package/skills/ue-game-features/references/experience-system.md +222 -0
  91. package/skills/ue-game-features/references/game-feature-patterns.md +308 -0
  92. package/skills/ue-gameplay-abilities/SKILL.md +518 -0
  93. package/skills/ue-gameplay-abilities/references/ability-task-reference.md +391 -0
  94. package/skills/ue-gameplay-abilities/references/gameplay-effect-reference.md +397 -0
  95. package/skills/ue-gameplay-abilities/references/gas-setup-patterns.md +369 -0
  96. package/skills/ue-gameplay-framework/SKILL.md +466 -0
  97. package/skills/ue-gameplay-framework/references/framework-class-map.md +243 -0
  98. package/skills/ue-input-system/SKILL.md +394 -0
  99. package/skills/ue-input-system/references/cpp-setup.md +131 -0
  100. package/skills/ue-input-system/references/enhanced-input-workflow.md +117 -0
  101. package/skills/ue-input-system/references/input-action-reference.md +731 -0
  102. package/skills/ue-mass-entity/SKILL.md +476 -0
  103. package/skills/ue-mass-entity/references/mass-entity-patterns.md +319 -0
  104. package/skills/ue-mass-entity/references/mass-fragment-reference.md +119 -0
  105. package/skills/ue-materials-rendering/SKILL.md +526 -0
  106. package/skills/ue-materials-rendering/references/material-parameter-reference.md +216 -0
  107. package/skills/ue-materials-rendering/references/post-process-settings.md +383 -0
  108. package/skills/ue-module-build-system/SKILL.md +487 -0
  109. package/skills/ue-module-build-system/references/build-cs-reference.md +418 -0
  110. package/skills/ue-module-build-system/references/common-build-errors.md +381 -0
  111. package/skills/ue-naming-conventions/SKILL.md +142 -0
  112. package/skills/ue-naming-conventions/references/asset-name-modifiers.md +233 -0
  113. package/skills/ue-naming-conventions/references/content-structure.md +83 -0
  114. package/skills/ue-networking-replication/SKILL.md +452 -0
  115. package/skills/ue-networking-replication/references/replication-patterns.md +526 -0
  116. package/skills/ue-networking-replication/references/rpc-decision-guide.md +393 -0
  117. package/skills/ue-niagara-effects/SKILL.md +531 -0
  118. package/skills/ue-niagara-effects/references/niagara-data-interfaces.md +491 -0
  119. package/skills/ue-niagara-effects/references/niagara-parameter-types.md +153 -0
  120. package/skills/ue-niagara-effects/references/niagara-workflow.md +115 -0
  121. package/skills/ue-packaging/SKILL.md +116 -0
  122. package/skills/ue-physics-collision/SKILL.md +423 -0
  123. package/skills/ue-physics-collision/references/collision-channel-setup.md +218 -0
  124. package/skills/ue-physics-collision/references/trace-patterns.md +499 -0
  125. package/skills/ue-procedural-generation/SKILL.md +505 -0
  126. package/skills/ue-procedural-generation/references/pcg-node-reference.md +381 -0
  127. package/skills/ue-procedural-generation/references/procedural-mesh-patterns.md +940 -0
  128. package/skills/ue-project-context/SKILL.md +305 -0
  129. package/skills/ue-sequencer-cinematics/SKILL.md +506 -0
  130. package/skills/ue-sequencer-cinematics/references/sequencer-patterns.md +629 -0
  131. package/skills/ue-serialization-savegames/SKILL.md +524 -0
  132. package/skills/ue-serialization-savegames/references/save-system-architecture.md +705 -0
  133. package/skills/ue-state-trees/SKILL.md +489 -0
  134. package/skills/ue-state-trees/references/state-tree-mass-integration.md +184 -0
  135. package/skills/ue-state-trees/references/state-tree-patterns.md +321 -0
  136. package/skills/ue-testing-debugging/SKILL.md +520 -0
  137. package/skills/ue-testing-debugging/references/automation-test-patterns.md +387 -0
  138. package/skills/ue-testing-debugging/references/profiling-commands.md +357 -0
  139. package/skills/ue-ui-umg-slate/SKILL.md +431 -0
  140. package/skills/ue-ui-umg-slate/references/common-ui-setup.md +484 -0
  141. package/skills/ue-ui-umg-slate/references/widget-types.md +487 -0
  142. package/skills/ue-world-level-streaming/SKILL.md +518 -0
  143. package/skills/ue-world-level-streaming/references/streaming-patterns.md +414 -0
  144. package/templates/gamedev/unreal-project-context.md +107 -0
@@ -0,0 +1,526 @@
1
+ ---
2
+ name: ue-materials-rendering
3
+ description: "Materials, shaders, dynamic material instances, post-process, render targets, Nanite, Lumen"
4
+ category: "gamedev"
5
+ argument-hint: "[material o effect]"
6
+ user-invocable: true
7
+ allowed-tools: Read, Glob, Grep, Bash, Write, Edit
8
+ ---
9
+
10
+ # UE Materials and Rendering
11
+
12
+ 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).
13
+
14
+ Ask before writing: this skill edits material assets, material functions and rendering code. Propose the change and get approval before using Write or Edit.
15
+
16
+ ---
17
+
18
+ ## Step 1: Read Project Context
19
+
20
+ Read `docs/unreal/project-context.md` before giving advice. From it, extract:
21
+
22
+ - **Engine version** — UE5.0–5.4 APIs differ (e.g., `SetNaniteOverride` added in 5.x; `CopyScalarAndVectorParameters` signature changed in 5.7)
23
+ - **Target platforms** — Mobile requires forward rendering; many post-process features are desktop-only
24
+ - **Rendering settings** — Nanite/Lumen enabled status affects which material features are safe
25
+ - **Module names** — needed for correct `#include` paths and `Build.cs` dependencies
26
+
27
+ If the context file is missing, ask for engine version and target platforms before proceeding.
28
+
29
+ ---
30
+
31
+ ## Step 2: Clarify the Rendering Need
32
+
33
+ Ask which area the user needs:
34
+
35
+ 1. **Dynamic Material Instances (MID)** — runtime parameter changes on mesh components
36
+ 2. **Material Parameter Collections** — global parameters shared across all materials
37
+ 3. **Post-Process** — bloom, exposure, color grading, DOF, AO via volumes or components
38
+ 4. **Render Targets** — scene capture, minimap, security camera, canvas drawing
39
+ 5. **Decals** — deferred decals spawned at runtime, fade, sort order
40
+ 6. **Rendering Pipeline / UE5 Features** — Nanite, Lumen, Virtual Shadow Maps, custom depth/stencil
41
+
42
+ Multiple areas can be combined.
43
+
44
+ ---
45
+
46
+ ## Core Patterns
47
+
48
+ ### 1. Dynamic Material Instances (MID)
49
+
50
+ #### Creation
51
+
52
+ **Pattern A — from UMaterialInterface (standalone, not tied to a component slot):**
53
+
54
+ ```cpp
55
+ // Header
56
+ UPROPERTY()
57
+ TObjectPtr<UMaterialInstanceDynamic> MyMID;
58
+
59
+ // Implementation — call once (BeginPlay or equivalent), cache the result
60
+ UMaterialInterface* BaseMat = LoadObject<UMaterialInterface>(
61
+ nullptr, TEXT("/Game/Materials/M_MyBase.M_MyBase"));
62
+
63
+ MyMID = UMaterialInstanceDynamic::Create(BaseMat, this);
64
+ ```
65
+
66
+ **Pattern B — via component slot (preferred for meshes):**
67
+
68
+ ```cpp
69
+ // UMeshComponent::CreateDynamicMaterialInstance creates a MID for the given
70
+ // element index and assigns it to the slot automatically.
71
+ // Signature: CreateDynamicMaterialInstance(int32 ElementIndex,
72
+ // UMaterialInterface* SourceMaterial = nullptr,
73
+ // FName OptionalName = NAME_None)
74
+
75
+ UMaterialInstanceDynamic* MID = MeshComponent->CreateDynamicMaterialInstance(
76
+ 0, // element index
77
+ nullptr, // nullptr = use the slot's current material as parent
78
+ TEXT("MyMID") // optional debug name
79
+ );
80
+ ```
81
+
82
+ Source: `MaterialInstanceDynamic.h`, `PrimitiveComponent.h`. Build.cs: `"Engine"`.
83
+
84
+ #### Setting Parameters
85
+
86
+ ```cpp
87
+ MyMID->SetScalarParameterValue(TEXT("Opacity"), 0.5f);
88
+ MyMID->SetVectorParameterValue(TEXT("BaseColor"), FLinearColor(1.f, 0.2f, 0.1f, 1.f));
89
+ MyMID->SetVectorParameterValue(TEXT("Offset"), FLinearColor(0.f, 0.f, 100.f, 0.f)); // XYZ via FLinearColor
90
+ MyMID->SetTextureParameterValue(TEXT("DamageMask"), MyTexture);
91
+ MyMID->SetTextureParameterValue(TEXT("SecurityFeed"), RenderTargetAsset); // RT as texture
92
+ ```
93
+
94
+ Full setter signatures from `MaterialInstanceDynamic.h`:
95
+ ```cpp
96
+ void SetScalarParameterValue(FName ParameterName, float Value);
97
+ void SetVectorParameterValue(FName ParameterName, FLinearColor Value); // Pass FLinearColor; no implicit conversion from FVector
98
+ void SetTextureParameterValue(FName ParameterName, UTexture* Value);
99
+ ```
100
+
101
+ #### High-Frequency Updates — Index-Based API
102
+
103
+ When setting dozens of parameters per frame (rare but valid), use index caching:
104
+
105
+ ```cpp
106
+ // In BeginPlay or initialization — call once per parameter name:
107
+ int32 OpacityIndex = -1;
108
+ MyMID->InitializeScalarParameterAndGetIndex(TEXT("Opacity"), 1.0f, OpacityIndex);
109
+
110
+ // In Tick — use index, no name lookup:
111
+ if (OpacityIndex >= 0)
112
+ {
113
+ MyMID->SetScalarParameterByIndex(OpacityIndex, NewOpacity);
114
+ }
115
+ ```
116
+
117
+ Index is invalidated if the parent material changes. Do not share indices across different MID instances.
118
+
119
+ #### MID Lifecycle and GC
120
+
121
+ MIDs are `UObject`s — they are garbage collected when unreferenced. To keep a MID alive:
122
+
123
+ ```cpp
124
+ // In your class header — must be UPROPERTY to prevent GC
125
+ UPROPERTY()
126
+ TObjectPtr<UMaterialInstanceDynamic> CachedMID;
127
+ ```
128
+
129
+ Never store MIDs in raw pointers or local variables across frames.
130
+
131
+ #### Additional MID Operations
132
+
133
+ ```cpp
134
+ // Lerp between two instances' scalar/vector params
135
+ MyMID->K2_InterpolateMaterialInstanceParams(InstanceA, InstanceB, Alpha);
136
+
137
+ // Assign Nanite-compatible override material (UE5)
138
+ MyMID->SetNaniteOverride(NaniteCompatibleMaterial);
139
+ ```
140
+
141
+ ---
142
+
143
+ ### 2. Material Parameter Collections
144
+
145
+ `UMaterialParameterCollection` is an asset holding scalar and vector parameters accessible from any material via `CollectionParameter` expression. One GPU buffer update propagates to all referencing materials. Source: `MaterialParameterCollection.h`, `MaterialParameterCollectionInstance.h`.
146
+
147
+ #### Setting Parameters at Runtime
148
+
149
+ ```cpp
150
+ // MyCollection is a UPROPERTY(EditAnywhere) pointing to the MPC asset.
151
+ UPROPERTY(EditAnywhere, Category="Rendering")
152
+ TObjectPtr<UMaterialParameterCollection> GlobalRenderingCollection;
153
+
154
+ // At runtime — get the per-world instance and set values:
155
+ void AMyActor::UpdateGlobalWeather(float RainIntensity, FLinearColor FogColor)
156
+ {
157
+ UMaterialParameterCollectionInstance* Instance =
158
+ GetWorld()->GetParameterCollectionInstance(GlobalRenderingCollection);
159
+
160
+ if (Instance)
161
+ {
162
+ Instance->SetScalarParameterValue(TEXT("RainIntensity"), RainIntensity);
163
+ Instance->SetVectorParameterValue(TEXT("FogColor"), FogColor);
164
+ }
165
+ }
166
+ ```
167
+
168
+ Both setters return `false` 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.
169
+
170
+ ---
171
+
172
+ ### 3. Post-Process Volumes
173
+
174
+ `APostProcessVolume` wraps `FPostProcessSettings` and controls how the camera is rendered when inside (or globally when `bUnbound = true`).
175
+
176
+ From `PostProcessVolume.h`:
177
+ ```cpp
178
+ struct FPostProcessSettings Settings; // The settings payload
179
+ float Priority; // Higher priority wins on overlap (undefined order when equal)
180
+ float BlendRadius; // World-space blend distance in cm (only when bUnbound = false)
181
+ float BlendWeight; // 0 = no effect, 1 = full effect
182
+ uint32 bEnabled:1;
183
+ uint32 bUnbound:1; // true = applies globally regardless of camera position
184
+ ```
185
+
186
+ #### Modifying a Post-Process Volume from C++
187
+
188
+ ```cpp
189
+ // Assume PostProcessVolume is assigned or found:
190
+ APostProcessVolume* PPV = /* find or spawn */;
191
+
192
+ // Enable and configure
193
+ PPV->bEnabled = true;
194
+ PPV->bUnbound = true; // global effect
195
+ PPV->BlendWeight = 1.0f;
196
+
197
+ // Bloom
198
+ PPV->Settings.bOverride_BloomIntensity = true;
199
+ PPV->Settings.BloomIntensity = 0.5f;
200
+
201
+ // Auto Exposure
202
+ PPV->Settings.bOverride_AutoExposureMinBrightness = true;
203
+ PPV->Settings.AutoExposureMinBrightness = 0.1f;
204
+ PPV->Settings.bOverride_AutoExposureMaxBrightness = true;
205
+ PPV->Settings.AutoExposureMaxBrightness = 2.0f;
206
+
207
+ // Depth of Field (Cinematic DOF)
208
+ PPV->Settings.bOverride_DepthOfFieldFstop = true;
209
+ PPV->Settings.DepthOfFieldFstop = 2.8f;
210
+ PPV->Settings.bOverride_DepthOfFieldFocalDistance = true;
211
+ PPV->Settings.DepthOfFieldFocalDistance = 300.0f; // cm
212
+
213
+ // Ambient Occlusion
214
+ PPV->Settings.bOverride_AmbientOcclusionIntensity = true;
215
+ PPV->Settings.AmbientOcclusionIntensity = 0.5f;
216
+
217
+ // Vignette
218
+ PPV->Settings.bOverride_VignetteIntensity = true;
219
+ PPV->Settings.VignetteIntensity = 0.4f;
220
+
221
+ // Color Grading
222
+ PPV->Settings.bOverride_ColorSaturation = true;
223
+ PPV->Settings.ColorSaturation = FVector4(1.2f, 1.0f, 0.8f, 1.0f); // per-channel RGBA
224
+ PPV->Settings.bOverride_FilmSlope = true;
225
+ PPV->Settings.FilmSlope = 0.88f; // 0–1 (default 0.88)
226
+ ```
227
+
228
+ Every field in `FPostProcessSettings` has a corresponding `bOverride_*` bool that must be set to `true` for the value to take effect. See `references/post-process-settings.md` for a full field reference.
229
+
230
+ #### Post-Process Materials (Blendables)
231
+
232
+ Material Domain must be "Post Process". Add via:
233
+ ```cpp
234
+ PPV->AddOrUpdateBlendable(PostProcessMaterial, 1.0f); // weight 0.0–1.0
235
+ ```
236
+
237
+ #### UPostProcessComponent (Actor-Owned)
238
+
239
+ ```cpp
240
+ // Constructor
241
+ PostProcessComp = CreateDefaultSubobject<UPostProcessComponent>(TEXT("PostProcess"));
242
+ PostProcessComp->bUnbound = true;
243
+ PostProcessComp->Priority = 5.0f;
244
+
245
+ // Runtime
246
+ PostProcessComp->Settings.bOverride_BloomIntensity = true;
247
+ PostProcessComp->Settings.BloomIntensity = 1.5f;
248
+ ```
249
+
250
+ Includes: `"Components/PostProcessComponent.h"`, `"Engine/PostProcessVolume.h"`, `"Engine/Scene.h"`.
251
+
252
+ ---
253
+
254
+ ### 4. Render Targets
255
+
256
+ #### Creating a Render Target in C++
257
+
258
+ ```cpp
259
+ #include "Engine/TextureRenderTarget2D.h"
260
+ #include "Kismet/KismetRenderingLibrary.h"
261
+
262
+ // Option A — via UKismetRenderingLibrary (handles resource init automatically)
263
+ UTextureRenderTarget2D* RT = UKismetRenderingLibrary::CreateRenderTarget2D(
264
+ this, // WorldContextObject
265
+ 512, // Width
266
+ 512, // Height
267
+ RTF_RGBA16f, // Format (see ETextureRenderTargetFormat)
268
+ FLinearColor::Black,
269
+ false // bAutoGenerateMipMaps
270
+ );
271
+
272
+ // Option B — manual creation
273
+ UTextureRenderTarget2D* RT = NewObject<UTextureRenderTarget2D>(this);
274
+ RT->InitCustomFormat(512, 512, PF_FloatRGBA, /*bInForceLinearGamma=*/true);
275
+ RT->UpdateResourceImmediate(/*bClearRenderTarget=*/true);
276
+ ```
277
+
278
+ `ETextureRenderTargetFormat` values from `TextureRenderTarget2D.h`:
279
+ | Format | Channels | Bits/Channel | Use Case |
280
+ |--------|----------|-------------|----------|
281
+ | `RTF_RGBA8` | RGBA | 8 fixed | LDR color, UI |
282
+ | `RTF_RGBA8_SRGB` | RGBA | 8 fixed | sRGB color |
283
+ | `RTF_RGBA16f` | RGBA | 16 float | HDR color (default) |
284
+ | `RTF_RGBA32f` | RGBA | 32 float | High precision data |
285
+ | `RTF_R16f` | R | 16 float | Single channel data |
286
+ | `RTF_RGB10A2` | RGB+A | 10+2 bit | Display output |
287
+
288
+ #### Scene Capture (Security Camera / Minimap)
289
+
290
+ ```cpp
291
+ #include "Components/SceneCaptureComponent2D.h"
292
+
293
+ // In actor constructor
294
+ SceneCapture = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("SceneCapture"));
295
+ SceneCapture->SetupAttachment(RootComponent);
296
+ SceneCapture->FOVAngle = 90.f;
297
+ SceneCapture->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR; // or SCS_SceneColorHDR
298
+ SceneCapture->bCaptureEveryFrame = true; // continuous update
299
+
300
+ // Assign a render target asset or a runtime-created one
301
+ SceneCapture->TextureTarget = MyRenderTargetAsset;
302
+
303
+ // Limit what's captured for performance
304
+ SceneCapture->ShowFlags.SetAtmosphere(false);
305
+ SceneCapture->ShowFlags.SetFog(false);
306
+ ```
307
+
308
+ #### Drawing a Material to a Render Target
309
+
310
+ ```cpp
311
+ // Renders a full-screen quad with Material applied to TextureTarget.
312
+ // This is expensive (sets render target each call); use canvas API for batching.
313
+ UKismetRenderingLibrary::DrawMaterialToRenderTarget(
314
+ this, // WorldContextObject
315
+ RT, // UTextureRenderTarget2D*
316
+ MyMaterial // UMaterialInterface*
317
+ );
318
+ ```
319
+
320
+ #### Canvas Drawing (Batched)
321
+
322
+ ```cpp
323
+ UCanvas* Canvas;
324
+ FVector2D CanvasSize;
325
+ FDrawToRenderTargetContext Context;
326
+
327
+ UKismetRenderingLibrary::BeginDrawCanvasToRenderTarget(this, RT, Canvas, CanvasSize, Context);
328
+
329
+ // Draw primitives to Canvas here...
330
+ Canvas->K2_DrawMaterial(MyMaterial, FVector2D(0, 0), CanvasSize, FVector2D(0, 0), FVector2D(1, 1));
331
+
332
+ UKismetRenderingLibrary::EndDrawCanvasToRenderTarget(this, Context);
333
+ ```
334
+
335
+ **`UCanvasRenderTarget2D`** — subclass of `UTextureRenderTarget2D` with a built-in `OnCanvasRenderTargetUpdate` delegate. Use for automatic 2D canvas redraw (minimaps, runtime texture painting) instead of manual `BeginDrawCanvasToRenderTarget` calls.
336
+
337
+ #### Reading Pixels (GPU Stall — Offline Only)
338
+
339
+ ```cpp
340
+ // WARNING: stalls GPU pipeline. Editor tools / screenshot only, never per-frame.
341
+ FColor Pixel = UKismetRenderingLibrary::ReadRenderTargetPixel(this, RT, X, Y);
342
+ TArray<FColor> Pixels;
343
+ UKismetRenderingLibrary::ReadRenderTarget(this, RT, Pixels); // whole RT, 8-bit sRGB
344
+ FLinearColor Raw = UKismetRenderingLibrary::ReadRenderTargetRawPixel(this, RT, X, Y);
345
+ ```
346
+
347
+ ---
348
+
349
+ ### 5. Decals
350
+
351
+ `UDecalComponent` projects a material onto surfaces. Key API from `DecalComponent.h`:
352
+
353
+ ```cpp
354
+ void SetDecalMaterial(UMaterialInterface* NewDecalMaterial);
355
+ UMaterialInstanceDynamic* CreateDynamicMaterialInstance(); // MID on the decal
356
+ void SetFadeOut(float StartDelay, float Duration, bool DestroyOwnerAfterFade = true);
357
+ void SetFadeIn(float StartDelay, float Duration);
358
+ void SetSortOrder(int32 Value); // higher = draws on top
359
+ void SetLifeSpan(float LifeSpan);
360
+ FVector DecalSize; // local-space extent (not component scale)
361
+ ```
362
+
363
+ #### Spawning Decals at Runtime
364
+
365
+ ```cpp
366
+ // 0.0f lifespan = persistent; >0.0f = auto-destroy after N seconds
367
+ UDecalComponent* Decal = UGameplayStatics::SpawnDecalAtLocation(
368
+ this, DecalMaterial, FVector(200.f), HitLocation, HitNormal.Rotation(), 0.0f);
369
+
370
+ // Dynamic parameters on the decal
371
+ UMaterialInstanceDynamic* DecalMID = Decal->CreateDynamicMaterialInstance();
372
+ DecalMID->SetScalarParameterValue(TEXT("Opacity"), 0.8f);
373
+ ```
374
+
375
+ #### DBuffer vs Non-DBuffer Decals
376
+
377
+ - **DBuffer** (Translucent + DBuffer enabled): writes before lighting, affects diffuse/normals/roughness. Enable via `Project Settings > Rendering > DBuffer Decals`.
378
+ - **Non-DBuffer**: rendered after lighting, emissive/opacity only; cheaper but limited.
379
+
380
+ For level-placed decals, use `ADecalActor` (a wrapper around `UDecalComponent`). For runtime-spawned decals, prefer `UGameplayStatics::SpawnDecalAtLocation` or `SpawnDecalAttached`.
381
+
382
+ ---
383
+
384
+ ### 6. Nanite and Lumen (UE5)
385
+
386
+ #### Nanite
387
+
388
+ Nanite is UE5's virtualized geometry system. Material compatibility rules:
389
+
390
+ | Feature | Nanite Compatible |
391
+ |---------|------------------|
392
+ | Opaque materials | Yes |
393
+ | Two-sided materials | Yes |
394
+ | Masked materials | Yes (with `r.Nanite.AllowMaskedMaterials=1`) |
395
+ | Translucent materials | No — falls back to non-Nanite path |
396
+ | World Position Offset (WPO) | Supported in UE 5.1+ (`bEvaluateWorldPositionOffset` on mesh) |
397
+ | Pixel Depth Offset | No |
398
+ | Custom vertex normals via shader | Limited |
399
+
400
+ Check at runtime:
401
+ ```cpp
402
+ // Check if a static mesh component is using Nanite (IsNaniteEnabled is on UStaticMesh, not on the component)
403
+ bool bIsNanite = StaticMeshComponent->GetStaticMesh() && StaticMeshComponent->GetStaticMesh()->IsNaniteEnabled();
404
+ ```
405
+
406
+ Override material for Nanite path:
407
+ ```cpp
408
+ MyMID->SetNaniteOverride(NaniteCompatibleMaterial);
409
+ ```
410
+
411
+ #### Lumen
412
+
413
+ 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:
414
+
415
+ ```cpp
416
+ PPV->Settings.bOverride_LumenReflectionQuality = true;
417
+ PPV->Settings.LumenReflectionQuality = 1.0f; // 0–4
418
+
419
+ PPV->Settings.bOverride_LumenSceneDetail = true;
420
+ PPV->Settings.LumenSceneDetail = 1.0f; // surface cache resolution multiplier
421
+
422
+ PPV->Settings.bOverride_LumenSceneLightingQuality = true;
423
+ PPV->Settings.LumenSceneLightingQuality = 1.0f;
424
+ ```
425
+
426
+ Performance: `r.Lumen.SurfaceCache.UpdateDownsampleFactor` controls cache update rate.
427
+
428
+ #### Deferred vs Forward Rendering
429
+
430
+ **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 Shading`.
431
+
432
+ **Scalability**: Use `Scalability::SetQualityLevels()` (in `Scalability.h`) or console commands such as `sg.PostProcessQuality 0-3` to adjust rendering quality at runtime. Configure presets in `BaseScalability.ini`.
433
+
434
+ #### Virtual Shadow Maps (VSM)
435
+
436
+ - WPO materials: enable "Evaluate World Position Offset" in the material's Details panel (material editor setting, not a C++ property) for correct VSM shadows.
437
+ - Masked materials: opacity masks respected correctly.
438
+ - Decals do not cast VSM shadows.
439
+
440
+ #### Custom Depth / Stencil (Outlines and Effects)
441
+
442
+ ```cpp
443
+ MeshComponent->SetRenderCustomDepth(true);
444
+ MeshComponent->SetCustomDepthStencilValue(1); // 0–255
445
+ // Sample CustomDepth / CustomStencil nodes in a post-process material for outlines, X-ray, highlight effects.
446
+ ```
447
+
448
+ Enable: `Project Settings > Rendering > Custom Depth-Stencil Pass > Enabled with Stencil`.
449
+
450
+ ---
451
+
452
+ ## Common Mistakes and Anti-Patterns
453
+
454
+ **Creating MIDs every frame** — Each `CreateDynamicMaterialInstance` call allocates a new GPU resource. Create once in `BeginPlay`, cache, update in `Tick`:
455
+
456
+ ```cpp
457
+ // BeginPlay
458
+ CachedMID = MeshComponent->CreateDynamicMaterialInstance(0);
459
+
460
+ // Tick
461
+ if (CachedMID) { CachedMID->SetScalarParameterValue(TEXT("Time"), GetWorld()->TimeSeconds); }
462
+ ```
463
+
464
+ **Not caching MID as UPROPERTY** — Raw `UMaterialInstanceDynamic*` is invisible to GC and collected on the next GC pass. Use `UPROPERTY() TObjectPtr<UMaterialInstanceDynamic> CachedMID;`.
465
+
466
+ **Wrong parameter names** — Names are case-sensitive exact matches. `"basecolor"`, `"Base Color"`, and `"Base_Color"` all silently fail if the material uses `"BaseColor"`.
467
+
468
+ **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 `bMainViewResolution` on `USceneCaptureComponent2D`.
469
+
470
+ **Reading render target pixels per frame** — `ReadRenderTargetPixel` stalls the GPU pipeline. Never call per frame. Use `FRHIGPUTextureReadback` for async non-stalling reads.
471
+
472
+ **MIDs on replicated actors** — MIDs are client-local. Do not replicate the MID pointer. Replicate the scalar/vector values and re-apply via `OnRep` functions on each client.
473
+
474
+ **Post-process bOverride not set** — Every `FPostProcessSettings` field requires its paired `bOverride_*` bool set to `true`. Setting a value without the override is a silent no-op.
475
+
476
+ **Nanite translucency fallback** — Translucent materials on Nanite meshes revert the full mesh to non-Nanite rendering. Split into separate opaque and translucent components.
477
+
478
+ ---
479
+
480
+ ## Required Build.cs Dependencies
481
+
482
+ ```csharp
483
+ PublicDependencyModuleNames.AddRange(new string[]
484
+ {
485
+ "Engine", // Materials, render targets, UTextureRenderTarget2D
486
+ "RenderCore", // Low-level render utilities
487
+ "RHI", // RHI types (EPixelFormat, etc.)
488
+ });
489
+
490
+ // For UKismetRenderingLibrary:
491
+ // Already available via "Engine" — no separate module needed.
492
+ ```
493
+
494
+ ---
495
+
496
+ ## Related Skills
497
+
498
+ - `/ue-cpp-foundations` — UObject management, UPROPERTY, TObjectPtr, garbage collection
499
+ - `/ue-actor-component-architecture` — setting up components (UDecalComponent, USceneCaptureComponent2D, UPostProcessComponent)
500
+ - `/ue-niagara-effects` — particle materials use MIDs; parameter passing into Niagara from C++
501
+ - `/ue-project-context` — engine version, target platforms, rendering feature flags
502
+ - `/ue-naming-conventions` — asset prefixes and Content folder layout for these assets
503
+
504
+ ## Reference Files
505
+
506
+ - `references/material-parameter-reference.md` — material parameter types and their C++/Blueprint setters
507
+
508
+ ---
509
+
510
+ ## Checklist
511
+
512
+ Validate before considering the work done:
513
+
514
+ - [ ] Material instances are used for variation instead of duplicated materials
515
+ - [ ] Instruction count and texture samplers stay within the platform budget
516
+ - [ ] Dynamic material instances are created once and cached, not per frame
517
+ - [ ] Conventions in `docs/unreal/project-context.md` were read and followed
518
+ - [ ] The Common Mistakes section of this skill was reviewed against the change
519
+
520
+ **PASS** — every item holds. **CONCERNS** — the work stands but at least one item is unresolved and worth flagging to the user. **FAIL** — an item is violated in a way that breaks correctness, replication or the frame budget; fix it before handing the work over.
521
+
522
+ ## Next Steps
523
+
524
+ - `/perf-profile` — measure the GPU cost of the change
525
+ - `/code-review` — architectural and quality review of the change
526
+ - `/commit` — conventional commit once the change is verified