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

Commit b33291d

Browse files
committed
Added a NaN killer; Layer UI cleanup for upcoming AO & SSR
1 parent 671d187 commit b33291d

5 files changed

Lines changed: 143 additions & 27 deletions

File tree

PostProcessing/Editor/PostProcessLayerEditor.cs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace UnityEditor.Rendering.PostProcessing
1414
[CustomEditor(typeof(PostProcessLayer))]
1515
public sealed class PostProcessLayerEditor : BaseEditor<PostProcessLayer>
1616
{
17+
SerializedProperty m_StopNaNPropagation;
1718
SerializedProperty m_VolumeTrigger;
1819
SerializedProperty m_VolumeLayer;
1920

@@ -23,7 +24,7 @@ public sealed class PostProcessLayerEditor : BaseEditor<PostProcessLayer>
2324
SerializedProperty m_TaaStationaryBlending;
2425
SerializedProperty m_TaaMotionBlending;
2526
SerializedProperty m_FxaaMobileOptimized;
26-
27+
2728
SerializedProperty m_AOEnabled;
2829
SerializedProperty m_AOIntensity;
2930
SerializedProperty m_AORadius;
@@ -32,7 +33,8 @@ public sealed class PostProcessLayerEditor : BaseEditor<PostProcessLayer>
3233

3334
SerializedProperty m_FogEnabled;
3435
SerializedProperty m_FogExcludeSkybox;
35-
36+
37+
SerializedProperty m_ShowRenderingFeatures;
3638
SerializedProperty m_ShowToolkit;
3739
SerializedProperty m_ShowCustomSorter;
3840

@@ -56,6 +58,7 @@ enum ExportMode
5658

5759
void OnEnable()
5860
{
61+
m_StopNaNPropagation = FindProperty(x => x.stopNaNPropagation);
5962
m_VolumeTrigger = FindProperty(x => x.volumeTrigger);
6063
m_VolumeLayer = FindProperty(x => x.volumeLayer);
6164

@@ -65,7 +68,7 @@ void OnEnable()
6568
m_TaaStationaryBlending = FindProperty(x => x.temporalAntialiasing.stationaryBlending);
6669
m_TaaMotionBlending = FindProperty(x => x.temporalAntialiasing.motionBlending);
6770
m_FxaaMobileOptimized = FindProperty(x => x.fastApproximateAntialiasing.mobileOptimized);
68-
71+
6972
m_AOEnabled = FindProperty(x => x.ambientOcclusion.enabled);
7073
m_AOIntensity = FindProperty(x => x.ambientOcclusion.intensity);
7174
m_AORadius = FindProperty(x => x.ambientOcclusion.radius);
@@ -75,6 +78,7 @@ void OnEnable()
7578
m_FogEnabled = FindProperty(x => x.fog.enabled);
7679
m_FogExcludeSkybox = FindProperty(x => x.fog.excludeSkybox);
7780

81+
m_ShowRenderingFeatures = serializedObject.FindProperty("m_ShowRenderingFeatures");
7882
m_ShowToolkit = serializedObject.FindProperty("m_ShowToolkit");
7983
m_ShowCustomSorter = serializedObject.FindProperty("m_ShowCustomSorter");
8084

@@ -90,7 +94,7 @@ void OnEnable()
9094
{
9195
var bundles = m_Target.sortedBundles[evt];
9296
var listName = ObjectNames.NicifyVariableName(evt.ToString());
93-
97+
9498
var list = new ReorderableList(bundles, typeof(SerializedBundleRef), true, true, false, false);
9599

96100
list.drawHeaderCallback = (rect) =>
@@ -121,13 +125,16 @@ void OnDisable()
121125
public override void OnInspectorGUI()
122126
{
123127
serializedObject.Update();
124-
128+
125129
var camera = m_Target.GetComponent<Camera>();
126130

127131
DoVolumeBlending();
128132
DoAntialiasing();
129-
DoAmbientOcclusion(camera);
130-
DoFog(camera);
133+
134+
EditorGUILayout.PropertyField(m_StopNaNPropagation, EditorUtilities.GetContent("Stop NaN Propagation|Automatically replaces NaN/Inf in shaders by a black pixel to avoid breaking some effects. This will slightly affect performances and should only be used if you experience NaN issues that you can't fix."));
135+
EditorGUILayout.Space();
136+
137+
DoRenderingFeatures(camera);
131138
DoToolkit();
132139
DoCustomEffectSorter();
133140

@@ -203,11 +210,25 @@ void DoAntialiasing()
203210
EditorGUILayout.Space();
204211
}
205212

206-
void DoAmbientOcclusion(Camera camera)
213+
void DoRenderingFeatures(Camera camera)
207214
{
208215
if (RuntimeUtilities.scriptableRenderPipelineActive)
209216
return;
210217

218+
EditorUtilities.DrawSplitter();
219+
m_ShowRenderingFeatures.boolValue = EditorUtilities.DrawHeader("Rendering Features", m_ShowRenderingFeatures.boolValue);
220+
221+
if (m_ShowRenderingFeatures.boolValue)
222+
{
223+
GUILayout.Space(2);
224+
225+
DoAmbientOcclusion(camera);
226+
DoFog(camera);
227+
}
228+
}
229+
230+
void DoAmbientOcclusion(Camera camera)
231+
{
211232
EditorGUILayout.LabelField(EditorUtilities.GetContent("Ambient Occlusion"), EditorStyles.boldLabel);
212233
EditorGUI.indentLevel++;
213234
{
@@ -218,7 +239,7 @@ void DoAmbientOcclusion(Camera camera)
218239
EditorGUILayout.PropertyField(m_AOIntensity);
219240
EditorGUILayout.PropertyField(m_AORadius);
220241
EditorGUILayout.PropertyField(m_AOQuality);
221-
242+
222243
if (camera != null && camera.actualRenderingPath == RenderingPath.DeferredShading && camera.allowHDR)
223244
EditorGUILayout.PropertyField(m_AOAmbientOnly);
224245
}
@@ -230,9 +251,6 @@ void DoAmbientOcclusion(Camera camera)
230251

231252
void DoFog(Camera camera)
232253
{
233-
if (RuntimeUtilities.scriptableRenderPipelineActive)
234-
return;
235-
236254
if (camera == null || camera.actualRenderingPath != RenderingPath.DeferredShading)
237255
return;
238256

PostProcessing/Runtime/PostProcessLayer.cs

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public enum Antialiasing
2323
// Settings
2424
public Transform volumeTrigger;
2525
public LayerMask volumeLayer;
26+
public bool stopNaNPropagation = true;
2627

2728
// Builtins / hardcoded effects that don't benefit from volume blending
2829
public Antialiasing antialiasingMode = Antialiasing.None;
@@ -39,7 +40,7 @@ public enum Antialiasing
3940
PostProcessResources m_Resources;
4041

4142
// UI states
42-
[SerializeField] bool m_ShowDebugLayer;
43+
[SerializeField] bool m_ShowRenderingFeatures;
4344
[SerializeField] bool m_ShowToolkit;
4445
[SerializeField] bool m_ShowCustomSorter;
4546

@@ -94,6 +95,8 @@ public sealed class SerializedBundleRef
9495

9596
TargetPool m_TargetPool;
9697

98+
bool m_NaNKilled = false;
99+
97100
// Recycled list - used to reduce GC stress when gathering active effects in a bundle list
98101
// on each frame
99102
readonly List<PostProcessEffectRenderer> m_ActiveEffects = new List<PostProcessEffectRenderer>();
@@ -157,7 +160,7 @@ public void InitBundles()
157160
UpdateBundleSortList(m_BeforeStackBundles, PostProcessEvent.BeforeStack);
158161
UpdateBundleSortList(m_AfterStackBundles, PostProcessEvent.AfterStack);
159162

160-
// Push all sorted lists in a dictionary for easier access
163+
// Push all sorted lists in a dictionary for easier access
161164
sortedBundles = new Dictionary<PostProcessEvent, List<SerializedBundleRef>>(new PostProcessEventComparer())
162165
{
163166
{ PostProcessEvent.BeforeTransparent, m_BeforeTransparentBundles },
@@ -275,10 +278,10 @@ void OnPreCull()
275278
{
276279
opaqueOnlyEffects++;
277280
}
278-
281+
279282
opaqueOnlyEffects += isFogActive ? 1 : 0;
280283
opaqueOnlyEffects += hasCustomOpaqueOnlyEffects ? 1 : 0;
281-
284+
282285
var cameraTarget = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget);
283286

284287
if (opaqueOnlyEffects > 0)
@@ -336,13 +339,18 @@ void OnPreCull()
336339

337340
cmd.ReleaseTemporaryRT(tempTarget0);
338341
}
339-
342+
340343
// Post-transparency stack
344+
// Same as before, first blit needs to use the builtin Blit command to properly handle
345+
// tiled GPUs
341346
int tempRt = m_TargetPool.Get();
347+
342348
m_LegacyCmdBuffer.GetTemporaryRT(tempRt, context.width, context.height, 24, FilterMode.Bilinear, sourceFormat);
343-
m_LegacyCmdBuffer.Blit(cameraTarget, tempRt);
349+
m_LegacyCmdBuffer.Blit(cameraTarget, tempRt, RuntimeUtilities.copyMaterial, stopNaNPropagation ? 3 : 2);
350+
m_NaNKilled = stopNaNPropagation;
351+
344352
context.command = m_LegacyCmdBuffer;
345-
context.source = new RenderTargetIdentifier(tempRt);
353+
context.source = tempRt;
346354
context.destination = cameraTarget;
347355
Render(context);
348356
m_LegacyCmdBuffer.ReleaseTemporaryRT(tempRt);
@@ -514,8 +522,18 @@ public void Render(PostProcessRenderContext context)
514522
// hasn't been called this frame.
515523
UpdateSettingsIfNeeded(context);
516524

517-
// Do temporal anti-aliasing first
525+
// Do a NaN killing pass if needed
518526
int lastTarget = -1;
527+
if (stopNaNPropagation && !m_NaNKilled)
528+
{
529+
lastTarget = m_TargetPool.Get();
530+
cmd.GetTemporaryRT(lastTarget, context.width, context.height, 24, FilterMode.Bilinear, context.sourceFormat);
531+
cmd.BlitFullscreenTriangle(context.source, lastTarget, RuntimeUtilities.copySheet, 1);
532+
context.source = lastTarget;
533+
m_NaNKilled = true;
534+
}
535+
536+
// Do temporal anti-aliasing first
519537
if (context.IsTemporalAntialiasingActive())
520538
{
521539
if (!RuntimeUtilities.scriptableRenderPipelineActive)
@@ -526,13 +544,18 @@ public void Render(PostProcessRenderContext context)
526544
camera.useJitteredProjectionMatrixForTransparentRendering = false;
527545
}
528546

529-
lastTarget = m_TargetPool.Get();
547+
var taaTarget = m_TargetPool.Get();
530548
var finalDestination = context.destination;
531-
cmd.GetTemporaryRT(lastTarget, context.width, context.height, 24, FilterMode.Bilinear, context.sourceFormat);
532-
context.destination = lastTarget;
549+
cmd.GetTemporaryRT(taaTarget, context.width, context.height, 24, FilterMode.Bilinear, context.sourceFormat);
550+
context.destination = taaTarget;
533551
temporalAntialiasing.Render(context);
534-
context.source = lastTarget;
552+
context.source = taaTarget;
535553
context.destination = finalDestination;
554+
555+
if (lastTarget > -1)
556+
cmd.ReleaseTemporaryRT(lastTarget);
557+
558+
lastTarget = taaTarget;
536559
}
537560

538561
bool hasBeforeStackEffects = HasActiveEffects(PostProcessEvent.BeforeStack, context);
@@ -561,6 +584,7 @@ public void Render(PostProcessRenderContext context)
561584

562585
TextureLerper.instance.EndFrame();
563586
m_SettingsUpdateNeeded = true;
587+
m_NaNKilled = false;
564588
}
565589

566590
int RenderInjectionPoint(PostProcessEvent evt, PostProcessRenderContext context, string marker, int releaseTargetAfterUse = -1)
@@ -599,7 +623,7 @@ void RenderList(List<SerializedBundleRef> list, PostProcessRenderContext context
599623
}
600624

601625
int count = m_ActiveEffects.Count;
602-
626+
603627
// If there's only one active effect, we can simply execute it and skip the rest
604628
if (count == 1)
605629
{
@@ -630,7 +654,7 @@ void RenderList(List<SerializedBundleRef> list, PostProcessRenderContext context
630654
context.destination = m_Targets[i + 1];
631655
m_ActiveEffects[i].Render(context);
632656
}
633-
657+
634658
cmd.ReleaseTemporaryRT(tempTarget1);
635659
if (count > 2)
636660
cmd.ReleaseTemporaryRT(tempTarget2);
@@ -705,7 +729,7 @@ int RenderBuiltins(PostProcessRenderContext context, bool isFinalPass, int relea
705729
if (releaseTargetAfterUse > -1) cmd.ReleaseTemporaryRT(releaseTargetAfterUse);
706730
if (motionBlurTarget > -1) cmd.ReleaseTemporaryRT(motionBlurTarget);
707731
if (depthOfFieldTarget > -1) cmd.ReleaseTemporaryRT(motionBlurTarget);
708-
732+
709733
cmd.EndSample("BuiltinStack");
710734

711735
return tempTarget;

PostProcessing/Runtime/Utils/RuntimeUtilities.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,18 @@ public static Material copyMaterial
111111
}
112112
}
113113

114+
static PropertySheet s_CopySheet;
115+
public static PropertySheet copySheet
116+
{
117+
get
118+
{
119+
if (s_CopySheet != null)
120+
s_CopySheet = new PropertySheet(copyMaterial);
121+
122+
return s_CopySheet;
123+
}
124+
}
125+
114126
// Use a custom blit method to draw a fullscreen triangle instead of a fullscreen quad
115127
// https://michaldrobot.com/2014/04/01/gcn-execution-patterns-in-full-screen-passes/
116128
public static void BlitFullscreenTriangle(this CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier destination, bool clear = false)

PostProcessing/Shaders/Builtins/Copy.shader

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@ Shader "Hidden/PostProcessing/Copy"
44

55
#include "../StdLib.hlsl"
66

7+
struct AttributesClassic
8+
{
9+
float4 vertex : POSITION;
10+
float2 texcoord : TEXCOORD0;
11+
};
12+
13+
VaryingsDefault VertClassic(AttributesClassic v)
14+
{
15+
VaryingsDefault o;
16+
o.vertex = mul(unity_MatrixVP, mul(unity_ObjectToWorld, float4(v.vertex.xyz, 1.0)));
17+
o.texcoord = v.texcoord;
18+
return o;
19+
}
20+
721
TEXTURE2D_SAMPLER2D(_MainTex, sampler_MainTex);
822

923
float4 Frag(VaryingsDefault i) : SV_Target
@@ -12,20 +26,66 @@ Shader "Hidden/PostProcessing/Copy"
1226
return color;
1327
}
1428

29+
float4 FragKillNaN(VaryingsDefault i) : SV_Target
30+
{
31+
float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
32+
33+
if (any(isnan(color)) || any(isinf(color)))
34+
{
35+
color = (0.0).xxxx;
36+
}
37+
38+
return color;
39+
}
40+
1541
ENDHLSL
1642

1743
SubShader
1844
{
1945
Cull Off ZWrite Off ZTest Always
2046

47+
// 0 - Fullscreen triangle copy
48+
Pass
49+
{
50+
HLSLPROGRAM
51+
52+
#pragma vertex VertDefault
53+
#pragma fragment Frag
54+
55+
ENDHLSL
56+
}
57+
58+
// 1 - Fullscreen triangle copy + NaN killer
2159
Pass
2260
{
2361
HLSLPROGRAM
2462

2563
#pragma vertex VertDefault
64+
#pragma fragment FragKillNaN
65+
66+
ENDHLSL
67+
}
68+
69+
// 2 - Classic copy
70+
Pass
71+
{
72+
HLSLPROGRAM
73+
74+
#pragma vertex VertClassic
2675
#pragma fragment Frag
2776

2877
ENDHLSL
2978
}
79+
80+
// 3 - Classic copy + NaN killer
81+
Pass
82+
{
83+
HLSLPROGRAM
84+
85+
#pragma vertex VertClassic
86+
#pragma fragment FragKillNaN
87+
88+
ENDHLSL
89+
}
3090
}
3191
}

PostProcessing/Shaders/StdLib.hlsl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ float4 PositivePow(float4 base, float4 power)
150150
// Std unity data
151151

152152
float4x4 unity_CameraProjection;
153+
float4x4 unity_MatrixVP;
154+
float4x4 unity_ObjectToWorld;
153155
float4x4 unity_WorldToCamera;
154156
float3 _WorldSpaceCameraPos;
155157
float4 _ProjectionParams; // x: 1 (-1 flipped), y: near, z: far, w: 1/far

0 commit comments

Comments
 (0)