Inverted Normal Studio

Sharp Stencil Shadows

Documentation for Sharp Stencil Shadows, a URP renderer feature for hard, pixel-exact stencil shadow volumes.

Scripting API

Home › Reference

Namespace and assembly

All public types are in the SharpStencilShadows namespace, in the SharpStencilShadows.Runtime assembly. Scripts in Assembly-CSharp can use it directly. Scripts in your own assembly definitions must reference it.

using SharpStencilShadows;

StencilShadowRendererFeature

The renderer feature. One per Universal Renderer.

FindActive

public static StencilShadowRendererFeature FindActive()

Returns the first active Sharp Stencil Shadows feature on the current URP asset's renderers, or null. If your renderers have differently configured features, keep a reference to the one you need instead.

Settings

public StencilShadowSettings Settings { get; }

The feature's settings. See StencilShadowSettings.

DebugStats

public StencilShadowDebugStats DebugStats { get; }

Statistics from the most recent camera this feature rendered. See StencilShadowDebugStats.

Changing settings at runtime

Method Setting
SetLightingMode(ShadowLightingMode) Lighting Mode
SetShadowLod(ShadowLodMode) Shadow LOD
SetSelfShadows(bool) Self Shadows
SetBackendMode(ShadowVolumeBackendMode) Backend
SetTransparentCasterMode(TransparentCasterMode) Transparent Casters Mode
SetUrpLightingColoredTransmittance(bool) Colored Transmittance
SetUrpLightingLocalLightTransmittance(bool) Local Light Transmittance
SetGpuDeformedMeshes(bool) GPU Deformed Meshes
SetCasterAtlasReceiverSizing(bool) Receiver Sizing
SetDebugVisualization(bool) Debug Visualization

Changes take effect the next time the feature renders. They modify the renderer asset, so changes made in Play Mode remain in the asset after exiting it.

StencilShadowSettings

Properties

Read-only properties mirror each renderer feature setting, for example LightingMode, BackendMode, CasterLayerMask, ShadowStrength, MaxShadowedAdditionalLights, and TransparentCasterMode.

MaxShadowedAdditionalLightLimit is the maximum point and spot light budget, 7.

Methods

In addition to the setters above, Settings provides:

Method Setting Throws
SetAdditionalLightLayerMask(LayerMask) Light Layers None
SetMaxShadowedAdditionalLights(int) Max Shadowed Lights ArgumentOutOfRangeException outside 0 to 7
SetStencilMask(int) Stencil Mask ArgumentOutOfRangeException unless 3, 7, 15, 31, 63, 127, or 255

Enums

ShadowLightingMode

Overlay, UrpLighting. See Lighting modes.

ShadowLodMode

MatchCamera, Lod0. See LOD groups.

ShadowVolumeBackendMode

Auto, Cpu, Gpu. See Volume generation backends.

TransparentCasterMode

Off, UniformOpacity, Textured. See Transparent caster modes.

CasterAtlasFilterMode

MatchCaster, Nearest, Bilinear, Bicubic. See Filtering.

GpuFallbackReason

Why a caster fell back from the GPU to the CPU backend: None, ComputeUnsupported, IndirectUnsupported, InvalidTopology, BufferCapacityExceeded, MissingPositionAttribute, UnsupportedPositionLayout, VertexCountMismatch, SourceBufferUnavailable, BufferAllocationFailed, OutputOverflow, ComputeShaderUnavailable. See GPU fallback.

ShadowCasterDiscovery

RequestRefresh

public static void RequestRefresh()

Rescans the scene for casters the next time the feature renders, instead of waiting for the next periodic scan. See Caster discovery.

ShadowVolumeTopologyRegistration

Supplies topology for non-readable meshes created at runtime, and refreshes meshes edited at runtime. See Procedural and runtime meshes.

Register

public static void Register(Mesh mesh, Vector3[] positions, int[] triangleIndices,
    float weldTolerance = 0.0001f, ulong[] skinSignatures = null)

