123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- using UnityEngine;
- using UnityEngine.Experimental.Rendering;
- using UnityEngine.Rendering;
- using UnityEngine.Rendering.RenderGraphModule;
- using UnityEngine.Rendering.Universal;
-
- // This Renderer Feature enqueues either the DepthBlitCopyDepthPass or the DepthBlitDepthOnlyPass depending on the current platform support.
- // DepthBlitCopyPass is a simplified version of URP CopyDepthPass. The pass copies the depth texture to an RTHandle.
- // DepthBlitDepthOnlyPass is a simplified version of the URP DepthOnlyPass. The pass renders depth values to an RTHandle.
- // 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.
- public class DepthBlitFeature : ScriptableRendererFeature
- {
- public RenderPassEvent evt_Depth = RenderPassEvent.AfterRenderingOpaques;
- public RenderPassEvent evt_Edge = RenderPassEvent.AfterRenderingOpaques;
- public UniversalRendererData rendererDataAsset; // The field for accessing opaqueLayerMask on the renderer asset
-
- public Shader copyDepthShader;
-
- public Material m_DepthEdgeMaterial;
-
- // The RTHandle for storing the depth texture
- private RTHandle m_DepthRTHandle;
- private const string k_DepthRTName = "_MyDepthTexture";
-
- // 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.
- public class TexRefData : ContextItem
- {
- public TextureHandle depthTextureHandle = TextureHandle.nullHandle;
-
- public override void Reset()
- {
- depthTextureHandle = TextureHandle.nullHandle;
- }
- }
-
- // The passes for the effect
- private DepthBlitCopyDepthPass m_CopyDepthPass;
- private DepthBlitDepthOnlyPass m_DepthOnlyPass; // DepthOnlyPass is for platforms that run OpenGL ES, which does not support CopyDepth.
- private DepthBlitEdgePass m_DepthEdgePass;
-
- // Check if the platform supports CopyDepthPass
- private bool CanCopyDepth(ref CameraData cameraData)
- {
- bool msaaEnabledForCamera = cameraData.cameraTargetDescriptor.msaaSamples > 1;
- bool supportsTextureCopy = SystemInfo.copyTextureSupport != CopyTextureSupport.None;
- bool supportsDepthTarget = RenderingUtils.SupportsRenderTextureFormat(RenderTextureFormat.Depth);
- bool supportsDepthCopy = !msaaEnabledForCamera && (supportsDepthTarget || supportsTextureCopy);
-
- bool msaaDepthResolve = msaaEnabledForCamera && SystemInfo.supportsMultisampledTextures != 0;
-
- // Avoid copying MSAA depth on GLES3 platform to avoid invalid results
- if (IsGLESDevice() && msaaDepthResolve)
- return false;
-
- return supportsDepthCopy || msaaDepthResolve;
- }
-
- private bool IsGLESDevice()
- {
- return SystemInfo.graphicsDeviceType == GraphicsDeviceType.OpenGLES3;
- }
-
- public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
- {
- var cameraData = renderingData.cameraData;
- if (renderingData.cameraData.cameraType != CameraType.Game)
- return;
-
- // Create an RTHandle for storing the depth
- var desc = renderingData.cameraData.cameraTargetDescriptor;
- if (CanCopyDepth(ref cameraData))
- {
- desc.depthBufferBits = 0;
- desc.msaaSamples = 1;
- }
- else
- {
- desc.graphicsFormat = GraphicsFormat.None;
- desc.msaaSamples = 1;
- }
- RenderingUtils.ReAllocateHandleIfNeeded(ref m_DepthRTHandle, desc, FilterMode.Bilinear, TextureWrapMode.Clamp, name: k_DepthRTName );
-
- // Setup passes
- if (CanCopyDepth(ref cameraData))
- {
- if (m_CopyDepthPass == null)
- m_CopyDepthPass = new DepthBlitCopyDepthPass(evt_Depth, copyDepthShader, m_DepthRTHandle);
-
- renderer.EnqueuePass(m_CopyDepthPass);
- }
- else
- {
- if (m_DepthOnlyPass == null)
- m_DepthOnlyPass = new DepthBlitDepthOnlyPass(evt_Depth, RenderQueueRange.opaque, rendererDataAsset.opaqueLayerMask, m_DepthRTHandle);
-
- renderer.EnqueuePass(m_DepthOnlyPass);
- }
-
- // Pass the RTHandle for the DepthEdge effect
- m_DepthEdgePass.SetRTHandle(ref m_DepthRTHandle);
- renderer.EnqueuePass(m_DepthEdgePass);
- }
-
- public override void Create()
- {
- m_DepthEdgePass = new DepthBlitEdgePass(m_DepthEdgeMaterial, evt_Edge);
- }
-
- protected override void Dispose(bool disposing)
- {
- m_CopyDepthPass?.Dispose();
- m_DepthRTHandle?.Release();
- m_DepthEdgePass = null;
- m_CopyDepthPass = null;
- m_DepthOnlyPass = null;
- }
- }
|