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

Commit 4f1bdd7

Browse files
committed
Merge branch 'ssr' into v2
2 parents b5ff284 + c8e9a32 commit 4f1bdd7

39 files changed

Lines changed: 1794 additions & 16 deletions

PostProcessing/Editor/PostProcessLayerEditor.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@
55
using UnityEngine.Rendering.PostProcessing;
66
using UnityEditorInternal;
77
using System.IO;
8+
using ScreenSpaceReflections = UnityEngine.Rendering.PostProcessing.ScreenSpaceReflections;
89

910
namespace UnityEditor.Rendering.PostProcessing
1011
{
1112
using SerializedBundleRef = PostProcessLayer.SerializedBundleRef;
1213
using EXRFlags = Texture2D.EXRFlags;
14+
using SSRPreset = UnityEngine.Rendering.PostProcessing.ScreenSpaceReflections.Preset;
1315

1416
[CanEditMultipleObjects, CustomEditor(typeof(PostProcessLayer))]
1517
public sealed class PostProcessLayerEditor : BaseEditor<PostProcessLayer>
@@ -65,6 +67,15 @@ void OnEnable()
6567
m_FxaaMobileOptimized = FindProperty(x => x.fastApproximateAntialiasing.mobileOptimized);
6668
m_FxaaKeepAlpha = FindProperty(x => x.fastApproximateAntialiasing.keepAlpha);
6769

70+
m_SSREnabled = FindProperty(x => x.screenSpaceReflections.enabled);
71+
m_SSRPreset = FindProperty(x => x.screenSpaceReflections.preset);
72+
m_SSRMaximumIterationCount = FindProperty(x => x.screenSpaceReflections.maximumIterationCount);
73+
m_SSRResolution = FindProperty(x => x.screenSpaceReflections.resolution);
74+
m_SSRThickness = FindProperty(x => x.screenSpaceReflections.thickness);
75+
m_SSRMaximumMarchDistance = FindProperty(x => x.screenSpaceReflections.maximumMarchDistance);
76+
m_SSRDistanceFade = FindProperty(x => x.screenSpaceReflections.distanceFade);
77+
m_SSRAttenuation = FindProperty(x => x.screenSpaceReflections.attenuation);
78+
6879
m_FogEnabled = FindProperty(x => x.fog.enabled);
6980
m_FogExcludeSkybox = FindProperty(x => x.fog.excludeSkybox);
7081

PostProcessing/Runtime/Effects/Dithering.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public sealed class Dithering
1010

1111
internal void Render(PostProcessRenderContext context)
1212
{
13-
var blueNoise = context.resources.blueNoise;
13+
var blueNoise = context.resources.blueNoise64;
1414
Assert.IsTrue(blueNoise != null && blueNoise.Length > 0);
1515

1616
#if POSTFX_DEBUG_STATIC_DITHERING // Used by QA for automated testing
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
using System;
2+
using UnityEngine.Assertions;
3+
4+
namespace UnityEngine.Rendering.PostProcessing
5+
{
6+
[Serializable]
7+
public sealed class ScreenSpaceReflections
8+
{
9+
public enum Preset
10+
{
11+
Lower,
12+
Low,
13+
Medium,
14+
High,
15+
Higher,
16+
Ultra,
17+
Overkill,
18+
Custom
19+
}
20+
21+
public enum Resolution
22+
{
23+
Downsampled,
24+
FullSize,
25+
Supersampled
26+
}
27+
28+
[Tooltip("Enables screen-space reflections.")]
29+
public bool enabled;
30+
31+
[Tooltip("Choose a quality preset, or use \"Custom\" to fine tune it. Don't use a preset higher than \"Medium\" if you care about performances on consoles.")]
32+
public Preset preset = Preset.Medium;
33+
34+
[Range(0, 256), Tooltip("Maximum iteration count.")]
35+
public int maximumIterationCount;
36+
37+
[Tooltip("Changes the size of the SSR buffer. Downsample it to maximize performances or supersample it to get slow but higher quality results.")]
38+
public Resolution resolution = Resolution.Downsampled;
39+
40+
[Range(1f, 64f), Tooltip("Ray thickness. Lower values are more expensive but allow the effect to detect smaller details.")]
41+
public float thickness = 8f;
42+
43+
[Tooltip("Maximum distance to traverse after which it will stop drawing reflections.")]
44+
public float maximumMarchDistance = 100f;
45+
46+
[Range(0f, 1f), Tooltip("Fades reflections close to the near planes.")]
47+
public float distanceFade = 0.5f;
48+
49+
[Range(0f, 1f), Tooltip("Fades reflections close to the screen borders.")]
50+
public float attenuation = 0.25f;
51+
52+
class QualityPreset
53+
{
54+
public int maximumIterationCount;
55+
public float thickness;
56+
public Resolution downsampling;
57+
}
58+
59+
QualityPreset[] m_Presets =
60+
{
61+
new QualityPreset { maximumIterationCount = 10, thickness = 32, downsampling = Resolution.Downsampled }, // Lower
62+
new QualityPreset { maximumIterationCount = 16, thickness = 32, downsampling = Resolution.Downsampled }, // Low
63+
new QualityPreset { maximumIterationCount = 32, thickness = 16, downsampling = Resolution.Downsampled }, // Medium
64+
new QualityPreset { maximumIterationCount = 48, thickness = 8, downsampling = Resolution.Downsampled }, // High
65+
new QualityPreset { maximumIterationCount = 16, thickness = 32, downsampling = Resolution.FullSize }, // Higher
66+
new QualityPreset { maximumIterationCount = 48, thickness = 16, downsampling = Resolution.FullSize }, // Ultra
67+
new QualityPreset { maximumIterationCount = 128, thickness = 12, downsampling = Resolution.Supersampled }, // Overkill
68+
};
69+
70+
RenderTexture m_Test;
71+
RenderTexture m_Resolve;
72+
RenderTexture m_History;
73+
int[] m_MipIDs;
74+
75+
bool m_ResetHistory = true;
76+
77+
enum Pass
78+
{
79+
Test,
80+
Resolve,
81+
Reproject,
82+
Composite
83+
}
84+
85+
internal bool IsEnabledAndSupported(PostProcessRenderContext context)
86+
{
87+
return enabled
88+
&& context.camera.actualRenderingPath == RenderingPath.DeferredShading
89+
&& SystemInfo.supportsMotionVectors
90+
&& SystemInfo.supportsComputeShaders
91+
&& SystemInfo.copyTextureSupport > CopyTextureSupport.None;
92+
}
93+
94+
internal DepthTextureMode GetCameraFlags()
95+
{
96+
return DepthTextureMode.Depth | DepthTextureMode.MotionVectors;
97+
}
98+
99+
internal void CheckRT(ref RenderTexture rt, int width, int height, RenderTextureFormat format, FilterMode filterMode, bool useMipMap)
100+
{
101+
if (rt == null || !rt.IsCreated() || rt.width != width || rt.height != height)
102+
{
103+
if (rt != null)
104+
rt.Release();
105+
106+
rt = new RenderTexture(width, height, 0, format)
107+
{
108+
filterMode = filterMode,
109+
useMipMap = useMipMap,
110+
autoGenerateMips = false,
111+
hideFlags = HideFlags.HideAndDontSave
112+
};
113+
114+
rt.Create();
115+
}
116+
}
117+
118+
internal void Render(PostProcessRenderContext context)
119+
{
120+
var cmd = context.command;
121+
cmd.BeginSample("Screen-space Reflections");
122+
123+
// Get quality settings
124+
if (preset != Preset.Custom)
125+
{
126+
int id = (int)preset;
127+
maximumIterationCount = m_Presets[id].maximumIterationCount;
128+
thickness = m_Presets[id].thickness;
129+
resolution = m_Presets[id].downsampling;
130+
}
131+
132+
maximumMarchDistance = Mathf.Max(0f, maximumMarchDistance);
133+
134+
// Square POT target
135+
int size = Mathf.ClosestPowerOfTwo(Mathf.Min(context.width, context.height));
136+
137+
if (resolution == Resolution.Downsampled)
138+
size >>= 1;
139+
else if (resolution == Resolution.Supersampled)
140+
size <<= 1;
141+
142+
// The gaussian pyramid compute works in blocks of 8x8 so make sure the last lod has a
143+
// minimum size of 8x8
144+
const int kMaxLods = 12;
145+
int lodCount = Mathf.FloorToInt(Mathf.Log(size, 2f) - 3f);
146+
lodCount = Mathf.Min(lodCount, kMaxLods);
147+
148+
CheckRT(ref m_Resolve, size, size, context.sourceFormat, FilterMode.Trilinear, true);
149+
CheckRT(ref m_History, size, size, context.sourceFormat, FilterMode.Bilinear, false);
150+
151+
if (m_ResetHistory)
152+
{
153+
context.command.BlitFullscreenTriangle(context.source, m_History);
154+
m_ResetHistory = false;
155+
}
156+
157+
var noiseTex = context.resources.blueNoise256[0];
158+
var sheet = context.propertySheets.Get(context.resources.shaders.screenSpaceReflections);
159+
sheet.properties.SetTexture(ShaderIDs.Noise, noiseTex);
160+
161+
var screenSpaceProjectionMatrix = new Matrix4x4();
162+
screenSpaceProjectionMatrix.SetRow(0, new Vector4(size * 0.5f, 0f, 0f, size * 0.5f));
163+
screenSpaceProjectionMatrix.SetRow(1, new Vector4(0f, size * 0.5f, 0f, size * 0.5f));
164+
screenSpaceProjectionMatrix.SetRow(2, new Vector4(0f, 0f, 1f, 0f));
165+
screenSpaceProjectionMatrix.SetRow(3, new Vector4(0f, 0f, 0f, 1f));
166+
167+
var projectionMatrix = GL.GetGPUProjectionMatrix(context.camera.projectionMatrix, false);
168+
screenSpaceProjectionMatrix *= projectionMatrix;
169+
170+
sheet.properties.SetMatrix(ShaderIDs.ViewMatrix, context.camera.worldToCameraMatrix);
171+
sheet.properties.SetMatrix(ShaderIDs.InverseViewMatrix, context.camera.worldToCameraMatrix.inverse);
172+
sheet.properties.SetMatrix(ShaderIDs.InverseProjectionMatrix, projectionMatrix.inverse);
173+
sheet.properties.SetMatrix(ShaderIDs.ScreenSpaceProjectionMatrix, screenSpaceProjectionMatrix);
174+
sheet.properties.SetVector(ShaderIDs.Params, new Vector4(attenuation, distanceFade, maximumMarchDistance, lodCount));
175+
sheet.properties.SetVector(ShaderIDs.Params2, new Vector4((float)context.width / (float)context.height, (float)size / (float)noiseTex.width, thickness, maximumIterationCount));
176+
177+
cmd.GetTemporaryRT(ShaderIDs.Test, size, size, 0, FilterMode.Point, context.sourceFormat);
178+
cmd.BlitFullscreenTriangle(context.source, ShaderIDs.Test, sheet, (int)Pass.Test);
179+
180+
cmd.GetTemporaryRT(ShaderIDs.SSRResolveTemp, size, size, 0, FilterMode.Bilinear, context.sourceFormat);
181+
cmd.BlitFullscreenTriangle(context.source, ShaderIDs.SSRResolveTemp, sheet, (int)Pass.Resolve);
182+
183+
sheet.properties.SetTexture(ShaderIDs.History, m_History);
184+
cmd.BlitFullscreenTriangle(ShaderIDs.SSRResolveTemp, m_Resolve, sheet, (int)Pass.Reproject);
185+
186+
cmd.ReleaseTemporaryRT(ShaderIDs.Test);
187+
cmd.ReleaseTemporaryRT(ShaderIDs.SSRResolveTemp);
188+
189+
cmd.CopyTexture(m_Resolve, 0, 0, m_History, 0, 0);
190+
191+
// Pre-cache mipmaps ids
192+
if (m_MipIDs == null || m_MipIDs.Length == 0)
193+
{
194+
m_MipIDs = new int[kMaxLods];
195+
196+
for (int i = 0; i < kMaxLods; i++)
197+
m_MipIDs[i] = Shader.PropertyToID("_SSRGaussianMip" + i);
198+
}
199+
200+
var compute = context.resources.computeShaders.gaussianDownsample;
201+
int kernel = compute.FindKernel("KMain");
202+
203+
var last = new RenderTargetIdentifier(m_Resolve);
204+
205+
for (int i = 0; i < lodCount; i++)
206+
{
207+
size >>= 1;
208+
Assert.IsTrue(size > 0);
209+
210+
cmd.GetTemporaryRT(m_MipIDs[i], size, size, 0, FilterMode.Bilinear, context.sourceFormat, RenderTextureReadWrite.Default, 1, true);
211+
cmd.SetComputeTextureParam(compute, kernel, "_Source", last);
212+
cmd.SetComputeTextureParam(compute, kernel, "_Result", m_MipIDs[i]);
213+
cmd.SetComputeVectorParam(compute, "_Size", new Vector4(size, size, 1f / size, 1f / size));
214+
cmd.DispatchCompute(compute, kernel, size / 8, size / 8, 1);
215+
cmd.CopyTexture(m_MipIDs[i], 0, 0, m_Resolve, 0, i + 1);
216+
217+
last = m_MipIDs[i];
218+
}
219+
220+
for (int i = 0; i < lodCount; i++)
221+
cmd.ReleaseTemporaryRT(m_MipIDs[i]);
222+
223+
sheet.properties.SetTexture(ShaderIDs.Resolve, m_Resolve);
224+
cmd.BlitFullscreenTriangle(context.source, context.destination, sheet, (int)Pass.Composite);
225+
cmd.EndSample("Screen-space Reflections");
226+
}
227+
228+
internal void Release()
229+
{
230+
RuntimeUtilities.Destroy(m_Test);
231+
RuntimeUtilities.Destroy(m_Resolve);
232+
RuntimeUtilities.Destroy(m_History);
233+
m_Test = null;
234+
m_Resolve = null;
235+
m_History = null;
236+
}
237+
238+
internal void ResetHistory()
239+
{
240+
m_ResetHistory = true;
241+
}
242+
}
243+
}

PostProcessing/Runtime/Effects/ScreenSpaceReflections.cs.meta

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

PostProcessing/Runtime/PostProcessLayer.cs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public enum Antialiasing
2929
public TemporalAntialiasing temporalAntialiasing;
3030
public SubpixelMorphologicalAntialiasing subpixelMorphologicalAntialiasing;
3131
public FastApproximateAntialiasing fastApproximateAntialiasing;
32+
public ScreenSpaceReflections screenSpaceReflections;
3233
public Fog fog;
3334
public Dithering dithering;
3435

@@ -137,8 +138,8 @@ void OnEnable()
137138
public void Init(PostProcessResources resources)
138139
{
139140
if (resources != null) m_Resources = resources;
140-
141-
RuntimeUtilities.CreateIfNull(ref debugLayer);
141+
142+
RuntimeUtilities.CreateIfNull(ref screenSpaceReflections);
142143
RuntimeUtilities.CreateIfNull(ref temporalAntialiasing);
143144
RuntimeUtilities.CreateIfNull(ref subpixelMorphologicalAntialiasing);
144145
RuntimeUtilities.CreateIfNull(ref fastApproximateAntialiasing);
@@ -226,6 +227,7 @@ void OnDisable()
226227
}
227228

228229
temporalAntialiasing.Release();
230+
screenSpaceReflections.Release();
229231
m_LogHistogram.Release();
230232

231233
foreach (var bundle in m_Bundles.Values)
@@ -270,7 +272,7 @@ void OnPreCull()
270272
context.Reset();
271273
context.camera = m_Camera;
272274
context.sourceFormat = sourceFormat;
273-
275+
274276
m_LegacyCmdBufferBeforeReflections.Clear();
275277
m_LegacyCmdBufferBeforeLighting.Clear();
276278
m_LegacyCmdBufferOpaque.Clear();
@@ -289,6 +291,7 @@ void OnPreCull()
289291
bool aoAmbientOnly = aoRenderer.IsAmbientOnly(context);
290292
bool isAmbientOcclusionDeferred = aoSupported && aoAmbientOnly;
291293
bool isAmbientOcclusionOpaque = aoSupported && !aoAmbientOnly;
294+
bool isScreenSpaceReflectionsActive = screenSpaceReflections.IsEnabledAndSupported(context);
292295
bool isFogActive = fog.IsEnabledAndSupported(context);
293296

294297
// Ambient-only AO is a special case and has to be done in separate command buffers
@@ -310,6 +313,7 @@ void OnPreCull()
310313
aoRenderer.Get().RenderAfterOpaque(context);
311314
}
312315

316+
opaqueOnlyEffects += isScreenSpaceReflectionsActive ? 1 : 0;
313317
opaqueOnlyEffects += isFogActive ? 1 : 0;
314318
opaqueOnlyEffects += hasCustomOpaqueOnlyEffects ? 1 : 0;
315319

@@ -337,7 +341,14 @@ void OnPreCull()
337341
}
338342
else context.destination = cameraTarget;
339343

