// Modified version of stencil render pass by Alexander Ameye. // https://alexanderameye.github.io/ // https://twitter.com/alexanderameye/status/1332286868222775298 using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; public class JumpFloodOutlineStencilPass : ScriptableRenderPass { private const string k_ProfilerTag = "JumpFlood Outline Stencil Pass"; private const string k_ShaderName = "Hidden/shader_jumpflood_outline"; public static class ShaderIDs { private static readonly ShaderTagId SRPDefaultUnlit = new ShaderTagId("SRPDefaultUnlit"); private static readonly ShaderTagId UniversalForward = new ShaderTagId("UniversalForward"); private static readonly ShaderTagId LightweightForward = new ShaderTagId("LightweightForward"); public static readonly List ShaderTags = new List { SRPDefaultUnlit, UniversalForward, LightweightForward, }; } private readonly JumpFloodOutlineFeature.Settings m_settings; private readonly Material m_stencilMaterial; private FilteringSettings m_filteringSettings; public bool IsValid => m_stencilMaterial != null; public JumpFloodOutlineStencilPass(JumpFloodOutlineFeature.Settings settings) { profilingSampler = new ProfilingSampler(k_ProfilerTag); m_settings = settings; renderPassEvent = settings.renderPassEvent; // TODO: Try this again when render layers are working with hybrid renderer. // uint renderingLayerMask = 1u << settings.RenderLayer - 1; // _filteringSettings = new FilteringSettings(RenderQueueRange.all, settings.LayerMask.value, renderingLayerMask); m_filteringSettings = new FilteringSettings(RenderQueueRange.all, settings.layerMask.value); int flags = (int)ScriptableRenderPassInput.Depth; // require depth this.ConfigureInput((ScriptableRenderPassInput)flags); if (!m_stencilMaterial) { Shader shader = Shader.Find(k_ShaderName); shader = shader == null ? settings.outlineShader : shader; if (shader != null) { m_stencilMaterial = CoreUtils.CreateEngineMaterial(shader); } else { Debug.LogError($"Failed to Load shader: \"{k_ShaderName}\""); } } } public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { if (IsValid) { DrawingSettings drawingSettings = CreateDrawingSettings( ShaderIDs.ShaderTags, ref renderingData, m_settings.sortingCriteria ); drawingSettings.overrideMaterial = m_stencilMaterial; drawingSettings.overrideMaterialPassIndex = 0; // TODO: Switch to this once mismatched markers bug is fixed. // CommandBuffer cmd = CommandBufferPool.Get(ProfilerTag); CommandBuffer cmd = CommandBufferPool.Get(); using (new ProfilingScope(cmd, profilingSampler)) { context.ExecuteCommandBuffer(cmd); cmd.Clear(); context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref m_filteringSettings); } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } } }