In this lesson, you’ll learn how to configure Nanite materials to handle masked transparency efficiently without compromising the performance gains of virtualized geometry.
When working with Nanite, using the Masked blend mode for effects like foliage or chain-link fences can significantly impact performance. Because Nanite optimizes geometry into clusters, standard transparency breaks the culling efficiency that makes Nanite fast. To mitigate this, Unreal Engine utilizes Nanite Programmable Rasterization.
Enabling Masked Support
To use transparency on a Nanite mesh, your Material must have its Blend Mode set to Masked. Crucially, you must ensure that "Evaluate World Position Offset" is enabled in the Material details if you are using WPO for wind or animations, as Nanite processes these transformations differently than standard static meshes.
Optimizing Masked Costs
The performance cost of masked Nanite surfaces comes from "overdraw"—the GPU rendering pixels that are discarded by the opacity mask. To keep this performant:
- Use DitherTemporalAA: For complex edges, consider using the
DitherTemporalAAnode instead of a hard mask. This helps the renderer manage depth testing more effectively within the Nanite clusters. - Avoid Over-Complexity: Keep your opacity mask logic lean. If your mask relies on a high-resolution texture lookup, try to keep the instructions to a minimum to ensure the programmable rasterizer doesn't bottleneck.
The Rasterizer Pipeline
When you enable Nanite on an object with a masked material, Unreal automatically transitions from its hardware-accelerated "Base" rasterizer to the "Programmable" rasterizer. You can visualize this in the viewport by navigating to View Mode > Nanite Visualization > Masked. Surfaces appearing in red are currently using the programmable rasterizer. If you see excessive red in your scene, you are likely taxing your masked rendering performance:
// Within your Material Editor, use a simple constant to test mask density:
// Keep your Opacity Mask logic optimized:
float Mask = tex2D(TextureSampler, UVs).r;
clip(Mask - 0.5); // Ensure your clip threshold is stable
Key Takeaway: While Nanite supports masked transparency via the programmable rasterizer, you should minimize high-frequency opacity masks to prevent excessive overdraw and keep your rendering pipeline efficient.