340-
// TODO: Insert SSR here
344+
if (isScreenSpaceReflectionsActive)
345+
{
346+
screenSpaceReflections.Render(context);
347+
opaqueOnlyEffects--;
348+
var prevSource = context.source;
349+
context.source = context.destination;
350+
context.destination = opaqueOnlyEffects == 1 ? cameraTarget : prevSource;
351+
}
341352

342353
if (isFogActive)
343354
{
@@ -373,14 +384,14 @@ void OnPreCull()
373384
}
374385

375386
void OnPostRender()
376-
{
377-
// Unused in scriptable render pipelines
378-
if (RuntimeUtilities.scriptableRenderPipelineActive)
379-
return;
380-
381-
if (m_CurrentContext.IsTemporalAntialiasingActive())
382-
m_Camera.ResetProjectionMatrix();
383-
}
387+
{
388+
// Unused in scriptable render pipelines
389+
if (RuntimeUtilities.scriptableRenderPipelineActive)
390+
return;
391+
392+
if (m_CurrentContext.IsTemporalAntialiasingActive())
393+
m_Camera.ResetProjectionMatrix();
394+
}
384395

385396
PostProcessBundle GetBundle<T>()
386397
where T : PostProcessEffectSettings
@@ -451,6 +462,7 @@ public void ResetHistory()
451462
bundle.Value.ResetHistory();
452463

453464
temporalAntialiasing.ResetHistory();
465+
screenSpaceReflections.ResetHistory();
454466
}
455467

456468
public bool HasOpaqueOnlyEffects(PostProcessRenderContext context)

0 commit comments

Comments
 (0)