Brak opisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DepthBlitFeature.cs 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. using UnityEngine;
  2. using UnityEngine.Experimental.Rendering;
  3. using UnityEngine.Rendering;
  4. using UnityEngine.Rendering.RenderGraphModule;
  5. using UnityEngine.Rendering.Universal;
  6. // This Renderer Feature enqueues either the DepthBlitCopyDepthPass or the DepthBlitDepthOnlyPass depending on the current platform support.
  7. // DepthBlitCopyPass is a simplified version of URP CopyDepthPass. The pass copies the depth texture to an RTHandle.
  8. // DepthBlitDepthOnlyPass is a simplified version of the URP DepthOnlyPass. The pass renders depth values to an RTHandle.
  9. // The Renderer Feature also enqueues the DepthBlitEdgePass which takes the RTHandle as input to create an effect to visualize depth, and output it to the screen.
  10. public class DepthBlitFeature : ScriptableRendererFeature
  11. {
  12. public RenderPassEvent evt_Depth = RenderPassEvent.AfterRenderingOpaques;
  13. public RenderPassEvent evt_Edge = RenderPassEvent.AfterRenderingOpaques;
  14. public UniversalRendererData rendererDataAsset; // The field for accessing opaqueLayerMask on the renderer asset
  15. public Shader copyDepthShader;
  16. public Material m_DepthEdgeMaterial;
  17. // The RTHandle for storing the depth texture
  18. private RTHandle m_DepthRTHandle;
  19. private const string k_DepthRTName = "_MyDepthTexture";
  20. // This class is for keeping the TextureHandle reference in the frame data so that it can be shared with multiple passes in the render graph system.
  21. public class TexRefData : ContextItem
  22. {
  23. public TextureHandle depthTextureHandle = TextureHandle.nullHandle;
  24. public override void Reset()
  25. {
  26. depthTextureHandle = TextureHandle.nullHandle;
  27. }
  28. }
  29. // The passes for the effect
  30. private DepthBlitCopyDepthPass m_CopyDepthPass;
  31. private DepthBlitDepthOnlyPass m_DepthOnlyPass; // DepthOnlyPass is for platforms that run OpenGL ES, which does not support CopyDepth.
  32. private DepthBlitEdgePass m_DepthEdgePass;
  33. // Check if the platform supports CopyDepthPass
  34. private bool CanCopyDepth(ref CameraData cameraData)
  35. {
  36. bool msaaEnabledForCamera = cameraData.cameraTargetDescriptor.msaaSamples > 1;
  37. bool supportsTextureCopy = SystemInfo.copyTextureSupport != CopyTextureSupport.None;
  38. bool supportsDepthTarget = RenderingUtils.SupportsRenderTextureFormat(RenderTextureFormat.Depth);
  39. bool supportsDepthCopy = !msaaEnabledForCamera && (supportsDepthTarget || supportsTextureCopy);
  40. bool msaaDepthResolve = msaaEnabledForCamera && SystemInfo.supportsMultisampledTextures != 0;
  41. // Avoid copying MSAA depth on GLES3 platform to avoid invalid results
  42. if (IsGLESDevice() && msaaDepthResolve)
  43. return false;
  44. return supportsDepthCopy || msaaDepthResolve;
  45. }
  46. private bool IsGLESDevice()
  47. {
  48. return SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3;
  49. }
  50. public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
  51. {
  52. var cameraData = renderingData.cameraData;
  53. if (renderingData.cameraData.cameraType != CameraType.Game)
  54. return;
  55. // Create an RTHandle for storing the depth
  56. var desc = renderingData.cameraData.cameraTargetDescriptor;
  57. if (CanCopyDepth(ref cameraData))
  58. {
  59. desc.depthBufferBits = 0;
  60. desc.msaaSamples = 1;
  61. }
  62. else
  63. {
  64. desc.graphicsFormat = GraphicsFormat.None;
  65. desc.msaaSamples = 1;
  66. }
  67. RenderingUtils.ReAllocateHandleIfNeeded(ref m_DepthRTHandle, desc, FilterMode.Bilinear, TextureWrapMode.Clamp, name: k_DepthRTName );
  68. // Setup passes
  69. if (CanCopyDepth(ref cameraData))
  70. {
  71. if (m_CopyDepthPass == null)
  72. m_CopyDepthPass = new DepthBlitCopyDepthPass(evt_Depth, copyDepthShader, m_DepthRTHandle);
  73. renderer.EnqueuePass(m_CopyDepthPass);
  74. }
  75. else
  76. {
  77. if (m_DepthOnlyPass == null)
  78. m_DepthOnlyPass = new DepthBlitDepthOnlyPass(evt_Depth, RenderQueueRange.opaque, rendererDataAsset.opaqueLayerMask, m_DepthRTHandle);
  79. renderer.EnqueuePass(m_DepthOnlyPass);
  80. }
  81. // Pass the RTHandle for the DepthEdge effect
  82. m_DepthEdgePass.SetRTHandle(ref m_DepthRTHandle);
  83. renderer.EnqueuePass(m_DepthEdgePass);
  84. }
  85. public override void Create()
  86. {
  87. m_DepthEdgePass = new DepthBlitEdgePass(m_DepthEdgeMaterial, evt_Edge);
  88. }
  89. protected override void Dispose(bool disposing)
  90. {
  91. m_CopyDepthPass?.Dispose();
  92. m_DepthRTHandle?.Release();
  93. m_DepthEdgePass = null;
  94. m_CopyDepthPass = null;
  95. m_DepthOnlyPass = null;
  96. }
  97. }