# 144 — Capture Surface Master Material (`M_CaptureSurface_Master`) ## Purpose Single master material for ALL capture surface modes (mirror, portal, monitor, horror, fake window). All features are parameter-driven — inactive features have zero rendering cost. ## Dependencies - **Requires:** `MPC_CaptureSurface` (145) for global scalar parameters - **Required By:** All capture surface actors (139-143) via their material instances - **Engine/Plugin Requirements:** None ## Class Info | Property | Value | |----------|-------| | **Material Domain** | Surface | | **Blend Mode** | Opaque | | **Shading Model** | Unlit | | **Asset Path** | `Content/Framework/Capture/M_CaptureSurface_Master.uasset` | | **C++ Status** | N/A (Material asset) | | **Asset to Create** | Material in UE5 editor | ## 1. Material Layer Stack (9 Layers) ### Layer 0: Render Target Sample ``` Texture Sample (parameter: "CaptureTexture", TextureRenderTarget2D) ├─ UVs: If Mirror mode → UV * (1, -1) + (0, 1) [flip vertically for mirror reflection] │ If Portal/Monitor mode → straight UVs └─ Output → Base Color input of Layer 1 ``` **Switch:** `StaticSwitchParameter: bIsMirror` (true = UV flip, false = straight) ### Layer 1: Condensation UV Distortion ``` Condensation Normal Map (Texture Sample, parameter: "CondensationNormal") ├─ UVs: Panner (slow drift, driven by Time * CondensationFlow MPC param) ├─ Normal strength: DistortionAmplitude MPC param └─ Output: Modified UVs for Layer 0's texture sample ``` **Note:** Layer 1 modifies the UVs of Layer 0, not its color. ### Layer 2: Fresnel Edge Fade ``` Fresnel node (Exponent = 2.0, BaseReflectFraction = 0.0) ├─ Dot product: CameraVector · VertexNormal └─ Output: Opacity mask for edge darkening (subtle vignette) ``` ### Layer 3: Dirt / Scratch Multiply ``` Dirt Mask (Texture Sample, parameter: "DirtMask") ├─ Multiply with DirtOpacity MPC param ├─ Lerp: Clean RT ←→ Dirty RT using DirtOpacity └─ Tint: Mix with SurfaceAge MPC param (yellowing/oxidation) ``` ### Layer 4: Steam / Fog Lerp ``` Animated Noise (Procedural noise, tiling, scrolling via Time) ├─ SteamIntensity MPC param → controls noise opacity ├─ Lerp: Clear view ←→ Fogged view └─ Output: blended base color ``` ### Layer 5: Steam Emissive Glow ``` Steam mask (same noise as Layer 4, separate brightness) ├─ Multiply by SteamEmissiveIntensity MPC param ├─ Color: Soft warm white (backlit fog look) └─ Output → Emissive Color pin ``` ### Layer 6: Text Reveal Mask ``` Text Mask (Texture Sample, parameter: "TextRevealMask") ├─ Reveal progress: TextRevealProgress MPC param (0→1 wipe) ├─ Blend with steam carrier (appears as text IN the steam) └─ Output: emissive text overlay (optional) or color replacement ``` ### Layer 7: Mirror Darkness Multiply ``` MirrorDarkness MPC param (0.0 = normal, 1.0 = black) ├─ Multiply base color by (1.0 - MirrorDarkness) └─ Output: darkened reflection ``` ### Layer 8: Wrong Reflection Crossfade ``` Second RT Input (parameter: "DelayedCaptureTexture" OR separate RT) ├─ Lerp: Current_RT ←→ Delayed/Wrong_RT using WrongReflectionBlend MPC param └─ Final Output → Emissive Color (Unlit material) ``` ## 2. Material Parameters (Exposed) ### Texture Parameters | Name | Type | Default | Description | |------|------|---------|-------------| | `CaptureTexture` | TextureRenderTarget2D | — | Live capture render target | | `CondensationNormal` | Texture2D | T_DefaultNormal | Condensation flow normal map | | `DirtMask` | Texture2D | T_DefaultWhite | Dirt/scratch mask texture | | `TextRevealMask` | Texture2D | T_DefaultBlack | Steam text mask | ### Scalar Parameters (Driven by MPC) | Name | Default | Description | |------|---------|-------------| | `SteamIntensity` | 0.0 | Steam fog opacity | | `DirtOpacity` | 0.0 | Dirt/scratch opacity | | `CondensationFlow` | 0.0 | Condensation normal scroll speed | | `DistortionAmplitude` | 0.0 | UV distortion magnitude | | `MirrorDarkness` | 0.0 | Mirror darkening | | `WrongReflectionBlend` | 0.0 | Wrong reflection crossfade | | `TextRevealProgress` | 0.0 | Steam text reveal progress | | `SteamEmissiveIntensity` | 0.0 | Steam glow brightness | | `DelayedReflectionBlend` | 0.0 | Delayed frame blend | | `SurfaceAge` | 0.0 | Oxidation/yellowing tint | ### Static Switch Parameters | Name | Default | Description | |------|---------|-------------| | `bIsMirror` | true | Enable vertical UV flip for mirror mode | | `bEnableHorrorLayers` | false | Enable Layers 6-8 (text reveal, darkness, wrong reflection) | ## 3. MPC Binding All 10 scalar parameters are NOT material-instance parameters — they are driven by `MPC_CaptureSurface` (145) at runtime. The C++ component calls `PushMPCParameters()` each frame to update these values globally. In the material: use `Collection Parameter` nodes referencing `MPC_CaptureSurface` for each of the 10 scalars listed above. ## 4. Manual Implementation Guide ### 4.1 Create Master Material 1. Create Material: Name = `M_CaptureSurface_Master` 2. Set Material Domain = Surface, Blend Mode = Opaque, Shading Model = Unlit 3. Build Layer 0: `Texture Sample Parameter` node named "CaptureTexture" 4. Add Static Switch: "bIsMirror" → UV flip branch (Custom UV × (1,-1) + (0,1)) 5. Build Layers 1-8 as described above 6. Connect final color → Emissive Color (Unlit output) ### 4.2 MPC Integration 1. Create `Collection Parameter` nodes for each of the 10 MPC scalars 2. Set the Collection asset to `MPC_CaptureSurface` 3. Set the Parameter Name to match each MPC entry (e.g., "SteamIntensity") ### 4.3 Performance - Use `StaticSwitchParameter` for `bEnableHorrorLayers` — when false, Layers 6-8 are compiled out (zero cost) - Condensation normal Layer 1 is cheap (one texture sample + panner) - All MPC reads are free (constant buffer lookup) ## 5. Build Checklist - [ ] Create M_CaptureSurface_Master material in UE5 editor - [ ] Set Domain=Surface, Blend=Opaque, Shading=Unlit - [ ] Build all 9 layers (verify material compiles) - [ ] Add 10 MPC Collection Parameter nodes - [ ] Add bIsMirror and bEnableHorrorLayers static switches - [ ] Compile material — no errors - [ ] Create MI instances and verify parameter override works