DepthOnlyPass.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using System;
  2. using UnityEngine.Experimental.Rendering;
  3. namespace UnityEngine.Rendering.Universal.Internal
  4. {
  5. /// <summary>
  6. /// Render all objects that have a 'DepthOnly' pass into the given depth buffer.
  7. ///
  8. /// You can use this pass to prime a depth buffer for subsequent rendering.
  9. /// Use it as a z-prepass, or use it to generate a depth buffer.
  10. /// </summary>
  11. public class DepthOnlyPass : ScriptableRenderPass
  12. {
  13. private static readonly ShaderTagId k_ShaderTagId = new ShaderTagId("DepthOnly");
  14. private RenderTargetHandle depthAttachmentHandle { get; set; }
  15. internal RenderTextureDescriptor descriptor { get; set; }
  16. internal bool allocateDepth { get; set; } = true;
  17. internal ShaderTagId shaderTagId { get; set; } = k_ShaderTagId;
  18. FilteringSettings m_FilteringSettings;
  19. // Constants
  20. private const int k_DepthBufferBits = 32;
  21. /// <summary>
  22. /// Create the DepthOnlyPass
  23. /// </summary>
  24. public DepthOnlyPass(RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask)
  25. {
  26. base.profilingSampler = new ProfilingSampler(nameof(DepthOnlyPass));
  27. m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask);
  28. renderPassEvent = evt;
  29. useNativeRenderPass = false;
  30. }
  31. /// <summary>
  32. /// Configure the pass
  33. /// </summary>
  34. public void Setup(
  35. RenderTextureDescriptor baseDescriptor,
  36. RenderTargetHandle depthAttachmentHandle)
  37. {
  38. this.depthAttachmentHandle = depthAttachmentHandle;
  39. baseDescriptor.colorFormat = RenderTextureFormat.Depth;
  40. baseDescriptor.depthBufferBits = k_DepthBufferBits;
  41. // Depth-Only pass don't use MSAA
  42. baseDescriptor.msaaSamples = 1;
  43. descriptor = baseDescriptor;
  44. this.allocateDepth = true;
  45. this.shaderTagId = k_ShaderTagId;
  46. }
  47. public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
  48. {
  49. if (this.allocateDepth)
  50. cmd.GetTemporaryRT(depthAttachmentHandle.id, descriptor, FilterMode.Point);
  51. var desc = renderingData.cameraData.cameraTargetDescriptor;
  52. // When depth priming is in use the camera target should not be overridden so the Camera's MSAA depth attachment is used.
  53. if (renderingData.cameraData.renderer.useDepthPriming && (renderingData.cameraData.renderType == CameraRenderType.Base || renderingData.cameraData.clearDepth))
  54. {
  55. ConfigureTarget(renderingData.cameraData.renderer.cameraDepthTarget, descriptor.depthStencilFormat, desc.width, desc.height, 1, true);
  56. }
  57. // When not using depth priming the camera target should be set to our non MSAA depth target.
  58. else
  59. {
  60. ConfigureTarget(new RenderTargetIdentifier(depthAttachmentHandle.Identifier(), 0, CubemapFace.Unknown, -1), descriptor.depthStencilFormat, desc.width, desc.height, 1, true);
  61. }
  62. // Only clear depth here so we don't clear any bound color target. It might be unused by this pass but that doesn't mean we can just clear it. (e.g. in case of overlay cameras + depth priming)
  63. ConfigureClear(ClearFlag.Depth, Color.black);
  64. }
  65. /// <inheritdoc/>
  66. public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
  67. {
  68. // NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
  69. // Currently there's an issue which results in mismatched markers.
  70. CommandBuffer cmd = CommandBufferPool.Get();
  71. using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.DepthPrepass)))
  72. {
  73. context.ExecuteCommandBuffer(cmd);
  74. cmd.Clear();
  75. var sortFlags = renderingData.cameraData.defaultOpaqueSortFlags;
  76. var drawSettings = CreateDrawingSettings(this.shaderTagId, ref renderingData, sortFlags);
  77. drawSettings.perObjectData = PerObjectData.None;
  78. context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref m_FilteringSettings);
  79. }
  80. context.ExecuteCommandBuffer(cmd);
  81. CommandBufferPool.Release(cmd);
  82. }
  83. /// <inheritdoc/>
  84. public override void OnCameraCleanup(CommandBuffer cmd)
  85. {
  86. if (cmd == null)
  87. throw new ArgumentNullException("cmd");
  88. if (depthAttachmentHandle != RenderTargetHandle.CameraTarget)
  89. {
  90. if (this.allocateDepth)
  91. cmd.ReleaseTemporaryRT(depthAttachmentHandle.id);
  92. depthAttachmentHandle = RenderTargetHandle.CameraTarget;
  93. }
  94. }
  95. }
  96. }