111
This commit is contained in:
185
Assets/ThirdParty/PostProcessing/Runtime/Components/AmbientOcclusionComponent.cs
vendored
Normal file
185
Assets/ThirdParty/PostProcessing/Runtime/Components/AmbientOcclusionComponent.cs
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user