Skip to content
This repository was archived by the owner on Nov 30, 2020. It is now read-only.

Commit b49af75

Browse files
committed
AO rework
- Improved "ambient-only" mode for the existing AO - Added a new Multi-scale Volumetric Obscurance method (Keijiro's version of MiniEngineAO) - Did some cleanup and made the initialization of PostProcessLayer more robust
1 parent 604369b commit b49af75

25 files changed

+2174
-155
lines changed

PostProcessing/Editor/Effects/BloomEditor.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public sealed class BloomEditor : PostProcessEffectEditor<Bloom>
1111
SerializedParameterOverride m_Diffusion;
1212
SerializedParameterOverride m_Color;
1313
SerializedParameterOverride m_MobileOptimized;
14-
14+
1515
SerializedParameterOverride m_LensTexture;
1616
SerializedParameterOverride m_LensIntensity;
1717

@@ -31,17 +31,17 @@ public override void OnEnable()
3131
public override void OnInspectorGUI()
3232
{
3333
EditorUtilities.DrawHeaderLabel("Bloom");
34-
34+
3535
PropertyField(m_Intensity);
3636
PropertyField(m_Threshold);
3737
PropertyField(m_SoftKnee);
3838
PropertyField(m_Diffusion);
3939
PropertyField(m_Color);
4040
PropertyField(m_MobileOptimized);
41-
41+
4242
EditorGUILayout.Space();
4343
EditorUtilities.DrawHeaderLabel("Lens Dirtiness");
44-
44+
4545
PropertyField(m_LensTexture);
4646
PropertyField(m_LensIntensity);
4747

PostProcessing/Editor/PostProcessLayerEditor.cs

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@ public sealed class PostProcessLayerEditor : BaseEditor<PostProcessLayer>
2727
SerializedProperty m_FxaaKeepAlpha;
2828

2929
SerializedProperty m_AOEnabled;
30-
SerializedProperty m_AOIntensity;
31-
SerializedProperty m_AORadius;
32-
SerializedProperty m_AOQuality;
30+
SerializedProperty m_AOMode;
31+
SerializedProperty m_SAOIntensity;
32+
SerializedProperty m_SAORadius;
33+
SerializedProperty m_SAOQuality;
34+
SerializedProperty m_MSVOIntensity;
35+
SerializedProperty m_MSVOThicknessModifier;
3336
SerializedProperty m_AOAmbientOnly;
3437

3538
SerializedProperty m_FogEnabled;
@@ -49,6 +52,12 @@ public sealed class PostProcessLayerEditor : BaseEditor<PostProcessLayer>
4952
new GUIContent("Temporal Anti-aliasing (TAA)")
5053
};
5154

55+
static GUIContent[] s_AmbientOcclusionMethodNames =
56+
{
57+
new GUIContent("Scalable Ambient Obscurance (Classic)"),
58+
new GUIContent("Multi-scale Volumetric Obscurance (Modern)")
59+
};
60+
5261
enum ExportMode
5362
{
5463
FullFrame,
@@ -70,12 +79,15 @@ void OnEnable()
7079
m_TaaMotionBlending = FindProperty(x => x.temporalAntialiasing.motionBlending);
7180
m_FxaaMobileOptimized = FindProperty(x => x.fastApproximateAntialiasing.mobileOptimized);
7281
m_FxaaKeepAlpha = FindProperty(x => x.fastApproximateAntialiasing.keepAlpha);
73-
82+
7483
m_AOEnabled = FindProperty(x => x.ambientOcclusion.enabled);
75-
m_AOIntensity = FindProperty(x => x.ambientOcclusion.intensity);
76-
m_AORadius = FindProperty(x => x.ambientOcclusion.radius);
77-
m_AOQuality = FindProperty(x => x.ambientOcclusion.quality);
84+
m_AOMode = FindProperty(x => x.ambientOcclusion.mode);
7885
m_AOAmbientOnly = FindProperty(x => x.ambientOcclusion.ambientOnly);
86+
m_SAOIntensity = FindProperty(x => x.ambientOcclusion.scalableAO.intensity);
87+
m_SAORadius = FindProperty(x => x.ambientOcclusion.scalableAO.radius);
88+
m_SAOQuality = FindProperty(x => x.ambientOcclusion.scalableAO.quality);
89+
m_MSVOIntensity = FindProperty(x => x.ambientOcclusion.multiScaleVO.intensity);
90+
m_MSVOThicknessModifier = FindProperty(x => x.ambientOcclusion.multiScaleVO.thicknessModifier);
7991

8092
m_FogEnabled = FindProperty(x => x.fog.enabled);
8193
m_FogExcludeSkybox = FindProperty(x => x.fog.excludeSkybox);
@@ -239,9 +251,20 @@ void DoAmbientOcclusion(Camera camera)
239251

240252
if (m_AOEnabled.boolValue)
241253
{
242-
EditorGUILayout.PropertyField(m_AOIntensity);
243-
EditorGUILayout.PropertyField(m_AORadius);
244-
EditorGUILayout.PropertyField(m_AOQuality);
254+
int aoMode = m_AOMode.intValue;
255+
m_AOMode.intValue = EditorGUILayout.Popup(EditorUtilities.GetContent("Mode|The ambient occlusion method to use. \"Modern\" is higher quality and faster on desktop & console platforms but requires compute shader support."), aoMode, s_AmbientOcclusionMethodNames);
256+
257+
if (aoMode == (int)AmbientOcclusion.Mode.SAO)
258+
{
259+
EditorGUILayout.PropertyField(m_SAOIntensity);
260+
EditorGUILayout.PropertyField(m_SAORadius);
261+
EditorGUILayout.PropertyField(m_SAOQuality);
262+
}
263+
else if (aoMode == (int)AmbientOcclusion.Mode.MSVO)
264+
{
265+
EditorGUILayout.PropertyField(m_MSVOIntensity);
266+
EditorGUILayout.PropertyField(m_MSVOThicknessModifier);
267+
}
245268

246269
if (camera != null && camera.actualRenderingPath == RenderingPath.DeferredShading && camera.allowHDR)
247270
EditorGUILayout.PropertyField(m_AOAmbientOnly);
636 Bytes
Binary file not shown.

PostProcessing/Runtime/Effects/AmbientOcclusion.cs

Lines changed: 32 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -2,160 +2,70 @@
22

33
namespace UnityEngine.Rendering.PostProcessing
44
{
5+
public interface IAmbientOcclusionMethod
6+
{
7+
DepthTextureMode GetCameraFlags();
8+
bool IsSupported(PostProcessRenderContext context);
9+
void RenderAfterOpaque(PostProcessRenderContext context);
10+
void RenderAmbientOnly(PostProcessRenderContext context);
11+
void CompositeAmbientOnly(PostProcessRenderContext context);
12+
void Release();
13+
}
14+
515
[Serializable]
616
public sealed class AmbientOcclusion
717
{
8-
// Unity sorts enums by value in the editor (and doesn't handle same-values enums very well
9-
// so we won't use enum values as sample counts this time
10-
public enum Quality
18+
public enum Mode
1119
{
12-
Lowest,
13-
Low,
14-
Medium,
15-
High,
16-
Ultra
20+
SAO,
21+
MSVO
1722
}
1823

1924
[Tooltip("Enables ambient occlusion.")]
2025
public bool enabled = false;
2126

22-
[Range(0f, 4f), Tooltip("Degree of darkness produced by the effect.")]
23-
public float intensity = 0.5f;
24-
25-
[Tooltip("Radius of sample points, which affects extent of darkened areas.")]
26-
public float radius = 0.25f;
27-
28-
[Tooltip("Number of sample points, which affects quality and performance. Lowest, Low & Medium passes are downsampled. High and Ultra are not and should only be used on high-end hardware.")]
29-
public Quality quality = Quality.Medium;
27+
public Mode mode = Mode.MSVO;
3028

3129
[Tooltip("Only affects 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.")]
3230
public bool ambientOnly = false;
3331

34-
readonly RenderTargetIdentifier[] m_MRT =
35-
{
36-
BuiltinRenderTextureType.GBuffer0, // Albedo, Occ
37-
BuiltinRenderTextureType.CameraTarget // Ambient
38-
};
32+
// Polymorphism doesn't play well with serialization in Unity so we have to keep explicit
33+
// references... Would be nice to have this more dynamic to allow user-custom AO methods.
34+
public ScalableAO scalableAO;
35+
public MultiScaleVO multiScaleVO;
3936

40-
readonly int[] m_SampleCount = { 4, 6, 10, 8, 12 };
37+
IAmbientOcclusionMethod[] m_Methods;
4138

42-
enum Pass
39+
public AmbientOcclusion()
4340
{
44-
OcclusionEstimationForward,
45-
OcclusionEstimationDeferred,
46-
HorizontalBlurForward,
47-
HorizontalBlurDeferred,
48-
VerticalBlur,
49-
CompositionForward,
50-
CompositionDeferred
41+
if (scalableAO == null) scalableAO = new ScalableAO();
42+
if (multiScaleVO == null) multiScaleVO = new MultiScaleVO();
43+
44+
m_Methods = new IAmbientOcclusionMethod[] { scalableAO, multiScaleVO };
5145
}
5246

53-
internal DepthTextureMode GetCameraFlags()
47+
public bool IsEnabledAndSupported(PostProcessRenderContext context)
5448
{
55-
return DepthTextureMode.Depth | DepthTextureMode.DepthNormals;
49+
return enabled && Get().IsSupported(context);
5650
}
5751

58-
internal bool IsAmbientOnly(PostProcessRenderContext context)
52+
public bool IsAmbientOnly(PostProcessRenderContext context)
5953
{
6054
var camera = context.camera;
6155
return ambientOnly
6256
&& camera.actualRenderingPath == RenderingPath.DeferredShading
6357
&& camera.allowHDR;
6458
}
6559

66-
internal bool IsEnabledAndSupported(PostProcessRenderContext context)
67-
{
68-
return enabled
69-
&& intensity > 0f
70-
&& !RuntimeUtilities.scriptableRenderPipelineActive;
71-
}
72-
73-
PropertySheet PreRender(PostProcessRenderContext context, int occlusionSource)
74-
{
75-
radius = Mathf.Max(radius, 1e-4f);
76-
var cmd = context.command;
77-
78-
// Material setup
79-
// Always use a quater-res AO buffer unless High/Ultra quality is set.
80-
bool downsampling = (int)quality < (int)Quality.High;
81-
float px = intensity;
82-
float py = radius;
83-
float pz = downsampling ? 0.5f : 1f;
84-
float pw = m_SampleCount[(int)quality];
85-
86-
var sheet = context.propertySheets.Get(context.resources.shaders.ambientOcclusion);
87-
sheet.ClearKeywords();
88-
sheet.properties.SetVector(ShaderIDs.AOParams, new Vector4(px, py, pz, pw));
89-
90-
// In forward fog is applied at the object level in the grometry pass so we need to
91-
// apply it to AO as well or it'll drawn on top of the fog effect.
92-
// Not needed in Deferred.
93-
if (context.camera.actualRenderingPath == RenderingPath.Forward && RenderSettings.fog)
94-
{
95-
sheet.properties.SetVector(ShaderIDs.FogParams, new Vector3(RenderSettings.fogDensity, RenderSettings.fogStartDistance, RenderSettings.fogEndDistance));
96-
97-
switch (RenderSettings.fogMode)
98-
{
99-
case FogMode.Linear:
100-
sheet.EnableKeyword("FOG_LINEAR");
101-
break;
102-
case FogMode.Exponential:
103-
sheet.EnableKeyword("FOG_EXP");
104-
break;
105-
case FogMode.ExponentialSquared:
106-
sheet.EnableKeyword("FOG_EXP2");
107-
break;
108-
}
109-
}
110-
111-
// Texture setup
112-
int tw = context.width;
113-
int th = context.height;
114-
int ts = downsampling ? 2 : 1;
115-
const RenderTextureFormat kFormat = RenderTextureFormat.ARGB32;
116-
const RenderTextureReadWrite kRWMode = RenderTextureReadWrite.Linear;
117-
const FilterMode kFilter = FilterMode.Bilinear;
118-
119-
// AO buffer
120-
var rtMask = ShaderIDs.OcclusionTexture1;
121-
cmd.GetTemporaryRT(rtMask, tw / ts, th / ts, 0, kFilter, kFormat, kRWMode);
122-
123-
// AO estimation
124-
cmd.BlitFullscreenTriangle(BuiltinRenderTextureType.None, rtMask, sheet, (int)Pass.OcclusionEstimationForward + occlusionSource);
125-
126-
// Blur buffer
127-
var rtBlur = ShaderIDs.OcclusionTexture2;
128-
129-
// Separable blur (horizontal pass)
130-
cmd.GetTemporaryRT(rtBlur, tw, th, 0, kFilter, kFormat, kRWMode);
131-
cmd.BlitFullscreenTriangle(rtMask, rtBlur, sheet, (int)Pass.HorizontalBlurForward + occlusionSource);
132-
cmd.ReleaseTemporaryRT(rtMask);
133-
134-
// Separable blur (vertical pass)
135-
rtMask = ShaderIDs.OcclusionTexture;
136-
cmd.GetTemporaryRT(rtMask, tw, th, 0, kFilter, kFormat, kRWMode);
137-
cmd.BlitFullscreenTriangle(rtBlur, rtMask, sheet, (int)Pass.VerticalBlur);
138-
cmd.ReleaseTemporaryRT(rtBlur);
139-
140-
return sheet;
141-
}
142-
143-
internal void RenderAfterOpaque(PostProcessRenderContext context)
60+
public IAmbientOcclusionMethod Get()
14461
{
145-
var cmd = context.command;
146-
cmd.BeginSample("Ambient Occlusion");
147-
var sheet = PreRender(context, 0); // Forward
148-
cmd.BlitFullscreenTriangle(context.source, context.destination, sheet, (int)Pass.CompositionForward);
149-
cmd.EndSample("Ambient Occlusion");
62+
return m_Methods[(int)mode];
15063
}
15164

152-
internal void RenderAmbientOnly(PostProcessRenderContext context)
65+
public void Release()
15366
{
154-
var cmd = context.command;
155-
cmd.BeginSample("Ambient Occlusion");
156-
var sheet = PreRender(context, 1); // Deferred
157-
cmd.BlitFullscreenTriangle(BuiltinRenderTextureType.None, m_MRT, BuiltinRenderTextureType.CameraTarget, sheet, (int)Pass.CompositionDeferred);
158-
cmd.EndSample("Ambient Occlusion");
67+
foreach (var m in m_Methods)
68+
m.Release();
15969
}
16070
}
16171
}

0 commit comments

Comments
 (0)