summaryrefslogtreecommitdiff
path: root/UnityEngine.PostProcessing/AmbientOcclusionComponent.cs
diff options
context:
space:
mode:
Diffstat (limited to 'UnityEngine.PostProcessing/AmbientOcclusionComponent.cs')
-rw-r--r--UnityEngine.PostProcessing/AmbientOcclusionComponent.cs160
1 files changed, 160 insertions, 0 deletions
diff --git a/UnityEngine.PostProcessing/AmbientOcclusionComponent.cs b/UnityEngine.PostProcessing/AmbientOcclusionComponent.cs
new file mode 100644
index 0000000..d1dbda2
--- /dev/null
+++ b/UnityEngine.PostProcessing/AmbientOcclusionComponent.cs
@@ -0,0 +1,160 @@
+using UnityEngine.Rendering;
+
+namespace UnityEngine.PostProcessing;
+
+public sealed class AmbientOcclusionComponent : PostProcessingComponentCommandBuffer<AmbientOcclusionModel>
+{
+ private static class Uniforms
+ {
+ internal static readonly int _Intensity = Shader.PropertyToID("_Intensity");
+
+ internal static readonly int _Radius = Shader.PropertyToID("_Radius");
+
+ internal static readonly int _FogParams = Shader.PropertyToID("_FogParams");
+
+ internal static readonly int _Downsample = Shader.PropertyToID("_Downsample");
+
+ internal static readonly int _SampleCount = Shader.PropertyToID("_SampleCount");
+
+ internal static readonly int _OcclusionTexture1 = Shader.PropertyToID("_OcclusionTexture1");
+
+ internal static readonly int _OcclusionTexture2 = Shader.PropertyToID("_OcclusionTexture2");
+
+ internal static readonly int _OcclusionTexture = Shader.PropertyToID("_OcclusionTexture");
+
+ internal static readonly int _MainTex = Shader.PropertyToID("_MainTex");
+
+ internal static readonly int _TempRT = Shader.PropertyToID("_TempRT");
+ }
+
+ private enum OcclusionSource
+ {
+ DepthTexture,
+ DepthNormalsTexture,
+ GBuffer
+ }
+
+ private const string k_BlitShaderString = "Hidden/Post FX/Blit";
+
+ private const string k_ShaderString = "Hidden/Post FX/Ambient Occlusion";
+
+ private readonly RenderTargetIdentifier[] m_MRT = new RenderTargetIdentifier[2]
+ {
+ BuiltinRenderTextureType.GBuffer0,
+ BuiltinRenderTextureType.CameraTarget
+ };
+
+ private OcclusionSource occlusionSource
+ {
+ get
+ {
+ if (context.isGBufferAvailable && !base.model.settings.forceForwardCompatibility)
+ {
+ return OcclusionSource.GBuffer;
+ }
+ if (base.model.settings.highPrecision && (!context.isGBufferAvailable || base.model.settings.forceForwardCompatibility))
+ {
+ return OcclusionSource.DepthTexture;
+ }
+ return OcclusionSource.DepthNormalsTexture;
+ }
+ }
+
+ private bool ambientOnlySupported => context.isHdr && base.model.settings.ambientOnly && context.isGBufferAvailable && !base.model.settings.forceForwardCompatibility;
+
+ public override bool active => base.model.enabled && base.model.settings.intensity > 0f && !context.interrupted;
+
+ public override DepthTextureMode GetCameraFlags()
+ {
+ DepthTextureMode depthTextureMode = DepthTextureMode.None;
+ if (occlusionSource == OcclusionSource.DepthTexture)
+ {
+ depthTextureMode |= DepthTextureMode.Depth;
+ }
+ if (occlusionSource != OcclusionSource.GBuffer)
+ {
+ depthTextureMode |= DepthTextureMode.DepthNormals;
+ }
+ return depthTextureMode;
+ }
+
+ public override string GetName()
+ {
+ return "Ambient Occlusion";
+ }
+
+ public override CameraEvent GetCameraEvent()
+ {
+ return (!ambientOnlySupported || context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.AmbientOcclusion)) ? CameraEvent.BeforeImageEffectsOpaque : CameraEvent.BeforeReflections;
+ }
+
+ public override void PopulateCommandBuffer(CommandBuffer cb)
+ {
+ AmbientOcclusionModel.Settings settings = base.model.settings;
+ Material mat = context.materialFactory.Get("Hidden/Post FX/Blit");
+ Material material = context.materialFactory.Get("Hidden/Post FX/Ambient Occlusion");
+ material.shaderKeywords = null;
+ material.SetFloat(Uniforms._Intensity, settings.intensity);
+ material.SetFloat(Uniforms._Radius, settings.radius);
+ material.SetFloat(Uniforms._Downsample, (!settings.downsampling) ? 1f : 0.5f);
+ material.SetInt(Uniforms._SampleCount, (int)settings.sampleCount);
+ if (!context.isGBufferAvailable && RenderSettings.fog)
+ {
+ material.SetVector(Uniforms._FogParams, new Vector3(RenderSettings.fogDensity, RenderSettings.fogStartDistance, RenderSettings.fogEndDistance));
+ switch (RenderSettings.fogMode)
+ {
+ case FogMode.Linear:
+ material.EnableKeyword("FOG_LINEAR");
+ break;
+ case FogMode.Exponential:
+ material.EnableKeyword("FOG_EXP");
+ break;
+ case FogMode.ExponentialSquared:
+ material.EnableKeyword("FOG_EXP2");
+ break;
+ }
+ }
+ else
+ {
+ material.EnableKeyword("FOG_OFF");
+ }
+ int width = context.width;
+ int height = context.height;
+ int num = ((!settings.downsampling) ? 1 : 2);
+ int occlusionTexture = Uniforms._OcclusionTexture1;
+ cb.GetTemporaryRT(occlusionTexture, width / num, height / num, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
+ cb.Blit(null, occlusionTexture, material, (int)occlusionSource);
+ int occlusionTexture2 = Uniforms._OcclusionTexture2;
+ cb.GetTemporaryRT(occlusionTexture2, width, height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
+ cb.SetGlobalTexture(Uniforms._MainTex, occlusionTexture);
+ cb.Blit(occlusionTexture, occlusionTexture2, material, (occlusionSource != OcclusionSource.GBuffer) ? 3 : 4);
+ cb.ReleaseTemporaryRT(occlusionTexture);
+ occlusionTexture = Uniforms._OcclusionTexture;
+ cb.GetTemporaryRT(occlusionTexture, width, height, 0, FilterMode.Bilinear, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
+ cb.SetGlobalTexture(Uniforms._MainTex, occlusionTexture2);
+ cb.Blit(occlusionTexture2, occlusionTexture, material, 5);
+ cb.ReleaseTemporaryRT(occlusionTexture2);
+ if (context.profile.debugViews.IsModeActive(BuiltinDebugViewsModel.Mode.AmbientOcclusion))
+ {
+ cb.SetGlobalTexture(Uniforms._MainTex, occlusionTexture);
+ cb.Blit(occlusionTexture, BuiltinRenderTextureType.CameraTarget, material, 8);
+ context.Interrupt();
+ }
+ else if (ambientOnlySupported)
+ {
+ cb.SetRenderTarget(m_MRT, BuiltinRenderTextureType.CameraTarget);
+ cb.DrawMesh(GraphicsUtils.quad, Matrix4x4.identity, material, 0, 7);
+ }
+ else
+ {
+ RenderTextureFormat format = ((!context.isHdr) ? RenderTextureFormat.Default : RenderTextureFormat.DefaultHDR);
+ int tempRT = Uniforms._TempRT;
+ cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Bilinear, format);
+ cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, mat, 0);
+ cb.SetGlobalTexture(Uniforms._MainTex, tempRT);
+ cb.Blit(tempRT, BuiltinRenderTextureType.CameraTarget, material, 6);
+ cb.ReleaseTemporaryRT(tempRT);
+ }
+ cb.ReleaseTemporaryRT(occlusionTexture);
+ }
+}