diff --git a/PostProcessing/Editor/Effects/FogEditor.cs b/PostProcessing/Editor/Effects/FogEditor.cs new file mode 100644 index 00000000..64972c1a --- /dev/null +++ b/PostProcessing/Editor/Effects/FogEditor.cs @@ -0,0 +1,44 @@ +using UnityEngine; +using UnityEngine.Rendering.PostProcessing; + +namespace UnityEditor.Rendering.PostProcessing +{ + [PostProcessEditor(typeof(Fog))] + public sealed class FogEditor : PostProcessEffectEditor + { + SerializedParameterOverride m_excludeSkybox; + SerializedParameterOverride m_color; + SerializedParameterOverride m_density; + SerializedParameterOverride m_startDistance; + SerializedParameterOverride m_endDistance; + SerializedParameterOverride m_mode; + + public override void OnEnable() + { + m_excludeSkybox = FindParameterOverride(x => x.excludeSkybox); + m_color = FindParameterOverride(x => x.color); + m_density = FindParameterOverride(x => x.density); + m_startDistance = FindParameterOverride(x => x.startDistance); + m_endDistance = FindParameterOverride(x => x.endDistance); + m_mode = FindParameterOverride(x => x.mode); + } + + public override void OnInspectorGUI() + { + base.OnInspectorGUI(); + + PropertyField(m_excludeSkybox); + PropertyField(m_color); + PropertyField(m_mode); + if (m_mode.value.intValue == (int)FogMode.Linear) + { + PropertyField(m_startDistance); + PropertyField(m_endDistance); + } + else if (m_mode.value.intValue == (int)FogMode.Exponential || m_mode.value.intValue == (int)FogMode.ExponentialSquared) + { + PropertyField(m_density); + } + } + } +} diff --git a/PostProcessing/Editor/Effects/FogEditor.cs.meta b/PostProcessing/Editor/Effects/FogEditor.cs.meta new file mode 100644 index 00000000..2ff9b412 --- /dev/null +++ b/PostProcessing/Editor/Effects/FogEditor.cs.meta @@ -0,0 +1,13 @@ +fileFormatVersion: 2 +guid: 356a7c80dc030f24a91cb96353cc88a2 +timeCreated: 1522677212 +licenseType: Free +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/PostProcessing/Editor/PostProcessLayerEditor.cs b/PostProcessing/Editor/PostProcessLayerEditor.cs index 6d8a2d3d..5d691e6b 100644 --- a/PostProcessing/Editor/PostProcessLayerEditor.cs +++ b/PostProcessing/Editor/PostProcessLayerEditor.cs @@ -30,9 +30,6 @@ sealed class PostProcessLayerEditor : BaseEditor SerializedProperty m_FxaaFastMode; SerializedProperty m_FxaaKeepAlpha; - SerializedProperty m_FogEnabled; - SerializedProperty m_FogExcludeSkybox; - SerializedProperty m_ShowToolkit; SerializedProperty m_ShowCustomSorter; @@ -70,9 +67,6 @@ void OnEnable() m_FxaaFastMode = FindProperty(x => x.fastApproximateAntialiasing.fastMode); m_FxaaKeepAlpha = FindProperty(x => x.fastApproximateAntialiasing.keepAlpha); - m_FogEnabled = FindProperty(x => x.fog.enabled); - m_FogExcludeSkybox = FindProperty(x => x.fog.excludeSkybox); - m_ShowToolkit = serializedObject.FindProperty("m_ShowToolkit"); m_ShowCustomSorter = serializedObject.FindProperty("m_ShowCustomSorter"); } @@ -86,8 +80,6 @@ public override void OnInspectorGUI() { serializedObject.Update(); - var camera = m_Target.GetComponent(); - #if !UNITY_2017_2_OR_NEWER if (RuntimeUtilities.isSinglePassStereoSelected) EditorGUILayout.HelpBox("Unity 2017.2+ required for full Single-pass stereo rendering support.", MessageType.Warning); @@ -95,7 +87,6 @@ public override void OnInspectorGUI() DoVolumeBlending(); DoAntialiasing(); - DoFog(camera); 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. Has no effect on GLES2 platforms.")); @@ -192,27 +183,6 @@ void DoAntialiasing() EditorGUILayout.Space(); } - void DoFog(Camera camera) - { - if (camera == null || camera.actualRenderingPath != RenderingPath.DeferredShading) - return; - - EditorGUILayout.LabelField(EditorUtilities.GetContent("Deferred Fog"), EditorStyles.boldLabel); - EditorGUI.indentLevel++; - { - EditorGUILayout.PropertyField(m_FogEnabled); - - if (m_FogEnabled.boolValue) - { - EditorGUILayout.PropertyField(m_FogExcludeSkybox); - EditorGUILayout.HelpBox("This adds fog compatibility to the deferred rendering path; actual fog settings should be set in the Lighting panel.", MessageType.Info); - } - } - EditorGUI.indentLevel--; - - EditorGUILayout.Space(); - } - void DoToolkit() { EditorUtilities.DrawSplitter(); diff --git a/PostProcessing/Runtime/Effects/Fog.cs b/PostProcessing/Runtime/Effects/Fog.cs index c8efcf30..1e78115b 100644 --- a/PostProcessing/Runtime/Effects/Fog.cs +++ b/PostProcessing/Runtime/Effects/Fog.cs @@ -9,27 +9,20 @@ namespace UnityEngine.Rendering.PostProcessing [UnityEngine.Scripting.Preserve] #endif [Serializable] - public sealed class Fog + [PostProcess(typeof(FogRenderer), "Unity/Fog")] + public sealed class Fog : PostProcessEffectSettings { - /// - /// If true, enables the internal deferred fog pass. Actual fog settings should be - /// set in the Lighting panel. - /// - [Tooltip("Enables the internal deferred fog pass. Actual fog settings should be set in the Lighting panel.")] - public bool enabled = true; + [Serializable] + public sealed class FogModeParameter : ParameterOverride { } - /// - /// Should the fog affect the skybox? - /// - [Tooltip("Mark true for the fog to ignore the skybox")] - public bool excludeSkybox = true; + public BoolParameter excludeSkybox = new BoolParameter { value = true }; + public ColorParameter color = new ColorParameter { value = Color.gray }; + public FloatParameter density = new FloatParameter { value = 0.01f }; + public FloatParameter startDistance = new FloatParameter { value = 100 }; + public FloatParameter endDistance = new FloatParameter { value = 200 }; + public FogModeParameter mode = new FogModeParameter { value = FogMode.Exponential }; - internal DepthTextureMode GetCameraFlags() - { - return DepthTextureMode.Depth; - } - - internal bool IsEnabledAndSupported(PostProcessRenderContext context) + public override bool IsEnabledAndSupported(PostProcessRenderContext context) { return enabled && RenderSettings.fog @@ -39,7 +32,29 @@ internal bool IsEnabledAndSupported(PostProcessRenderContext context) && context.camera.actualRenderingPath == RenderingPath.DeferredShading; // In forward fog is already done at shader level } - internal void Render(PostProcessRenderContext context) + public override void Reset(PostProcessEffectSettings defaultSettings) + { + base.Reset(defaultSettings); + + enabled.value = RenderSettings.fog; + color.value = RenderSettings.fogColor; + density.value = RenderSettings.fogDensity; + startDistance.value = RenderSettings.fogStartDistance; + endDistance.value = RenderSettings.fogEndDistance; + mode.value = RenderSettings.fogMode; + } + } + + public sealed class FogRenderer : PostProcessEffectRenderer + { + Fog m_backupSettings = ScriptableObject.CreateInstance(); + + public override DepthTextureMode GetCameraFlags() + { + return DepthTextureMode.Depth; + } + + public override void Render(PostProcessRenderContext context) { var sheet = context.propertySheets.Get(context.resources.shaders.deferredFog); sheet.ClearKeywords(); @@ -49,7 +64,48 @@ internal void Render(PostProcessRenderContext context) sheet.properties.SetVector(ShaderIDs.FogParams, new Vector3(RenderSettings.fogDensity, RenderSettings.fogStartDistance, RenderSettings.fogEndDistance)); var cmd = context.command; - cmd.BlitFullscreenTriangle(context.source, context.destination, sheet, excludeSkybox ? 1 : 0); + cmd.BlitFullscreenTriangle(context.source, context.destination, sheet, settings.excludeSkybox ? 1 : 0); + } + + static void Load(Fog settings) + { + RenderSettings.fog = settings.enabled; + RenderSettings.fogColor = settings.color; + RenderSettings.fogDensity = settings.density; + RenderSettings.fogStartDistance = settings.startDistance; + RenderSettings.fogEndDistance = settings.endDistance; + RenderSettings.fogMode = settings.mode; + } + + static void Store(Fog result) + { + result.enabled.value = RenderSettings.fog; + result.color.value = RenderSettings.fogColor; + result.density.value = RenderSettings.fogDensity; + result.startDistance.value = RenderSettings.fogStartDistance; + result.endDistance.value = RenderSettings.fogEndDistance; + result.mode.value = RenderSettings.fogMode; + } + + public void ApplySettings(PostProcessRenderContext context) + { + // Backup settings + Store(m_backupSettings); + + // Apply settings + Load(settings); + +#if UNITY_EDITOR + if (context.isSceneView && !UnityEditor.SceneView.currentDrawingSceneView.sceneViewState.showFog) + { + RenderSettings.fog = false; + } +#endif + } + + public void RestoreSettings() + { + Load(m_backupSettings); } } } diff --git a/PostProcessing/Runtime/PostProcessEffectSettings.cs b/PostProcessing/Runtime/PostProcessEffectSettings.cs index 2b86ccfa..9c655607 100644 --- a/PostProcessing/Runtime/PostProcessEffectSettings.cs +++ b/PostProcessing/Runtime/PostProcessEffectSettings.cs @@ -117,5 +117,13 @@ public int GetHash() return hash; } } + + public virtual void Reset(PostProcessEffectSettings defaultSettings) + { + int count = defaultSettings.parameters.Count; + + for (int i = 0; i < count; i++) + parameters[i].SetValue(defaultSettings.parameters[i]); + } } } diff --git a/PostProcessing/Runtime/PostProcessLayer.cs b/PostProcessing/Runtime/PostProcessLayer.cs index 1071c05a..0a048ede 100644 --- a/PostProcessing/Runtime/PostProcessLayer.cs +++ b/PostProcessing/Runtime/PostProcessLayer.cs @@ -108,7 +108,8 @@ public enum Antialiasing /// public Fog fog; - Dithering dithering; + + internal Dithering dithering; /// /// The debug layer is reponsible for rendering debugging information on the screen. It will @@ -264,7 +265,6 @@ public void Init(PostProcessResources resources) RuntimeUtilities.CreateIfNull(ref subpixelMorphologicalAntialiasing); RuntimeUtilities.CreateIfNull(ref fastApproximateAntialiasing); RuntimeUtilities.CreateIfNull(ref dithering); - RuntimeUtilities.CreateIfNull(ref fog); RuntimeUtilities.CreateIfNull(ref debugLayer); } @@ -505,6 +505,11 @@ void BuildCommandBuffers() TextureLerper.instance.BeginFrame(context); UpdateVolumeSystem(context.camera, context.command); + // Fog effect settings + var fogBundle = GetBundle(); + var fogRenderer = fogBundle.CastRenderer(); + fogRenderer.ApplySettings(context); + // Lighting & opaque-only effects var aoBundle = GetBundle(); var aoSettings = aoBundle.CastSettings(); @@ -539,7 +544,7 @@ void BuildCommandBuffers() aoRenderer.Get().RenderAfterOpaque(context); } - bool isFogActive = fog.IsEnabledAndSupported(context); + bool isFogActive = fogRenderer.settings.IsEnabledAndSupported(context); bool hasCustomOpaqueOnlyEffects = HasOpaqueOnlyEffects(context); int opaqueOnlyEffects = 0; opaqueOnlyEffects += isScreenSpaceReflectionsActive ? 1 : 0; @@ -575,7 +580,7 @@ void BuildCommandBuffers() if (isFogActive) { - fog.Render(context); + fogRenderer.Render(context); opaqueOnlyEffects--; UpdateSrcDstForOpaqueOnly(ref srcTarget, ref dstTarget, context, cameraTarget, opaqueOnlyEffects); } @@ -635,6 +640,13 @@ void OnPostRender() if (RuntimeUtilities.scriptableRenderPipelineActive) return; + // Restore original fog settings + var fogBundle = GetBundle(); + if (fogBundle != null) + { + fogBundle.CastRenderer().RestoreSettings(); + } + if (m_CurrentContext.IsTemporalAntialiasingActive()) { #if UNITY_2018_2_OR_NEWER @@ -735,9 +747,6 @@ void SetLegacyCameraFlags(PostProcessRenderContext context) if (context.IsTemporalAntialiasingActive()) flags |= temporalAntialiasing.GetCameraFlags(); - if (fog.IsEnabledAndSupported(context)) - flags |= fog.GetCameraFlags(); - if (debugLayer.debugOverlay != DebugOverlay.None) flags |= debugLayer.GetCameraFlags(); diff --git a/PostProcessing/Runtime/PostProcessManager.cs b/PostProcessing/Runtime/PostProcessManager.cs index 251818b6..f5faffd0 100644 --- a/PostProcessing/Runtime/PostProcessManager.cs +++ b/PostProcessing/Runtime/PostProcessManager.cs @@ -306,10 +306,7 @@ void ReplaceData(PostProcessLayer postProcessLayer) foreach (var settings in m_BaseSettings) { var target = postProcessLayer.GetBundle(settings.GetType()).settings; - int count = settings.parameters.Count; - - for (int i = 0; i < count; i++) - target.parameters[i].SetValue(settings.parameters[i]); + target.Reset(settings); } }