AmbientOcclusion.cs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. using System;
  2. namespace UnityEngine.Rendering.PostProcessing
  3. {
  4. /// <summary>
  5. /// Ambient occlusion modes.
  6. /// </summary>
  7. public enum AmbientOcclusionMode
  8. {
  9. /// <summary>
  10. /// A standard implementation of ambient obscurance that works on non modern platforms. If
  11. /// you target a compute-enabled platform we recommend that you use
  12. /// <see cref="MultiScaleVolumetricObscurance"/> instead.
  13. /// </summary>
  14. ScalableAmbientObscurance,
  15. /// <summary>
  16. /// A modern version of ambient occlusion heavily optimized for consoles and desktop
  17. /// platforms.
  18. /// </summary>
  19. MultiScaleVolumetricObscurance
  20. }
  21. /// <summary>
  22. /// Quality settings for <see cref="AmbientOcclusionMode.ScalableAmbientObscurance"/>.
  23. /// </summary>
  24. public enum AmbientOcclusionQuality
  25. {
  26. /// <summary>
  27. /// 4 samples + downsampling.
  28. /// </summary>
  29. Lowest,
  30. /// <summary>
  31. /// 6 samples + downsampling.
  32. /// </summary>
  33. Low,
  34. /// <summary>
  35. /// 10 samples + downsampling.
  36. /// </summary>
  37. Medium,
  38. /// <summary>
  39. /// 8 samples.
  40. /// </summary>
  41. High,
  42. /// <summary>
  43. /// 12 samples.
  44. /// </summary>
  45. Ultra
  46. }
  47. /// <summary>
  48. /// A volume parameter holding a <see cref="AmbientOcclusionMode"/> value.
  49. /// </summary>
  50. [Serializable]
  51. public sealed class AmbientOcclusionModeParameter : ParameterOverride<AmbientOcclusionMode> {}
  52. /// <summary>
  53. /// A volume parameter holding a <see cref="AmbientOcclusionQuality"/> value.
  54. /// </summary>
  55. [Serializable]
  56. public sealed class AmbientOcclusionQualityParameter : ParameterOverride<AmbientOcclusionQuality> {}
  57. /// <summary>
  58. /// This class holds settings for the Ambient Occlusion effect.
  59. /// </summary>
  60. [Serializable]
  61. [PostProcess(typeof(AmbientOcclusionRenderer), "Unity/Ambient Occlusion")]
  62. public sealed class AmbientOcclusion : PostProcessEffectSettings
  63. {
  64. // Shared parameters
  65. /// <summary>
  66. /// The ambient occlusion method to use.
  67. /// </summary>
  68. [Tooltip("The ambient occlusion method to use. \"Multi Scale Volumetric Obscurance\" is higher quality and faster on desktop & console platforms but requires compute shader support.")]
  69. public AmbientOcclusionModeParameter mode = new AmbientOcclusionModeParameter { value = AmbientOcclusionMode.MultiScaleVolumetricObscurance };
  70. /// <summary>
  71. /// The degree of darkness added by ambient occlusion.
  72. /// </summary>
  73. [Range(0f, 4f), Tooltip("The degree of darkness added by ambient occlusion. Higher values produce darker areas.")]
  74. public FloatParameter intensity = new FloatParameter { value = 0f };
  75. /// <summary>
  76. /// A custom color to use for the ambient occlusion.
  77. /// </summary>
  78. [ColorUsage(false), Tooltip("The custom color to use for the ambient occlusion. The default is black.")]
  79. public ColorParameter color = new ColorParameter { value = Color.black };
  80. /// <summary>
  81. /// Only affects ambient lighting. This mode is only available with the Deferred rendering
  82. /// path and HDR rendering. Objects rendered with the Forward rendering path won't get any
  83. /// ambient occlusion.
  84. /// </summary>
  85. [Tooltip("Check this box to mark this Volume as to only affect ambient lighting. This mode is only available with the Deferred rendering path and HDR rendering. Objects rendered with the Forward rendering path won't get any ambient occlusion.")]
  86. public BoolParameter ambientOnly = new BoolParameter { value = true };
  87. // MSVO-only parameters
  88. /// <summary>
  89. /// The tolerance of the noise filter to changes in the depth pyramid.
  90. /// </summary>
  91. [Range(-8f, 0f)]
  92. public FloatParameter noiseFilterTolerance = new FloatParameter { value = 0f }; // Hidden
  93. /// <summary>
  94. /// The tolerance of the bilateral blur filter to depth changes.
  95. /// </summary>
  96. [Range(-8f, -1f)]
  97. public FloatParameter blurTolerance = new FloatParameter { value = -4.6f }; // Hidden
  98. /// <summary>
  99. /// The tolerance of the upsampling pass to depth changes.
  100. /// </summary>
  101. [Range(-12f, -1f)]
  102. public FloatParameter upsampleTolerance = new FloatParameter { value = -12f }; // Hidden
  103. /// <summary>
  104. /// Modifies the thickness of occluders. This increases dark areas but also introduces dark
  105. /// halo around objects.
  106. /// </summary>
  107. [Range(1f, 10f), Tooltip("This modifies the thickness of occluders. It increases the size of dark areas and also introduces a dark halo around objects.")]
  108. public FloatParameter thicknessModifier = new FloatParameter { value = 1f };
  109. // HDRP-only parameters
  110. /// <summary>
  111. /// Modifies he influence of direct lighting on ambient occlusion. This is only used in the
  112. /// HD Render Pipeline currently.
  113. /// </summary>
  114. [Range(0f, 1f), Tooltip("Modifies the influence of direct lighting on ambient occlusion.")]
  115. public FloatParameter directLightingStrength = new FloatParameter { value = 0f };
  116. // SAO-only parameters
  117. /// <summary>
  118. /// Radius of sample points, which affects extent of darkened areas.
  119. /// </summary>
  120. [Tooltip("The radius of sample points. This affects the size of darkened areas.")]
  121. public FloatParameter radius = new FloatParameter { value = 0.25f };
  122. /// <summary>
  123. /// The number of sample points, which affects quality and performance. Lowest, Low & Medium
  124. /// passes are downsampled. High and Ultra are not and should only be used on high-end
  125. /// hardware.
  126. /// </summary>
  127. [Tooltip("The number of sample points. This affects both quality and performance. For \"Lowest\", \"Low\", and \"Medium\", passes are downsampled. For \"High\" and \"Ultra\", they are not and therefore you should only \"High\" and \"Ultra\" on high-end hardware.")]
  128. public AmbientOcclusionQualityParameter quality = new AmbientOcclusionQualityParameter { value = AmbientOcclusionQuality.Medium };
  129. // SRPs can call this method without a context set (see HDRP).
  130. // We need a better way to handle this than checking for a null context, context should
  131. // never be null.
  132. /// <inheritdoc />
  133. public override bool IsEnabledAndSupported(PostProcessRenderContext context)
  134. {
  135. bool state = enabled.value
  136. && intensity.value > 0f;
  137. if (mode.value == AmbientOcclusionMode.ScalableAmbientObscurance)
  138. {
  139. state &= !RuntimeUtilities.scriptableRenderPipelineActive;
  140. if (context != null)
  141. {
  142. state &= context.resources.shaders.scalableAO
  143. && context.resources.shaders.scalableAO.isSupported;
  144. }
  145. }
  146. else if (mode.value == AmbientOcclusionMode.MultiScaleVolumetricObscurance)
  147. {
  148. #if UNITY_2017_1_OR_NEWER
  149. if (context != null)
  150. {
  151. state &= context.resources.shaders.multiScaleAO
  152. && context.resources.shaders.multiScaleAO.isSupported
  153. && context.resources.computeShaders.multiScaleAODownsample1
  154. && context.resources.computeShaders.multiScaleAODownsample2
  155. && context.resources.computeShaders.multiScaleAORender
  156. && context.resources.computeShaders.multiScaleAOUpsample;
  157. }
  158. state &= SystemInfo.supportsComputeShaders
  159. && !RuntimeUtilities.isAndroidOpenGL
  160. && RenderTextureFormat.RFloat.IsSupported()
  161. && RenderTextureFormat.RHalf.IsSupported()
  162. && RenderTextureFormat.R8.IsSupported();
  163. #else
  164. state = false;
  165. #endif
  166. }
  167. return state;
  168. }
  169. }
  170. internal interface IAmbientOcclusionMethod
  171. {
  172. DepthTextureMode GetCameraFlags();
  173. void RenderAfterOpaque(PostProcessRenderContext context);
  174. void RenderAmbientOnly(PostProcessRenderContext context);
  175. void CompositeAmbientOnly(PostProcessRenderContext context);
  176. void Release();
  177. }
  178. internal sealed class AmbientOcclusionRenderer : PostProcessEffectRenderer<AmbientOcclusion>
  179. {
  180. IAmbientOcclusionMethod[] m_Methods;
  181. public override void Init()
  182. {
  183. if (m_Methods == null)
  184. {
  185. m_Methods = new IAmbientOcclusionMethod[]
  186. {
  187. new ScalableAO(settings),
  188. new MultiScaleVO(settings),
  189. };
  190. }
  191. }
  192. public bool IsAmbientOnly(PostProcessRenderContext context)
  193. {
  194. var camera = context.camera;
  195. return settings.ambientOnly.value
  196. && camera.actualRenderingPath == RenderingPath.DeferredShading
  197. && camera.allowHDR;
  198. }
  199. public IAmbientOcclusionMethod Get()
  200. {
  201. return m_Methods[(int)settings.mode.value];
  202. }
  203. public override DepthTextureMode GetCameraFlags()
  204. {
  205. return Get().GetCameraFlags();
  206. }
  207. public override void Release()
  208. {
  209. foreach (var m in m_Methods)
  210. m.Release();
  211. }
  212. public ScalableAO GetScalableAO()
  213. {
  214. return (ScalableAO)m_Methods[(int)AmbientOcclusionMode.ScalableAmbientObscurance];
  215. }
  216. public MultiScaleVO GetMultiScaleVO()
  217. {
  218. return (MultiScaleVO)m_Methods[(int)AmbientOcclusionMode.MultiScaleVolumetricObscurance];
  219. }
  220. // Unused
  221. public override void Render(PostProcessRenderContext context)
  222. {
  223. }
  224. }
  225. }