using System; namespace UnityEngine.Rendering.Universal { /// /// Copy the given depth buffer into the given destination depth buffer. /// /// You can use this pass to copy a depth buffer to a destination, /// so you can use it later in rendering. If the source texture has MSAA /// enabled, the pass uses a custom MSAA resolve. If the source texture /// does not have MSAA enabled, the pass uses a Blit or a Copy Texture /// operation, depending on what the current platform supports. /// internal class CopyDepthPass : ScriptableRenderPass { private RenderTargetHandle source { get; set; } private RenderTargetHandle destination { get; set; } Material m_CopyDepthMaterial; const string m_ProfilerTag = "Copy Depth"; public CopyDepthPass(RenderPassEvent evt, Material copyDepthMaterial) { m_CopyDepthMaterial = copyDepthMaterial; renderPassEvent = evt; } /// /// Configure the pass with the source and destination to execute on. /// /// Source Render Target /// Destination Render Targt public void Setup(RenderTargetHandle source, RenderTargetHandle destination) { this.source = source; this.destination = destination; } public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) { var descriptor = cameraTextureDescriptor; descriptor.colorFormat = RenderTextureFormat.Depth; descriptor.depthBufferBits = 32; //TODO: do we really need this. double check; descriptor.msaaSamples = 1; cmd.GetTemporaryRT(destination.id, descriptor, FilterMode.Point); } /// public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { if (m_CopyDepthMaterial == null) { Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_CopyDepthMaterial, GetType().Name); return; } CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag); RenderTargetIdentifier depthSurface = source.Identifier(); RenderTargetIdentifier copyDepthSurface = destination.Identifier(); RenderTextureDescriptor descriptor = renderingData.cameraData.cameraTargetDescriptor; int cameraSamples = descriptor.msaaSamples; // TODO: we don't need a command buffer here. We can set these via Material.Set* API cmd.SetGlobalTexture("_CameraDepthAttachment", source.Identifier()); if (cameraSamples > 1) { cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthNoMsaa); if (cameraSamples == 4) { cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2); cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa4); } else { cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa2); cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4); } Blit(cmd, depthSurface, copyDepthSurface, m_CopyDepthMaterial); } else { cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthNoMsaa); cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2); cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4); CopyTexture(cmd, depthSurface, copyDepthSurface, m_CopyDepthMaterial); } context.ExecuteCommandBuffer(cmd); CommandBufferPool.Release(cmd); } void CopyTexture(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier dest, Material material) { // TODO: In order to issue a copyTexture we need to also check if source and dest have same size //if (SystemInfo.copyTextureSupport != CopyTextureSupport.None) // cmd.CopyTexture(source, dest); //else Blit(cmd, source, dest, material); } /// public override void FrameCleanup(CommandBuffer cmd) { if (cmd == null) throw new ArgumentNullException("cmd"); cmd.ReleaseTemporaryRT(destination.id); destination = RenderTargetHandle.CameraTarget; } } }