Нет описания
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

RenderingLayerUtils.cs 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine.Experimental.Rendering;
  4. namespace UnityEngine.Rendering.Universal
  5. {
  6. /// <summary>
  7. /// Helper class for handling rendering layers.
  8. /// </summary>
  9. internal static class RenderingLayerUtils
  10. {
  11. public enum Event
  12. {
  13. DepthNormalPrePass,
  14. Opaque,
  15. }
  16. public enum MaskSize
  17. {
  18. Bits8,
  19. Bits16,
  20. Bits24,
  21. Bits32,
  22. }
  23. public static void CombineRendererEvents(bool isDeferred, int msaaSampleCount, Event rendererEvent, ref Event combinedEvent)
  24. {
  25. // Rendering layers can not use MSAA resolve, because it encodes integer
  26. if (msaaSampleCount > 1 && !isDeferred)
  27. combinedEvent = Event.DepthNormalPrePass;
  28. // Otherwise we combine them by selecting the min of the two...
  29. else
  30. combinedEvent = Combine(combinedEvent, rendererEvent);
  31. }
  32. /// <summary>
  33. /// Returns True if <see cref="UniversalRenderer"/> will require rendering layers texture.
  34. /// </summary>
  35. /// <param name="universalRenderer"></param>
  36. /// <param name="rendererFeatures">List of renderer features used by the renderer</param>
  37. /// <param name="msaaSampleCount">MSAA sample count</param>
  38. /// <param name="combinedEvent">Event at which rendering layers texture needs to be created</param>
  39. /// <param name="combinedMaskSize">The mask size of rendering layers texture</param>
  40. public static bool RequireRenderingLayers(UniversalRenderer universalRenderer, List<ScriptableRendererFeature> rendererFeatures, int msaaSampleCount, out Event combinedEvent, out MaskSize combinedMaskSize)
  41. {
  42. RenderingMode renderingMode = universalRenderer.renderingModeActual;
  43. bool accurateGBufferNormals = universalRenderer.accurateGbufferNormals;
  44. return RequireRenderingLayers(rendererFeatures, renderingMode, accurateGBufferNormals, msaaSampleCount,
  45. out combinedEvent, out combinedMaskSize);
  46. }
  47. internal static bool RequireRenderingLayers(List<ScriptableRendererFeature> rendererFeatures, RenderingMode renderingMode, bool accurateGbufferNormals, int msaaSampleCount, out Event combinedEvent, out MaskSize combinedMaskSize)
  48. {
  49. combinedEvent = Event.Opaque;
  50. combinedMaskSize = MaskSize.Bits8;
  51. bool isDeferred = renderingMode == RenderingMode.Deferred;
  52. bool result = false;
  53. foreach (var rendererFeature in rendererFeatures)
  54. {
  55. if (rendererFeature.isActive)
  56. {
  57. result |= rendererFeature.RequireRenderingLayers(isDeferred, accurateGbufferNormals, out Event rendererEvent, out MaskSize rendererMaskSize);
  58. combinedEvent = Combine(combinedEvent, rendererEvent);
  59. combinedMaskSize = Combine(combinedMaskSize, rendererMaskSize);
  60. }
  61. }
  62. // Rendering layers can not use MSAA resolve, because it encodes integer
  63. if (msaaSampleCount > 1 && combinedEvent == Event.Opaque)
  64. combinedEvent = Event.DepthNormalPrePass;
  65. // Make sure texture has enough bits to encode all rendering layers in urp global settings
  66. if (UniversalRenderPipelineGlobalSettings.instance)
  67. {
  68. int count = RenderingLayerMask.GetLastDefinedRenderingLayerIndex();
  69. MaskSize maskSize = GetMaskSize(count);
  70. combinedMaskSize = Combine(combinedMaskSize, maskSize);
  71. }
  72. return result;
  73. }
  74. /// <summary>
  75. /// Setups properties that are needed for accessing rendering layers texture.
  76. /// </summary>
  77. /// <param name="cmd">Used command buffer</param>
  78. /// <param name="maskSize">The mask size of rendering layers texture</param>
  79. public static void SetupProperties(CommandBuffer cmd, MaskSize maskSize) { SetupProperties(CommandBufferHelpers.GetRasterCommandBuffer(cmd), maskSize); }
  80. internal static void SetupProperties(RasterCommandBuffer cmd, MaskSize maskSize)
  81. {
  82. int bits = GetBits(maskSize);
  83. // Pre-computes properties used for packing/unpacking
  84. uint maxInt = bits != 32 ? (1u << bits) - 1u : uint.MaxValue;
  85. float rcpMaxInt = Unity.Mathematics.math.rcp(maxInt);
  86. cmd.SetGlobalInt(ShaderPropertyId.renderingLayerMaxInt, (int)maxInt);
  87. cmd.SetGlobalFloat(ShaderPropertyId.renderingLayerRcpMaxInt, rcpMaxInt);
  88. }
  89. /// <summary>
  90. /// Converts rendering layers texture mask size to graphics format.
  91. /// </summary>
  92. public static GraphicsFormat GetFormat(MaskSize maskSize)
  93. {
  94. switch (maskSize)
  95. {
  96. case MaskSize.Bits8:
  97. return GraphicsFormat.R8_UNorm;
  98. case MaskSize.Bits16:
  99. return GraphicsFormat.R16_UNorm;
  100. case MaskSize.Bits24:
  101. case MaskSize.Bits32:
  102. return GraphicsFormat.R32_SFloat;
  103. default:
  104. throw new NotImplementedException();
  105. }
  106. }
  107. /// <summary>
  108. /// Masks rendering layers with those that available in urp global settings.
  109. /// </summary>
  110. public static uint ToValidRenderingLayers(uint renderingLayers)
  111. {
  112. if (UniversalRenderPipelineGlobalSettings.instance)
  113. {
  114. uint validRenderingLayers = RenderingLayerMask.GetDefinedRenderingLayersCombinedMaskValue();
  115. return validRenderingLayers & renderingLayers;
  116. }
  117. return renderingLayers;
  118. }
  119. static MaskSize GetMaskSize(int bits)
  120. {
  121. int bytes = (bits + 7) / 8;
  122. switch (bytes)
  123. {
  124. case 0:
  125. return MaskSize.Bits8;
  126. case 1:
  127. return MaskSize.Bits8;
  128. case 2:
  129. return MaskSize.Bits16;
  130. case 3:
  131. return MaskSize.Bits24;
  132. case 4:
  133. return MaskSize.Bits32;
  134. default:
  135. return MaskSize.Bits32;
  136. }
  137. }
  138. static int GetBits(MaskSize maskSize)
  139. {
  140. switch (maskSize)
  141. {
  142. case MaskSize.Bits8:
  143. return 8;
  144. case MaskSize.Bits16:
  145. return 16;
  146. case MaskSize.Bits24:
  147. return 24;
  148. case MaskSize.Bits32:
  149. return 32;
  150. default:
  151. throw new NotImplementedException();
  152. }
  153. }
  154. static Event Combine(Event a, Event b)
  155. {
  156. return (Event)Mathf.Min((int)a, (int)b);
  157. }
  158. static MaskSize Combine(MaskSize a, MaskSize b)
  159. {
  160. return (MaskSize)Mathf.Max((int)a, (int)b);
  161. }
  162. }
  163. }