123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- using System;
- using System.Collections.Generic;
- using UnityEngine.Experimental.Rendering;
- namespace UnityEngine.Rendering.Universal.Internal
- {
- public class DepthNormalOnlyPass : ScriptableRenderPass
- {
- internal RenderTextureDescriptor normalDescriptor { get; set; }
- internal RenderTextureDescriptor depthDescriptor { get; set; }
- internal bool allocateDepth { get; set; } = true;
- internal bool allocateNormal { get; set; } = true;
- internal List<ShaderTagId> shaderTagIds { get; set; }
- private RenderTargetHandle depthHandle { get; set; }
- private RenderTargetHandle normalHandle { get; set; }
- private FilteringSettings m_FilteringSettings;
- private int m_RendererMSAASamples = 1;
- // Constants
- private const int k_DepthBufferBits = 32;
- private static readonly List<ShaderTagId> k_DepthNormals = new List<ShaderTagId> { new ShaderTagId("DepthNormals"), new ShaderTagId("DepthNormalsOnly") };
- /// <summary>
- /// Create the DepthNormalOnlyPass
- /// </summary>
- public DepthNormalOnlyPass(RenderPassEvent evt, RenderQueueRange renderQueueRange, LayerMask layerMask)
- {
- base.profilingSampler = new ProfilingSampler(nameof(DepthNormalOnlyPass));
- m_FilteringSettings = new FilteringSettings(renderQueueRange, layerMask);
- renderPassEvent = evt;
- useNativeRenderPass = false;
- }
- /// <summary>
- /// Configure the pass
- /// </summary>
- public void Setup(RenderTextureDescriptor baseDescriptor, RenderTargetHandle depthHandle, RenderTargetHandle normalHandle)
- {
- // Find compatible render-target format for storing normals.
- // Shader code outputs normals in signed format to be compatible with deferred gbuffer layout.
- // Deferred gbuffer format is signed so that normals can be blended for terrain geometry.
- GraphicsFormat normalsFormat;
- if (RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R8G8B8A8_SNorm, FormatUsage.Render))
- normalsFormat = GraphicsFormat.R8G8B8A8_SNorm; // Preferred format
- else if (RenderingUtils.SupportsGraphicsFormat(GraphicsFormat.R16G16B16A16_SFloat, FormatUsage.Render))
- normalsFormat = GraphicsFormat.R16G16B16A16_SFloat; // fallback
- else
- normalsFormat = GraphicsFormat.R32G32B32A32_SFloat; // fallback
- this.depthHandle = depthHandle;
- m_RendererMSAASamples = baseDescriptor.msaaSamples;
- baseDescriptor.colorFormat = RenderTextureFormat.Depth;
- baseDescriptor.depthBufferBits = k_DepthBufferBits;
- // Never have MSAA on this depth texture. When doing MSAA depth priming this is the texture that is resolved to and used for post-processing.
- baseDescriptor.msaaSamples = 1;// Depth-Only pass don't use MSAA
- depthDescriptor = baseDescriptor;
- this.normalHandle = normalHandle;
- baseDescriptor.graphicsFormat = normalsFormat;
- baseDescriptor.depthBufferBits = 0;
- normalDescriptor = baseDescriptor;
- this.allocateDepth = true;
- this.allocateNormal = true;
- this.shaderTagIds = k_DepthNormals;
- }
- /// <inheritdoc/>
- public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
- {
- if (this.allocateNormal)
- {
- RenderTextureDescriptor desc = normalDescriptor;
- desc.msaaSamples = renderingData.cameraData.renderer.useDepthPriming ? m_RendererMSAASamples : 1;
- cmd.GetTemporaryRT(normalHandle.id, desc, FilterMode.Point);
- }
- if (this.allocateDepth)
- cmd.GetTemporaryRT(depthHandle.id, depthDescriptor, FilterMode.Point);
- if (renderingData.cameraData.renderer.useDepthPriming && (renderingData.cameraData.renderType == CameraRenderType.Base || renderingData.cameraData.clearDepth))
- {
- ConfigureTarget(
- new RenderTargetIdentifier(normalHandle.Identifier(), 0, CubemapFace.Unknown, -1),
- new RenderTargetIdentifier(renderingData.cameraData.renderer.cameraDepthTarget, 0, CubemapFace.Unknown, -1)
- );
- }
- else
- {
- ConfigureTarget(
- new RenderTargetIdentifier(normalHandle.Identifier(), 0, CubemapFace.Unknown, -1),
- new RenderTargetIdentifier(depthHandle.Identifier(), 0, CubemapFace.Unknown, -1)
- );
- }
- ConfigureClear(ClearFlag.All, Color.black);
- }
- /// <inheritdoc/>
- public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
- {
- // NOTE: Do NOT mix ProfilingScope with named CommandBuffers i.e. CommandBufferPool.Get("name").
- // Currently there's an issue which results in mismatched markers.
- CommandBuffer cmd = CommandBufferPool.Get();
- using (new ProfilingScope(cmd, ProfilingSampler.Get(URPProfileId.DepthNormalPrepass)))
- {
- context.ExecuteCommandBuffer(cmd);
- cmd.Clear();
- var sortFlags = renderingData.cameraData.defaultOpaqueSortFlags;
- var drawSettings = CreateDrawingSettings(this.shaderTagIds, ref renderingData, sortFlags);
- drawSettings.perObjectData = PerObjectData.None;
- ref CameraData cameraData = ref renderingData.cameraData;
- Camera camera = cameraData.camera;
- context.DrawRenderers(renderingData.cullResults, ref drawSettings, ref m_FilteringSettings);
- }
- context.ExecuteCommandBuffer(cmd);
- CommandBufferPool.Release(cmd);
- }
- /// <inheritdoc/>
- public override void OnCameraCleanup(CommandBuffer cmd)
- {
- if (cmd == null)
- {
- throw new ArgumentNullException("cmd");
- }
- if (depthHandle != RenderTargetHandle.CameraTarget)
- {
- if (this.allocateNormal)
- cmd.ReleaseTemporaryRT(normalHandle.id);
- if (this.allocateDepth)
- cmd.ReleaseTemporaryRT(depthHandle.id);
- normalHandle = RenderTargetHandle.CameraTarget;
- depthHandle = RenderTargetHandle.CameraTarget;
- }
- }
- }
- }
|