123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- using UnityEngine.Rendering;
- namespace UnityEngine.PostProcessing
- {
- using DebugMode = BuiltinDebugViewsModel.Mode;
- public sealed class AmbientOcclusionComponent : PostProcessingComponentCommandBuffer<AmbientOcclusionModel>
- {
- 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");
- }
- const string k_BlitShaderString = "Hidden/Post FX/Blit";
- const string k_ShaderString = "Hidden/Post FX/Ambient Occlusion";
- readonly RenderTargetIdentifier[] m_MRT =
- {
- BuiltinRenderTextureType.GBuffer0, // Albedo, Occ
- BuiltinRenderTextureType.CameraTarget // Ambient
- };
- enum OcclusionSource
- {
- DepthTexture,
- DepthNormalsTexture,
- GBuffer
- }
- OcclusionSource occlusionSource
- {
- get
- {
- if (context.isGBufferAvailable && !model.settings.forceForwardCompatibility)
- return OcclusionSource.GBuffer;
- if (model.settings.highPrecision && (!context.isGBufferAvailable || model.settings.forceForwardCompatibility))
- return OcclusionSource.DepthTexture;
- return OcclusionSource.DepthNormalsTexture;
- }
- }
- bool ambientOnlySupported
- {
- get { return context.isHdr && model.settings.ambientOnly && context.isGBufferAvailable && !model.settings.forceForwardCompatibility; }
- }
- public override bool active
- {
- get
- {
- return model.enabled
- && model.settings.intensity > 0f
- && !context.interrupted;
- }
- }
- public override DepthTextureMode GetCameraFlags()
- {
- var flags = DepthTextureMode.None;
- if (occlusionSource == OcclusionSource.DepthTexture)
- flags |= DepthTextureMode.Depth;
- if (occlusionSource != OcclusionSource.GBuffer)
- flags |= DepthTextureMode.DepthNormals;
- return flags;
- }
- public override string GetName()
- {
- return "Ambient Occlusion";
- }
- public override CameraEvent GetCameraEvent()
- {
- return ambientOnlySupported && !context.profile.debugViews.IsModeActive(DebugMode.AmbientOcclusion)
- ? CameraEvent.BeforeReflections
- : CameraEvent.BeforeImageEffectsOpaque;
- }
- public override void PopulateCommandBuffer(CommandBuffer cb)
- {
- var settings = model.settings;
- // Material setup
- var blitMaterial = context.materialFactory.Get(k_BlitShaderString);
- var material = context.materialFactory.Get(k_ShaderString);
- material.shaderKeywords = null;
- material.SetFloat(Uniforms._Intensity, settings.intensity);
- material.SetFloat(Uniforms._Radius, settings.radius);
- material.SetFloat(Uniforms._Downsample, settings.downsampling ? 0.5f : 1f);
- 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 tw = context.width;
- int th = context.height;
- int ts = settings.downsampling ? 2 : 1;
- const RenderTextureFormat kFormat = RenderTextureFormat.ARGB32;
- const RenderTextureReadWrite kRWMode = RenderTextureReadWrite.Linear;
- const FilterMode kFilter = FilterMode.Bilinear;
- // AO buffer
- var rtMask = Uniforms._OcclusionTexture1;
- cb.GetTemporaryRT(rtMask, tw / ts, th / ts, 0, kFilter, kFormat, kRWMode);
- // AO estimation
- cb.Blit((Texture)null, rtMask, material, (int)occlusionSource);
- // Blur buffer
- var rtBlur = Uniforms._OcclusionTexture2;
- // Separable blur (horizontal pass)
- cb.GetTemporaryRT(rtBlur, tw, th, 0, kFilter, kFormat, kRWMode);
- cb.SetGlobalTexture(Uniforms._MainTex, rtMask);
- cb.Blit(rtMask, rtBlur, material, occlusionSource == OcclusionSource.GBuffer ? 4 : 3);
- cb.ReleaseTemporaryRT(rtMask);
- // Separable blur (vertical pass)
- rtMask = Uniforms._OcclusionTexture;
- cb.GetTemporaryRT(rtMask, tw, th, 0, kFilter, kFormat, kRWMode);
- cb.SetGlobalTexture(Uniforms._MainTex, rtBlur);
- cb.Blit(rtBlur, rtMask, material, 5);
- cb.ReleaseTemporaryRT(rtBlur);
- if (context.profile.debugViews.IsModeActive(DebugMode.AmbientOcclusion))
- {
- cb.SetGlobalTexture(Uniforms._MainTex, rtMask);
- cb.Blit(rtMask, 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
- {
- var fbFormat = context.isHdr ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;
- int tempRT = Uniforms._TempRT;
- cb.GetTemporaryRT(tempRT, context.width, context.height, 0, FilterMode.Bilinear, fbFormat);
- cb.Blit(BuiltinRenderTextureType.CameraTarget, tempRT, blitMaterial, 0);
- cb.SetGlobalTexture(Uniforms._MainTex, tempRT);
- cb.Blit(tempRT, BuiltinRenderTextureType.CameraTarget, material, 6);
- cb.ReleaseTemporaryRT(tempRT);
- }
- cb.ReleaseTemporaryRT(rtMask);
- }
- }
- }
|