# Seamcraft Screen space render kit for Unreal Engine, written into the GBuffer right after the base pass, so the engine's lights, shadows, Lumen and reflections see it. No material to change, no engine patch, no Runtime Virtual Texture. - **Mesh blending**: where a rock, a post or a wall meets the ground, its foot takes the ground's texture, mirrored across the seam so the detail stays sharp. - **Bevel**: hard edges of an actor get rounded on screen, without bleeding into the floor or the next prop. - **Coverage**: snow, wetness, moss or dust over everything that faces up, kept off whatever is under a roof. Works with Nanite, Substrate (Blendable GBuffer), split screen and stereo (tested with emulated stereo, not on a headset), on UE 5.6, 5.7 and 5.8, Windows (DirectX 12). Linux builds but has not been run yet. GPU cost at 1080p on an RTX 2070 Super, test scene of shapes on a ground plane (every shape blends and has bevel on): | | Total | Of which | |---|---|---| | Mesh blending + bevel, wide view | 0.34 ms | tiles 0.09, bevel 0.07, blend 0.13, copies 0.05 | | Mesh blending + bevel, close up | 0.40 ms | bevel 0.08, blend 0.17 | | Mesh blending only (bevel off) | 0.26 ms | | | Lit color mode (fallback), wide view | 0.21 ms | | | Snow cover, wide view | 0.18 ms | on top of the above | | Height capture for the cover | about 0.8 ms | only when the camera has moved 12 m | | Custom depth pass (engine) | 0.01 ms | 0.3 ms with Nanite meshes | ## Example map `Seamcraft Content/Examples/SeamcraftExample` has one station for each part of this manual, each with a label saying what to look at. From the player start: mesh blending on the right (shapes on a textured ground, the three widths, two shapes that touch, a wall with an unmarked window, a sphere without the component to compare), bevel in the middle, and a snow Coverage Volume on the left (a roof that keeps the snow off, a lake that freezes, a sphere with Receives Decals off and a box with Cover off). The cover is drawn while the camera is inside its box: walk in, then change the volume's Preset, Amount or Water Cover in the Details panel. Every actor there has the same Seamcraft component you would add to yours. ## Setup 1. Enable the plugin and restart the editor. 2. Project Settings > Rendering > Postprocessing > **Custom Depth-Stencil Pass: Enabled with Stencil**. If it is lower, Seamcraft turns it on as soon as a level has a Seamcraft component or Coverage Volume, and says so in the log; set it in the project to keep it. 3. Add a **Seamcraft** component to the actors: - the ground, the terrain, a floor: **Role: Receiver**. It never changes; others blend into it; - rocks, posts, walls, props: **Role: Blend** (the default). When the editor opens, Seamcraft checks the project: if Custom Depth-Stencil Pass is not Enabled with Stencil, or custom depth is drawn after the base pass (DBuffer Decals off), a notification says what is missing and **Fix project settings** sets it (Enabled with Stencil, and `r.CustomDepth.Order 0`). **Don't ask again** turns the check off for the project. That is all for mesh blending. For the cover, drop a **Seamcraft Coverage Volume** in the level (see Coverage). The component works on any actor, Blueprint or placed, landscape included. It gives every primitive of the actor a custom stencil value. Blending actors that touch get different IDs, so two rocks blend into each other too, and the ID is picked again when the actor moves more than 5 cm. ## Mesh blending Each pixel of a blending mesh looks for the nearest surface with another ID that touches it in 3D, finds the seam between the two and takes the other surface's material from the mirrored point across the seam. A height blend decides which texture climbs first (the brighter one, like a height lerp in a material), and world space noise bends the blend line so it is not a straight band. Into a receiver the mesh turns fully into the ground at the seam; two blending meshes meet halfway. **Width** on the component sets how far up the mesh it goes: Narrow, Normal or Wide, half, once or twice `r.Seamcraft.Width` (40 cm by default, so 20, 40 or 80 cm). Meshes without the component stop the search: a window in a wall that blends does not get the wall smeared over it. There are two modes (`r.Seamcraft.Mode`): - **1, GBuffer (default).** Blends base color, metallic, specular, roughness and AO before lighting, so light, shadow and GI fall on the blended edge as they would on the ground. The rock's side in shadow stays in shadow. The normal is left out by default (`r.Seamcraft.GBufferChannels`): the ground's normal on the foot of a rock faces the open sky and lit a pale band. - **0, lit color.** Blends the final lit color after lighting. Seamcraft falls back to it by itself with Forward Shading, Substrate's Adaptive GBuffer, or when custom depth is drawn after the base pass (DBuffer decals off and `r.CustomDepth.Order` not 0). ## Bevel Tick **Bevel** on the component. Its hard edges get the average of the normals around them within `r.Seamcraft.Bevel.Radius` (2 cm), so light catches a rounded corner. Only pixels of the same actor count, so the bevel never reaches into the floor or the next prop. Close to the camera it stops growing at `r.Seamcraft.Bevel.MaxPixels` (12 pixels) instead of costing more. GBuffer mode only. ## Coverage Place a **Seamcraft Coverage Volume**. It covers everything that faces up with the look of its **Preset**: | Preset | Look | Puddles | Water Cover | |---|---|---|---| | Snow | white with soft lumps and a cold blue in some patches, crisp noisy edge | 0 | 1 (lakes freeze over) | | Wet | darker and glossy, puddles on flat ground | 0.5 | 0 | | Moss | dark olive going yellow in patches, settling in gaps and cracks first, with a fine fuzz | 0 | 0 | | Dust | brown going grey, gathered in the low parts, the surface's grain still showing | 0 | 0 | | Custom | keeps whatever you set | | | The preset fills the values below it; change any of them after picking Custom. - **Amount** (0 to 2): 0 nothing, 1 every surface that faces up, above 1 reaches steeper slopes. It can be animated from Sequencer or Blueprint, so snow can build up during a level. - **Color**, **Color Amount**, **Roughness**, **Roughness Amount**, **Specular**: the material the surface turns into. - **Normal Flatten**: how far the normal turns up under the cover, hiding the detail below it. - **Slope Start** and **Slope End**: up component of the normal where the cover starts and where it is full (0 is a wall, 1 a floor). - **Noise Amount** and **Noise Scale**: how patchy the cover is and how big the patches are, in cm. - **Sharpness**: 1 is a soft fade from bare to covered; higher gives the cover an edge. - **Puddles**: flat spots turn into still water. - **Detail**, what keeps the cover from looking like flat paint: - **Second Color** and **Color Variation**: the cover drifts to a second color in broad patches. - **Detail Keep**: how much of the surface's own texture (its light and dark parts) shows through the cover's color. - **Cavity**: the cover grows first in the darker parts of the surface (gaps between planks, cracks) and leaves the bright ones. - **Bumps** and **Bump Scale**: lumps in the cover's surface, their size in cm. - **Unbound** covers the whole level; off, only the box, faded over **Edge Fade** at its sides. Where volumes overlap, the highest **Priority** around the camera wins. **Nothing under a roof.** With **Occlusion From Above** on (default), a depth capture looks straight down at a 60 m square around the camera (in front of it, where most of the view is) and the cover stays off whatever has something above it: under roofs, bridges, porches. It captures again when the camera has moved a fifth of the square (12 m). **Occlusion Bias** lets the cover reach a little below the top surface (a ledge right under a beam), and **Occlusion Fade** softens the line. Trees and grass painted with the foliage tool do not block it by default (**Foliage Blocks Cover**), or a forest floor would be bare under every canopy. Sky spheres around the camera are left out of the capture. In split screen each player gets a capture of their own (up to four), so a roof keeps the snow off wherever each one is. Call **Refresh Occlusion** after something big moves under the cover. The capture follows the editor viewport too, so the cover shows while you build the level. **Water.** While the game runs, the volume finds flat, wide meshes whose material has "Water" in its name and applies **Water Cover** to them: 1 under snow, so a lake freezes over, 0 for the other presets, so water stays water. In the editor viewport it does not look for water (that would change the meshes' settings and be saved into the level), so a lake there takes the cover like the ground. Turn **Find Water** off to leave water alone, or put a Seamcraft component with Cover off on it. Water from the Water plugin (Single Layer Water) is never covered. **Keeping things clean.** Primitives with **Receives Decals** off are never covered (characters, glass), and so is any actor whose Seamcraft component has **Cover** off. The cover is written before the mesh blending, so blended edges carry it across seams. **Footprints and tracks.** Characters and vehicles leave marks in the cover, with no material change and no displacement: - Attach a **Seamcraft Trail** component to each foot socket of a character, or to each wheel of a vehicle. Each frame it is within **Ground Distance** (15 cm) of the ground it stamps an ellipse there, **Length** by **Width** cm, pointing where the owner faces. - Or call **Add Seamcraft Trail Stamp** (Location on the ground, Direction, Length, Width, Strength) from an animation notify on each footstep, from a landing, from anything. - The volume decides how marks look: **Trail Depth** (cm, the light carves the edge of the print), **Trail Clear** (how much of the cover a print clears: dust swept off, the ground showing through moss), **Trail Darken** (packed snow at the bottom of a print) and **Trail Refill** (seconds for fresh snow or settling dust to fill a print back in; 0 = it stays). Each preset sets its own: deep prints in snow, dark ones in wet ground, swept dust. - Marks live in a map 40 m across that follows the camera, about 2 cm a texel; the marks it leaves behind are dropped. It is updated only when there are new marks, when it moves, or twice a second to refill (0.075 ms those frames, nothing the others). - In development builds, `Seamcraft.TrailWalk` stamps a line of footprints across the ground the camera looks at, and `Seamcraft.TrailWalk Tracks` two wheel tracks. The example map has a row of Trail components in its snow. Prints are drawn, not dug: up close and at grazing angles they read as shading, not as holes. ## Settings **Project Settings > Plugins > Seamcraft** has the settings that change the look for the whole project: on/off, blend before lighting, the compact stencil, the blend width, noise and height contrast, what the blend takes from the other surface, the bevel's radius and the cover. They apply right away in the editor and are saved in `DefaultEngine.ini`; Seamcraft applies them when a packaged game starts too. What costs GPU time follows the engine's **Post Processing scalability** (`sg.PostProcessQuality`), so a game's graphics menu drives it. Epic is the defaults measured above: | Level | Search steps | Search radius | Bevel | Cost, wide view / close up | |---|---|---|---|---| | Low | 3 | 24 px | off | 0.17 / 0.18 ms | | Medium | 4 | 40 px | on, up to 8 px | 0.30 / 0.33 ms | | High, Epic | 6 | 64 px | on, up to 12 px | 0.33 / 0.39 ms | | Cinematic | 8 | 96 px | on, up to 16 px | 0.35 / 0.46 ms | A value set in an ini under `[SystemSettings]` or in the console wins over the level. Each setting is also a console variable: ## Console variables All of them can go in `DefaultEngine.ini` under `[SystemSettings]`, or change at runtime. | Variable | Default | What it does | |---|---|---| | `r.Seamcraft.Enable` | 1 | Mesh blending and bevel on or off. | | `r.Seamcraft.Mode` | 1 | 1 = blend in the GBuffer before lighting, 0 = blend the lit color (see Mesh blending). | | `r.Seamcraft.Width` | 40 | How far the Normal width reaches from the seam, in cm. Narrow is half, Wide twice. | | `r.Seamcraft.Steps` | 6 | Steps each of the 8 search rays takes out to the width. Fewer is cheaper on close ups and may miss thin gaps. | | `r.Seamcraft.MaxRadius` | 64 | Largest search radius in pixels. Close to the camera the blend gets narrower than Width instead of costing more. | | `r.Seamcraft.Noise` | 0.4 | How much the blend line wanders, as a share of the width. 0 = straight. | | `r.Seamcraft.NoiseScale` | 12 | Size of the wander, in cm. | | `r.Seamcraft.HeightContrast` | 0.15 | Height blend: how far the brighter texture climbs first. 0 = plain fade; 0.6 is soft. With 0.4 a light rock keeps almost all of its own texture. | | `r.Seamcraft.GBufferChannels` | 13 | What the GBuffer blend takes from the other surface, as bits: 1 base color, 2 normal, 4 metallic/specular/roughness, 8 AO. | | `r.Seamcraft.Bevel` | 1 | Bevel on actors that ask for it. | | `r.Seamcraft.Bevel.Radius` | 2 | How round the edges are, in cm. | | `r.Seamcraft.Bevel.MaxPixels` | 12 | Largest bevel on screen, in pixels. | | `r.Seamcraft.Coverage` | 1 | Draws the Coverage Volume's cover. | | `r.Seamcraft.StencilLayout` | 0 | 0 = the whole custom stencil value is Seamcraft's; 1 = only 128 to 255, leaving 1 to 127 to other systems (see Custom stencil). | | `r.Seamcraft.Debug` | 0 | 1 = pixels the blend searched in blue, blend weight in red. 2 = cover occlusion: green sees the sky, red is covered from above. | In development builds (not Shipping), `Seamcraft.Cover Snow` (or Wet, Moss, Dust, Off, with an optional amount) in the console covers any level with an unbound volume, to try the presets. `Seamcraft.CoverSet <value> <number>` then changes one value of it by name, for example `Seamcraft.CoverSet Cavity 0.8`. ## Blueprint - Component: **Set Role**, **Set Width**, **Set Bevel**, **Set Cover**, **Refresh Seams**, **Get Stencil Value**. - Coverage Volume: **Fade Cover** (target Amount, target Puddles, seconds) moves the cover there over time and calls **On Cover Fade Finished** when it gets there: snow building up during a level (Snow preset, Amount from 0 to 1 over a few minutes), a street drying after rain (Wet preset, Amount and Puddles to 0). A new call takes over from wherever the last one got to. - Weather systems: Seamcraft reads no weather plugin by itself. Most of them keep a snow, wetness or dust value from 0 to 1; on their change, or on a timer, set the volume's Amount from it, or call Fade Cover with it. - Coverage Volume: **Apply Preset**, **Refresh Occlusion**, and every cover value (Amount, Color, Puddles, Water Cover, the shape and detail values) can be set from Blueprint and animated in Sequencer. The height capture's size, resolution and height are set in the editor. ## Custom stencil Seamcraft uses the custom stencil value of every primitive whose actor has the component: bits 0-4 are the ID (1-29; 30 is water the volume found, 31 is Cover off), bit 5 asks for bevel, bits 6-7 the width (0 = receiver). Actors without the component keep whatever they had, except the water meshes a Coverage Volume finds (only those that did not draw custom depth already). If another system of your game also writes custom stencil (an outline on the actor under the cursor, a highlight), set **`r.Seamcraft.StencilLayout 1`** in `DefaultEngine.ini` under `[SystemSettings]`. Seamcraft then only writes values 128 to 255 and ignores 1 to 127, which stay free for the other system: - an outline material that tests for its own values (1, 2, 3...) never sees Seamcraft's; - an actor the other system sets to one of its values (a highlighted rock) simply stops blending while it has it, and blends again when Seamcraft's value comes back (call **Refresh Seams** on its component); - each width has 13 IDs instead of 29, plenty for most scenes. An outline that lights up for any value above 0 will still see Seamcraft's actors: test for your values only, or for values below 128. ## Limits - Only what the camera sees blends: a surface hidden behind the mesh does not show in the mirror. - More than 29 actors of the same role and width touching one actor repeat an ID (the log says so); two of them will not blend into each other. Actors with Cover off all share one ID, so two of them touching do not blend into each other either. - Instanced meshes (foliage, ISM, HISM) get one ID for the whole component: instances blend into the receiver, not into each other. - No blending or cover with MSAA. Forward Shading and Substrate's Adaptive GBuffer get the lit color mode only, with no bevel and no cover. - With Substrate and DBuffer decals, the scene stencil bit Seamcraft reads for Receives Decals means something else, so turning Receives Decals off no longer keeps the cover off. Use Cover off on the component instead. - The cover's height capture sees everything opaque: with Foliage Blocks Cover on, dense trees keep the ground under them bare. - With Nanite meshes, the engine's custom depth pass costs about 0.3 ms more. - The Coverage Volume's box is axis aligned: rotating the actor does not rotate the area it covers. - Perspective and orthographic cameras are both supported (top-down and isometric games). ## Engine hotfixes Seamcraft hooks into the renderer and uses its own types, which an engine hotfix can change. A plugin compiled for one hotfix (say 5.7.1) and run on another (5.7.4) may crash at startup. To rebuild it for your hotfix: 1. Move the Seamcraft folder from the engine's `Plugins/Marketplace` folder into your project's `Plugins` folder. 2. Delete its `Binaries` and `Intermediate` folders. 3. In a C++ project, right click the `.uproject` > Generate Visual Studio project files, then build. A Blueprint-only project needs one C++ class first (Tools > New C++ Class, any parent). Or from a command line: `RunUAT.bat BuildPlugin -Plugin=<path>/Seamcraft.uplugin -Package=<output folder>`. ## Support Email contato@tessaroapps.com. Say which engine version and graphics card you use, and attach the log (`Saved/Logs`); a screenshot with `r.Seamcraft.Debug 1` or `2` helps too.