Builds and stores topology for mesh from its positions and triangle indices. The arrays are copied.

Registrations last for the current runtime session. They are cleared when a new player or Play Mode session starts, even with domain reload disabled. Register procedural meshes again during runtime initialization.

  • weldTolerance must match the feature's Topology Weld Tolerance.
  • skinSignatures is optional, one value per vertex. Vertices with different signatures are never welded. Use it for skinned meshes, for example a hash of each vertex's bone weights.

Unregister

public static bool Unregister(Mesh mesh)

Removes every registration for mesh. Returns true if any existed.

Refresh

public static void Refresh(Mesh mesh)

Rebuilds the topology of mesh from its current data the next time it casts, after a script changed its vertices or triangles in place. Only that mesh's casters rebuild their volumes. From then on its topology cache entry is not used, so the mesh must be readable in players. A registered mesh keeps its registered topology: call Register with the new data instead. Throws ArgumentNullException for a null mesh.

StencilShadowDebugStats

A snapshot of the last rendered camera.

Caster counts

Property Meaning
DiscoveredCasterCount, EligibleCasterCount Casters found by the last discovery scan; both report the same value
CpuCasterCount, GpuCasterCount Volumes per backend: one per caster in Overlay, one per caster and light in URP Lighting
GpuDeformedMeshCasterCount GPU volumes read from a deformed mesh
SkippedCasterCount Discovered casters minus CPU volumes, GPU volumes, and atlas casters, for example casters skipped for missing topology. In URP Lighting volumes count once per light, so it undercounts

Backend and GPU statistics

Property Meaning
RequestedBackend, GpuBackendAvailable The selected backend, and whether the device supports the GPU backend
GpuFallbackCasterCount, GpuFallbacks Casters that fell back to CPU, in total and by reason
CpuGeneratedVertexCount, GpuAllocatedVertexCapacity Vertices the CPU volumes draw (their index count) and the GPU volumes' allocated capacity, counted the same way
PendingOverflowCheckCount GPU overflow checks awaiting readback

Transparent caster statistics

Property Meaning
TransparentCasterMode The mode in use
AtlasCasterCount Casters drawn into the caster atlas
UniformTransparentCasterCount Casters using one uniform opacity
AtlasOverflowCasterCount Atlas casters that did not fit this frame

Lighting statistics

Property Meaning
LightingMode The mode the camera rendered with, which is Overlay when it fell back
ShadowedAdditionalLightCount Point and spot lights with stencil shadows
LocalAtlasTileCount Point and spot light caster atlas tiles

GpuFallbackReasonCounts

Member Meaning
TotalCount All fallen-back casters
GetCount(GpuFallbackReason) Casters that fell back for one reason

Examples

A graphics options menu

using SharpStencilShadows;
using UnityEngine;

public class ShadowOptions : MonoBehaviour
{
    public void SetQuality(int level)
    {
        StencilShadowRendererFeature feature = StencilShadowRendererFeature.FindActive();
        if (feature == null)
            return;

        feature.SetLightingMode(level > 0 ? ShadowLightingMode.UrpLighting : ShadowLightingMode.Overlay);
        feature.SetTransparentCasterMode(level > 1 ? TransparentCasterMode.Textured : TransparentCasterMode.UniformOpacity);
    }
}

In players, switch to URP Lighting only on renderers saved in URP Lighting mode. See Player builds.

Showing statistics on screen

using SharpStencilShadows;
using UnityEngine;

public class ShadowStatsHud : MonoBehaviour
{
    private void OnGUI()
    {
        StencilShadowRendererFeature feature = StencilShadowRendererFeature.FindActive();
        if (feature == null)
            return;

        StencilShadowDebugStats stats = feature.DebugStats;
        GUILayout.Label($"CPU {stats.CpuCasterCount}  GPU {stats.GpuCasterCount}  Fallbacks {stats.GpuFallbackCasterCount}");
    }
}