using System; using UnityEngine.Experimental.Rendering; using UnityEngine.Rendering.RenderGraphModule; namespace UnityEngine.Rendering.Universal.Internal { /// /// Render all objects that have a 'DepthOnly' pass into the given depth buffer. /// /// You can use this pass to prime a depth buffer for subsequent rendering. /// Use it as a z-prepass, or use it to generate a depth buffer. /// public partial class DepthOnlyPass : ScriptableRenderPass { internal ShaderTagId shaderTagId { get; set; } = k_ShaderTagId; FilteringSettings m_FilteringSettings; // Statics private static readonly ShaderTagId k_ShaderTagId = new ShaderTagId("DepthOnly"); private static readonly int s_CameraDepthTextureID = Shader.PropertyToID("_CameraDepthTexture"); /// /// Creates a new DepthOnlyPass instance. /// /// The RenderPassEvent to use. /// The RenderQueueRange to use for creating filtering settings that control what objects get rendered. /// The layer mask to use for creating filtering settings that control what objects get rendered. /// /// /// public DepthOnlyPass(RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask) { profilingSampler = new ProfilingSampler("Draw Depth Only"); m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask); renderPassEvent = evt; shaderTagId = k_ShaderTagId; } /// /// Configures the pass. /// /// The RenderTextureDescriptor used for the depthStencilFormat. /// The RTHandle used to render to. /// /// /// public void Setup( RenderTextureDescriptor baseDescriptor, RTHandle depthAttachmentHandle) { } private static void ExecutePass(RasterCommandBuffer cmd, RendererList rendererList) { using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.DepthPrepass))) { cmd.DrawRendererList(rendererList); } } private class PassData { internal RendererListHandle rendererList; } private RendererListParams InitRendererListParams(UniversalRenderingData renderingData, UniversalCameraData cameraData, UniversalLightData lightData) { var sortFlags = cameraData.defaultOpaqueSortFlags; var drawSettings = RenderingUtils.CreateDrawingSettings(this.shaderTagId, renderingData, cameraData, lightData, sortFlags); drawSettings.perObjectData = PerObjectData.None; drawSettings.lodCrossFadeStencilMask = 0; // For stencil-based Lod, we use texture dither instead of stencil testing because we have the same shader variants for cross-fade shadow. return new RendererListParams(renderingData.cullResults, drawSettings, m_FilteringSettings); } internal void Render(RenderGraph renderGraph, ContextContainer frameData, in TextureHandle depthTexture, uint batchLayerMask, bool setGlobalDepth) { UniversalRenderingData renderingData = frameData.Get(); UniversalCameraData cameraData = frameData.Get(); UniversalLightData lightData = frameData.Get(); using (var builder = renderGraph.AddRasterRenderPass(passName, out var passData, profilingSampler)) { var param = InitRendererListParams(renderingData, cameraData, lightData); param.filteringSettings.batchLayerMask = batchLayerMask; passData.rendererList = renderGraph.CreateRendererList(param); builder.UseRendererList(passData.rendererList); builder.SetRenderAttachmentDepth(depthTexture, AccessFlags.ReadWrite); if (setGlobalDepth) builder.SetGlobalTextureAfterPass(depthTexture, s_CameraDepthTextureID); builder.AllowGlobalStateModification(true); if (cameraData.xr.enabled) { builder.EnableFoveatedRasterization(cameraData.xr.supportsFoveatedRendering && cameraData.xrUniversal.canFoveateIntermediatePasses); // Apply MultiviewRenderRegionsCompatible flag only to the peripheral view in Quad Views if (cameraData.xr.multipassId == 0) { builder.SetExtendedFeatureFlags(ExtendedFeatureFlags.MultiviewRenderRegionsCompatible); } } builder.SetRenderFunc(static (PassData data, RasterGraphContext context) => { ExecutePass(context.cmd, data.rendererList); }); } } } }