Overview
The outline feature visually highlights meshes by rendering an inflated version using backface culling (inverted hull technique). Outline thickness dynamically adjusts based on camera distance and can be controlled at runtime.
Setup
- Add
Outline Authoring component to target entity
- Configure:
Material: Outline material (defaults to M_Outline)
ThicknessMultiplier: Outline width (0-1)
BakeNormals: Enables smooth normals for hard edges
CombineSubMeshes: Enables outlines on meshes with multiple submeshes
Technical Details
Mesh Processing
- Smooth normals are baked into UV3 channel for better quality on hard edges
- Submeshes are combined to handle multi-material meshes correctly
- Both operations require mesh Read/Write enabled
Limitations
Child meshes receive individual outlines rather than a single combined outline.
Implementation
Two primary systems:
OutlineInitializationClientSystem: Material setup and mesh processing
OutlineRenderClientSystem: Outline renderer lifecycle management
The outline shader (Assets/Shaders/Outline) can be modified via Shader Graph.
Code Example
public partial struct PulsingOutlineSystem : ISystem
{
private double _lastToggleTime;
private const float ToggleInterval = 3f;
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate();
}
public void OnUpdate(ref SystemState state)
{
var time = SystemAPI.Time.ElapsedTime;
var pulseValue = (math.sin((float)time * 2f) + 1f) * 0.5f;
if (time - _lastToggleTime > ToggleInterval)
{
_lastToggleTime = time;
foreach (var (_, entity) in
SystemAPI.Query<RefRW>().WithEntityAccess())
{
var isEnabled = SystemAPI.IsComponentEnabled(entity);
SystemAPI.SetComponentEnabled(entity, !isEnabled);
}
}
foreach (var outline in
SystemAPI.Query<RefRW>()
.WithEnabledComponent())
{
outline.ValueRW.ThicknessMultiplier = pulseValue;
}
}
}