-
Notifications
You must be signed in to change notification settings - Fork 872
Expand file tree
/
Copy pathAmbientOcclusion.cs
More file actions
280 lines (239 loc) · 11.1 KB
/
AmbientOcclusion.cs
File metadata and controls
280 lines (239 loc) · 11.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
using System;
using UnityEngine.Experimental.Rendering;
namespace UnityEngine.Rendering.PostProcessing
{
/// <summary>
/// Ambient occlusion modes.
/// </summary>
public enum AmbientOcclusionMode
{
/// <summary>
/// A standard implementation of ambient obscurance that works on non modern platforms. If
/// you target a compute-enabled platform we recommend that you use
/// <see cref="MultiScaleVolumetricObscurance"/> instead.
/// </summary>
ScalableAmbientObscurance,
/// <summary>
/// A modern version of ambient occlusion heavily optimized for consoles and desktop
/// platforms.
/// </summary>
MultiScaleVolumetricObscurance
}
/// <summary>
/// Quality settings for <see cref="AmbientOcclusionMode.ScalableAmbientObscurance"/>.
/// </summary>
public enum AmbientOcclusionQuality
{
/// <summary>
/// 4 samples + downsampling.
/// </summary>
Lowest,
/// <summary>
/// 6 samples + downsampling.
/// </summary>
Low,
/// <summary>
/// 10 samples + downsampling.
/// </summary>
Medium,
/// <summary>
/// 8 samples.
/// </summary>
High,
/// <summary>
/// 12 samples.
/// </summary>
Ultra
}
/// <summary>
/// A volume parameter holding a <see cref="AmbientOcclusionMode"/> value.
/// </summary>
[Serializable]
public sealed class AmbientOcclusionModeParameter : ParameterOverride<AmbientOcclusionMode> { }
/// <summary>
/// A volume parameter holding a <see cref="AmbientOcclusionQuality"/> value.
/// </summary>
[Serializable]
public sealed class AmbientOcclusionQualityParameter : ParameterOverride<AmbientOcclusionQuality> { }
/// <summary>
/// This class holds settings for the Ambient Occlusion effect.
/// </summary>
[Serializable]
[PostProcess(typeof(AmbientOcclusionRenderer), "Unity/Ambient Occlusion")]
public sealed class AmbientOcclusion : PostProcessEffectSettings
{
// Shared parameters
/// <summary>
/// The ambient occlusion method to use.
/// </summary>
[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.")]
public AmbientOcclusionModeParameter mode = new AmbientOcclusionModeParameter { value = AmbientOcclusionMode.MultiScaleVolumetricObscurance };
/// <summary>
/// The degree of darkness added by ambient occlusion.
/// </summary>
[Range(0f, 4f), Tooltip("The degree of darkness added by ambient occlusion. Higher values produce darker areas.")]
public FloatParameter intensity = new FloatParameter { value = 0f };
/// <summary>
/// A custom color to use for the ambient occlusion.
/// </summary>
[ColorUsage(false), Tooltip("The custom color to use for the ambient occlusion. The default is black.")]
public ColorParameter color = new ColorParameter { value = Color.black };
/// <summary>
/// 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.
/// </summary>
[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.")]
public BoolParameter ambientOnly = new BoolParameter { value = true };
// MSVO-only parameters
/// <summary>
/// The tolerance of the noise filter to changes in the depth pyramid.
/// </summary>
[Range(-8f, 0f)]
public FloatParameter noiseFilterTolerance = new FloatParameter { value = 0f }; // Hidden
/// <summary>
/// The tolerance of the bilateral blur filter to depth changes.
/// </summary>
[Range(-8f, -1f)]
public FloatParameter blurTolerance = new FloatParameter { value = -4.6f }; // Hidden
/// <summary>
/// The tolerance of the upsampling pass to depth changes.
/// </summary>
[Range(-12f, -1f)]
public FloatParameter upsampleTolerance = new FloatParameter { value = -12f }; // Hidden
/// <summary>
/// Modifies the thickness of occluders. This increases dark areas but also introduces dark
/// halo around objects.
/// </summary>
[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.")]
public FloatParameter thicknessModifier = new FloatParameter { value = 1f };
/// <summary>
/// Add a bias distance to sampled depth in AO to reduce self-shadowing aliasing artifacts.
/// </summary>
[Range(0f, 0.001f), Tooltip("Add a bias distance to sampled depth in AO to reduce self-shadowing aliasing artifacts. ")]
public FloatParameter zBias = new FloatParameter { value = 0.0001f };
// HDRP-only parameters
/// <summary>
/// Modifies he influence of direct lighting on ambient occlusion. This is only used in the
/// HD Render Pipeline currently.
/// </summary>
[Range(0f, 1f), Tooltip("Modifies the influence of direct lighting on ambient occlusion.")]
public FloatParameter directLightingStrength = new FloatParameter { value = 0f };
// SAO-only parameters
/// <summary>
/// Radius of sample points, which affects extent of darkened areas.
/// </summary>
[Tooltip("The radius of sample points. This affects the size of darkened areas.")]
public FloatParameter radius = new FloatParameter { value = 0.25f };
/// <summary>
/// The number of sample points, which affects quality and performance. Lowest, Low and Medium
/// passes are downsampled. High and Ultra are not and should only be used on high-end
/// hardware.
/// </summary>
[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.")]
public AmbientOcclusionQualityParameter quality = new AmbientOcclusionQualityParameter { value = AmbientOcclusionQuality.Medium };
// SRPs can call this method without a context set (see HDRP).
// We need a better way to handle this than checking for a null context, context should
// never be null.
/// <summary>
/// Returns <c>true</c> if the effect is currently enabled and supported.
/// </summary>
/// <param name="context">The current post-processing render context</param>
/// <returns><c>true</c> if the effect is currently enabled and supported</returns>
public override bool IsEnabledAndSupported(PostProcessRenderContext context)
{
bool state = enabled.value
&& intensity.value > 0f;
if (mode.value == AmbientOcclusionMode.ScalableAmbientObscurance)
{
state &= !RuntimeUtilities.scriptableRenderPipelineActive;
if (context != null)
{
state &= context.resources.shaders.scalableAO
&& context.resources.shaders.scalableAO.isSupported;
}
}
else if (mode.value == AmbientOcclusionMode.MultiScaleVolumetricObscurance)
{
if (context != null)
{
state &= context.resources.shaders.multiScaleAO
&& context.resources.shaders.multiScaleAO.isSupported
&& context.resources.computeShaders.multiScaleAODownsample1
&& context.resources.computeShaders.multiScaleAODownsample2
&& context.resources.computeShaders.multiScaleAORender
&& context.resources.computeShaders.multiScaleAOUpsample;
}
state &= SystemInfo.supportsComputeShaders
&& !RuntimeUtilities.isOpenGLES
&& !RuntimeUtilities.isWebNonWebGPU
#if UNITY_2023_2_OR_NEWER
&& SystemInfo.IsFormatSupported(GraphicsFormat.R32_SFloat, GraphicsFormatUsage.Render)
&& SystemInfo.IsFormatSupported(GraphicsFormat.R16_SFloat, GraphicsFormatUsage.Render)
&& SystemInfo.IsFormatSupported(GraphicsFormat.R8_UNorm, GraphicsFormatUsage.Render);
#else
&& SystemInfo.IsFormatSupported(GraphicsFormat.R32_SFloat, FormatUsage.Render)
&& SystemInfo.IsFormatSupported(GraphicsFormat.R16_SFloat, FormatUsage.Render)
&& SystemInfo.IsFormatSupported(GraphicsFormat.R8_UNorm, FormatUsage.Render);
#endif
}
return state;
}
}
internal interface IAmbientOcclusionMethod
{
DepthTextureMode GetCameraFlags();
void RenderAfterOpaque(PostProcessRenderContext context);
void RenderAmbientOnly(PostProcessRenderContext context);
void CompositeAmbientOnly(PostProcessRenderContext context);
void Release();
}
[UnityEngine.Scripting.Preserve]
internal sealed class AmbientOcclusionRenderer : PostProcessEffectRenderer<AmbientOcclusion>
{
IAmbientOcclusionMethod[] m_Methods;
public override void Init()
{
if (m_Methods == null)
{
m_Methods = new IAmbientOcclusionMethod[]
{
new ScalableAO(settings),
new MultiScaleVO(settings),
};
}
}
public bool IsAmbientOnly(PostProcessRenderContext context)
{
var camera = context.camera;
return settings.ambientOnly.value
&& camera.actualRenderingPath == RenderingPath.DeferredShading
&& camera.allowHDR;
}
public IAmbientOcclusionMethod Get()
{
return m_Methods[(int)settings.mode.value];
}
public override DepthTextureMode GetCameraFlags()
{
return Get().GetCameraFlags();
}
public override void Release()
{
foreach (var m in m_Methods)
m.Release();
}
public ScalableAO GetScalableAO()
{
return (ScalableAO)m_Methods[(int)AmbientOcclusionMode.ScalableAmbientObscurance];
}
public MultiScaleVO GetMultiScaleVO()
{
return (MultiScaleVO)m_Methods[(int)AmbientOcclusionMode.MultiScaleVolumetricObscurance];
}
// Unused
public override void Render(PostProcessRenderContext context)
{
}
}
}