123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- using System;
- using UnityEngine.Experimental.Rendering;
- namespace UnityEngine.Rendering.Universal.Internal
- {
- /// <summary>
- /// 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.
- /// </summary>
- public class CopyDepthPass : ScriptableRenderPass
- {
- private RenderTargetHandle source { get; set; }
- private RenderTargetHandle destination { get; set; }
- internal bool AllocateRT { get; set; }
- internal int MssaSamples { get; set; }
- Material m_CopyDepthMaterial;
- public CopyDepthPass(RenderPassEvent evt, Material copyDepthMaterial)
- {
- base.profilingSampler = new ProfilingSampler(nameof(CopyDepthPass));
- AllocateRT = true;
- m_CopyDepthMaterial = copyDepthMaterial;
- renderPassEvent = evt;
- }
- /// <summary>
- /// Configure the pass with the source and destination to execute on.
- /// </summary>
- /// <param name="source">Source Render Target</param>
- /// <param name="destination">Destination Render Targt</param>
- public void Setup(RenderTargetHandle source, RenderTargetHandle destination)
- {
- this.source = source;
- this.destination = destination;
- this.AllocateRT = !destination.HasInternalRenderTargetId();
- this.MssaSamples = -1;
- }
- public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
- {
- var descriptor = renderingData.cameraData.cameraTargetDescriptor;
- descriptor.colorFormat = RenderTextureFormat.Depth;
- descriptor.depthBufferBits = 32; //TODO: do we really need this. double check;
- descriptor.msaaSamples = 1;
- if (this.AllocateRT)
- cmd.GetTemporaryRT(destination.id, descriptor, FilterMode.Point);
- // On Metal iOS, prevent camera attachments to be bound and cleared during this pass.
- ConfigureTarget(new RenderTargetIdentifier(destination.Identifier(), 0, CubemapFace.Unknown, -1), descriptor.depthStencilFormat, descriptor.width, descriptor.height, descriptor.msaaSamples, true);
- ConfigureClear(ClearFlag.None, Color.black);
- }
- /// <inheritdoc/>
- 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();
- using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.CopyDepth)))
- {
- int cameraSamples = 0;
- if (MssaSamples == -1)
- {
- RenderTextureDescriptor descriptor = renderingData.cameraData.cameraTargetDescriptor;
- cameraSamples = descriptor.msaaSamples;
- }
- else
- cameraSamples = MssaSamples;
- // When auto resolve is supported or multisampled texture is not supported, set camera samples to 1
- if (SystemInfo.supportsMultisampleAutoResolve || SystemInfo.supportsMultisampledTextures == 0)
- cameraSamples = 1;
- CameraData cameraData = renderingData.cameraData;
- switch (cameraSamples)
- {
- case 8:
- cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
- cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
- cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
- break;
- case 4:
- cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
- cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
- cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
- break;
- case 2:
- cmd.EnableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
- cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
- cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
- break;
- // MSAA disabled, auto resolve supported or ms textures not supported
- default:
- cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa2);
- cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa4);
- cmd.DisableShaderKeyword(ShaderKeywordStrings.DepthMsaa8);
- break;
- }
- cmd.SetGlobalTexture("_CameraDepthAttachment", source.Identifier());
- #if ENABLE_VR && ENABLE_XR_MODULE
- // XR uses procedural draw instead of cmd.blit or cmd.DrawFullScreenMesh
- if (renderingData.cameraData.xr.enabled)
- {
- // XR flip logic is not the same as non-XR case because XR uses draw procedure
- // and draw procedure does not need to take projection matrix yflip into account
- // We y-flip if
- // 1) we are bliting from render texture to back buffer and
- // 2) renderTexture starts UV at top
- // XRTODO: handle scalebias and scalebiasRt for src and dst separately
- bool isRenderToBackBufferTarget = destination.Identifier() == cameraData.xr.renderTarget && !cameraData.xr.renderTargetIsRenderTexture;
- bool yflip = isRenderToBackBufferTarget && SystemInfo.graphicsUVStartsAtTop;
- float flipSign = (yflip) ? -1.0f : 1.0f;
- Vector4 scaleBiasRt = (flipSign < 0.0f)
- ? new Vector4(flipSign, 1.0f, -1.0f, 1.0f)
- : new Vector4(flipSign, 0.0f, 1.0f, 1.0f);
- cmd.SetGlobalVector(ShaderPropertyId.scaleBiasRt, scaleBiasRt);
- cmd.DrawProcedural(Matrix4x4.identity, m_CopyDepthMaterial, 0, MeshTopology.Quads, 4);
- }
- else
- #endif
- {
- // Blit has logic to flip projection matrix when rendering to render texture.
- // Currently the y-flip is handled in CopyDepthPass.hlsl by checking _ProjectionParams.x
- // If you replace this Blit with a Draw* that sets projection matrix double check
- // to also update shader.
- // scaleBias.x = flipSign
- // scaleBias.y = scale
- // scaleBias.z = bias
- // scaleBias.w = unused
- // In game view final target acts as back buffer were target is not flipped
- bool isGameViewFinalTarget = (cameraData.cameraType == CameraType.Game && destination == RenderTargetHandle.CameraTarget);
- bool yflip = (cameraData.IsCameraProjectionMatrixFlipped()) && !isGameViewFinalTarget;
- float flipSign = yflip ? -1.0f : 1.0f;
- Vector4 scaleBiasRt = (flipSign < 0.0f)
- ? new Vector4(flipSign, 1.0f, -1.0f, 1.0f)
- : new Vector4(flipSign, 0.0f, 1.0f, 1.0f);
- cmd.SetGlobalVector(ShaderPropertyId.scaleBiasRt, scaleBiasRt);
- cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_CopyDepthMaterial);
- }
- }
- context.ExecuteCommandBuffer(cmd);
- CommandBufferPool.Release(cmd);
- }
- /// <inheritdoc/>
- public override void OnCameraCleanup(CommandBuffer cmd)
- {
- if (cmd == null)
- throw new ArgumentNullException("cmd");
- if (this.AllocateRT)
- cmd.ReleaseTemporaryRT(destination.id);
- destination = RenderTargetHandle.CameraTarget;
- }
- }
- }
|