123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- using System;
- using System.Collections.Generic;
- using UnityEngine.Experimental.Rendering;
-
- namespace UnityEngine.Rendering.Universal
- {
- /// <summary>
- /// Helper class for handling rendering layers.
- /// </summary>
- internal static class RenderingLayerUtils
- {
- public enum Event
- {
- DepthNormalPrePass,
- Opaque,
- }
-
- public enum MaskSize
- {
- Bits8,
- Bits16,
- Bits24,
- Bits32,
- }
-
- public static void CombineRendererEvents(bool isDeferred, int msaaSampleCount, Event rendererEvent, ref Event combinedEvent)
- {
- // Rendering layers can not use MSAA resolve, because it encodes integer
- if (msaaSampleCount > 1 && !isDeferred)
- combinedEvent = Event.DepthNormalPrePass;
-
- // Otherwise we combine them by selecting the min of the two...
- else
- combinedEvent = Combine(combinedEvent, rendererEvent);
- }
-
- /// <summary>
- /// Returns True if <see cref="UniversalRenderer"/> will require rendering layers texture.
- /// </summary>
- /// <param name="universalRenderer"></param>
- /// <param name="rendererFeatures">List of renderer features used by the renderer</param>
- /// <param name="msaaSampleCount">MSAA sample count</param>
- /// <param name="combinedEvent">Event at which rendering layers texture needs to be created</param>
- /// <param name="combinedMaskSize">The mask size of rendering layers texture</param>
- public static bool RequireRenderingLayers(UniversalRenderer universalRenderer, List<ScriptableRendererFeature> rendererFeatures, int msaaSampleCount, out Event combinedEvent, out MaskSize combinedMaskSize)
- {
- RenderingMode renderingMode = universalRenderer.renderingModeActual;
- bool accurateGBufferNormals = universalRenderer.accurateGbufferNormals;
- return RequireRenderingLayers(rendererFeatures, renderingMode, accurateGBufferNormals, msaaSampleCount,
- out combinedEvent, out combinedMaskSize);
- }
-
- internal static bool RequireRenderingLayers(List<ScriptableRendererFeature> rendererFeatures, RenderingMode renderingMode, bool accurateGbufferNormals, int msaaSampleCount, out Event combinedEvent, out MaskSize combinedMaskSize)
- {
- combinedEvent = Event.Opaque;
- combinedMaskSize = MaskSize.Bits8;
-
- bool isDeferred = renderingMode == RenderingMode.Deferred;
- bool result = false;
- foreach (var rendererFeature in rendererFeatures)
- {
- if (rendererFeature.isActive)
- {
- result |= rendererFeature.RequireRenderingLayers(isDeferred, accurateGbufferNormals, out Event rendererEvent, out MaskSize rendererMaskSize);
- combinedEvent = Combine(combinedEvent, rendererEvent);
- combinedMaskSize = Combine(combinedMaskSize, rendererMaskSize);
- }
- }
-
- // Rendering layers can not use MSAA resolve, because it encodes integer
- if (msaaSampleCount > 1 && combinedEvent == Event.Opaque)
- combinedEvent = Event.DepthNormalPrePass;
-
- // Make sure texture has enough bits to encode all rendering layers in urp global settings
- if (UniversalRenderPipelineGlobalSettings.instance)
- {
- int count = RenderingLayerMask.GetLastDefinedRenderingLayerIndex();
- MaskSize maskSize = GetMaskSize(count);
- combinedMaskSize = Combine(combinedMaskSize, maskSize);
- }
-
- return result;
- }
-
- /// <summary>
- /// Setups properties that are needed for accessing rendering layers texture.
- /// </summary>
- /// <param name="cmd">Used command buffer</param>
- /// <param name="maskSize">The mask size of rendering layers texture</param>
- public static void SetupProperties(CommandBuffer cmd, MaskSize maskSize) { SetupProperties(CommandBufferHelpers.GetRasterCommandBuffer(cmd), maskSize); }
- internal static void SetupProperties(RasterCommandBuffer cmd, MaskSize maskSize)
- {
- int bits = GetBits(maskSize);
-
- // Pre-computes properties used for packing/unpacking
- uint maxInt = bits != 32 ? (1u << bits) - 1u : uint.MaxValue;
- float rcpMaxInt = Unity.Mathematics.math.rcp(maxInt);
- cmd.SetGlobalInt(ShaderPropertyId.renderingLayerMaxInt, (int)maxInt);
- cmd.SetGlobalFloat(ShaderPropertyId.renderingLayerRcpMaxInt, rcpMaxInt);
- }
-
- /// <summary>
- /// Converts rendering layers texture mask size to graphics format.
- /// </summary>
- public static GraphicsFormat GetFormat(MaskSize maskSize)
- {
- switch (maskSize)
- {
- case MaskSize.Bits8:
- return GraphicsFormat.R8_UNorm;
- case MaskSize.Bits16:
- return GraphicsFormat.R16_UNorm;
- case MaskSize.Bits24:
- case MaskSize.Bits32:
- return GraphicsFormat.R32_SFloat;
- default:
- throw new NotImplementedException();
- }
- }
-
- /// <summary>
- /// Masks rendering layers with those that available in urp global settings.
- /// </summary>
- public static uint ToValidRenderingLayers(uint renderingLayers)
- {
- if (UniversalRenderPipelineGlobalSettings.instance)
- {
- uint validRenderingLayers = RenderingLayerMask.GetDefinedRenderingLayersCombinedMaskValue();
- return validRenderingLayers & renderingLayers;
- }
- return renderingLayers;
- }
-
- static MaskSize GetMaskSize(int bits)
- {
- int bytes = (bits + 7) / 8;
- switch (bytes)
- {
- case 0:
- return MaskSize.Bits8;
- case 1:
- return MaskSize.Bits8;
- case 2:
- return MaskSize.Bits16;
- case 3:
- return MaskSize.Bits24;
- case 4:
- return MaskSize.Bits32;
- default:
- return MaskSize.Bits32;
- }
- }
-
- static int GetBits(MaskSize maskSize)
- {
- switch (maskSize)
- {
- case MaskSize.Bits8:
- return 8;
- case MaskSize.Bits16:
- return 16;
- case MaskSize.Bits24:
- return 24;
- case MaskSize.Bits32:
- return 32;
- default:
- throw new NotImplementedException();
- }
- }
-
- static Event Combine(Event a, Event b)
- {
- return (Event)Mathf.Min((int)a, (int)b);
- }
-
- static MaskSize Combine(MaskSize a, MaskSize b)
- {
- return (MaskSize)Mathf.Max((int)a, (int)b);
- }
- }
- }
|