451 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
			
		
		
	
	
			451 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			C#
		
	
	
	
| //using System;
 | |
| //using System.Collections.Generic;
 | |
| //using UnityEngine.Rendering;
 | |
| 
 | |
| //namespace UnityEngine.PostProcessing
 | |
| //{
 | |
| //    using DebugMode = BuiltinDebugViewsModel.Mode;
 | |
| 
 | |
| //#if UNITY_5_4_OR_NEWER
 | |
| //    [ImageEffectAllowedInSceneView]
 | |
| //#endif
 | |
| //    [RequireComponent(typeof(Camera)), DisallowMultipleComponent, ExecuteInEditMode]
 | |
| //    [AddComponentMenu("Effects/Post-Processing Behaviour", -1)]
 | |
| //    public class PostProcessingBehaviour : MonoBehaviour
 | |
| //    {
 | |
| //        // Inspector fields
 | |
| //        public PostProcessingProfile profile;
 | |
| 
 | |
| //        // Internal helpers
 | |
| //        Dictionary<Type, KeyValuePair<CameraEvent, CommandBuffer>> m_CommandBuffers;
 | |
| //        List<PostProcessingComponentBase> m_Components;
 | |
| //        Dictionary<PostProcessingComponentBase, bool> m_ComponentStates;
 | |
| 
 | |
| //        MaterialFactory m_MaterialFactory;
 | |
| //        RenderTextureFactory m_RenderTextureFactory;
 | |
| //        PostProcessingContext m_Context;
 | |
| //        Camera m_Camera;
 | |
| //        PostProcessingProfile m_PreviousProfile;
 | |
| 
 | |
| //        bool m_RenderingInSceneView;
 | |
| //        RenderTexture m_JitteredDepthHistory;
 | |
| 
 | |
| //        // Effect components
 | |
| //        BuiltinDebugViewsComponent m_DebugViews;
 | |
| //        AmbientOcclusionComponent m_AmbientOcclusion;
 | |
| //        ScreenSpaceReflectionComponent m_ScreenSpaceReflection;
 | |
| //        MotionBlurComponent m_MotionBlur;
 | |
| //        TaaComponent m_Taa;
 | |
| //        EyeAdaptationComponent m_EyeAdaptation;
 | |
| //        DepthOfFieldComponent m_DepthOfField;
 | |
| //        BloomComponent m_Bloom;
 | |
| //        ChromaticAberrationComponent m_ChromaticAberration;
 | |
| //        ColorGradingComponent m_ColorGrading;
 | |
| //        UserLutComponent m_UserLut;
 | |
| //        GrainComponent m_Grain;
 | |
| //        VignetteComponent m_Vignette;
 | |
| //        FxaaComponent m_Fxaa;
 | |
| 
 | |
| //        void OnEnable()
 | |
| //        {
 | |
| //            m_CommandBuffers = new Dictionary<Type, KeyValuePair<CameraEvent, CommandBuffer>>();
 | |
| //            m_MaterialFactory = new MaterialFactory();
 | |
| //            m_RenderTextureFactory = new RenderTextureFactory();
 | |
| //            m_Context = new PostProcessingContext();
 | |
| 
 | |
| //            // Keep a list of all post-fx for automation purposes
 | |
| //            m_Components = new List<PostProcessingComponentBase>();
 | |
| 
 | |
| //            // Component list
 | |
| //            m_DebugViews = AddComponent(new BuiltinDebugViewsComponent());
 | |
| //            m_AmbientOcclusion = AddComponent(new AmbientOcclusionComponent());
 | |
| //            m_ScreenSpaceReflection = AddComponent(new ScreenSpaceReflectionComponent());
 | |
| //            m_MotionBlur = AddComponent(new MotionBlurComponent());
 | |
| //            m_Taa = AddComponent(new TaaComponent());
 | |
| //            m_EyeAdaptation = AddComponent(new EyeAdaptationComponent());
 | |
| //            m_DepthOfField = AddComponent(new DepthOfFieldComponent());
 | |
| //            m_Bloom = AddComponent(new BloomComponent());
 | |
| //            m_ChromaticAberration = AddComponent(new ChromaticAberrationComponent());
 | |
| //            m_ColorGrading = AddComponent(new ColorGradingComponent());
 | |
| //            m_UserLut = AddComponent(new UserLutComponent());
 | |
| //            m_Grain = AddComponent(new GrainComponent());
 | |
| //            m_Vignette = AddComponent(new VignetteComponent());
 | |
| //            m_Fxaa = AddComponent(new FxaaComponent());
 | |
| 
 | |
| //            // Prepare state observers
 | |
| //            m_ComponentStates = new Dictionary<PostProcessingComponentBase, bool>();
 | |
| 
 | |
| //            foreach (var component in m_Components)
 | |
| //                m_ComponentStates.Add(component, false);
 | |
| //        }
 | |
| 
 | |
| //        void OnPreCull()
 | |
| //        {
 | |
| //            // All the per-frame initialization logic has to be done in OnPreCull instead of Update
 | |
| //            // because [ImageEffectAllowedInSceneView] doesn't trigger Update events...
 | |
| 
 | |
| //            m_Camera = GetComponent<Camera>();
 | |
| 
 | |
| //            if (profile == null || m_Camera == null)
 | |
| //                return;
 | |
| 
 | |
| //#if UNITY_EDITOR
 | |
| //            // Track the scene view camera to disable some effects we don't want to see in the
 | |
| //            // scene view
 | |
| //            // Currently disabled effects :
 | |
| //            //  - Temporal Antialiasing
 | |
| //            //  - Depth of Field
 | |
| //            //  - Motion blur
 | |
| //            m_RenderingInSceneView = UnityEditor.SceneView.currentDrawingSceneView != null
 | |
| //                && UnityEditor.SceneView.currentDrawingSceneView.camera == m_Camera;
 | |
| //#endif
 | |
| 
 | |
| //            // Prepare context
 | |
| //            var context = m_Context.Reset();
 | |
| //            context.profile = profile;
 | |
| //            context.renderTextureFactory = m_RenderTextureFactory;
 | |
| //            context.materialFactory = m_MaterialFactory;
 | |
| //            context.camera = m_Camera;
 | |
| 
 | |
| //            // Prepare components
 | |
| //            m_DebugViews.Init(context, profile.debugViews);
 | |
| //            m_AmbientOcclusion.Init(context, profile.ambientOcclusion);
 | |
| //            m_ScreenSpaceReflection.Init(context, profile.screenSpaceReflection);
 | |
| //            m_MotionBlur.Init(context, profile.motionBlur);
 | |
| //            m_Taa.Init(context, profile.antialiasing);
 | |
| //            m_EyeAdaptation.Init(context, profile.eyeAdaptation);
 | |
| //            m_DepthOfField.Init(context, profile.depthOfField);
 | |
| //            m_Bloom.Init(context, profile.bloom);
 | |
| //            m_ChromaticAberration.Init(context, profile.chromaticAberration);
 | |
| //            m_ColorGrading.Init(context, profile.colorGrading);
 | |
| //            m_UserLut.Init(context, profile.userLut);
 | |
| //            m_Grain.Init(context, profile.grain);
 | |
| //            m_Vignette.Init(context, profile.vignette);
 | |
| //            m_Fxaa.Init(context, profile.antialiasing);
 | |
| 
 | |
| //            // Handles profile change and 'enable' state observers
 | |
| //            if (m_PreviousProfile != profile)
 | |
| //            {
 | |
| //                DisableComponents();
 | |
| //                m_PreviousProfile = profile;
 | |
| //            }
 | |
| 
 | |
| //            CheckObservers();
 | |
| 
 | |
| //            // Find out which camera flags are needed before rendering begins
 | |
| //            // Note that motion vectors will only be available one frame after being enabled
 | |
| //            var flags = DepthTextureMode.None;
 | |
| //            foreach (var component in m_Components)
 | |
| //            {
 | |
| //                if (component.active)
 | |
| //                    flags |= component.GetCameraFlags();
 | |
| //            }
 | |
| 
 | |
| //            context.camera.depthTextureMode = flags;
 | |
| 
 | |
| //            // Temporal antialiasing jittering, needs to happen before culling
 | |
| //            if (!m_RenderingInSceneView && m_Taa.active && !profile.debugViews.willInterrupt)
 | |
| //                m_Taa.SetProjectionMatrix();
 | |
| //        }
 | |
| 
 | |
| //        void OnPreRender()
 | |
| //        {
 | |
| //            if (profile == null)
 | |
| //                return;
 | |
| 
 | |
| //            // Command buffer-based effects should be set-up here
 | |
| //            TryExecuteCommandBuffer(m_DebugViews);
 | |
| //            TryExecuteCommandBuffer(m_AmbientOcclusion);
 | |
| //            TryExecuteCommandBuffer(m_ScreenSpaceReflection);
 | |
| 
 | |
| //            if (!m_RenderingInSceneView)
 | |
| //                TryExecuteCommandBuffer(m_MotionBlur);
 | |
| //        }
 | |
| 
 | |
| //        void OnPostRender()
 | |
| //        {
 | |
| //            if (profile == null || m_Camera == null)
 | |
| //                return;
 | |
| 
 | |
| //            m_Camera.ResetProjectionMatrix();
 | |
| //        }
 | |
| 
 | |
| //        // Classic render target pipeline for RT-based effects
 | |
| //        // Note that any effect that happens after this stack will work in LDR
 | |
| //        [ImageEffectTransformsToLDR]
 | |
| //        void OnRenderImage(RenderTexture source, RenderTexture destination)
 | |
| //        {
 | |
| //            if (profile == null || m_Camera == null)
 | |
| //            {
 | |
| //                Graphics.Blit(source, destination);
 | |
| //                return;
 | |
| //            }
 | |
| 
 | |
| //            // Uber shader setup
 | |
| //            bool uberActive = false;
 | |
| //            bool fxaaActive = m_Fxaa.active;
 | |
| //            bool taaActive = m_Taa.active && !m_RenderingInSceneView;
 | |
| //            bool dofActive = m_DepthOfField.active && !m_RenderingInSceneView;
 | |
| 
 | |
| //            var uberMaterial = m_MaterialFactory.Get("Hidden/Post FX/Uber Shader");
 | |
| //            uberMaterial.shaderKeywords = null;
 | |
| 
 | |
| //            var src = source;
 | |
| //            var dst = destination;
 | |
| 
 | |
| //            if (taaActive)
 | |
| //            {
 | |
| //                var tempRT = m_RenderTextureFactory.Get(src);
 | |
| //                m_Taa.Render(src, tempRT);
 | |
| //                src = tempRT;
 | |
| //            }
 | |
| 
 | |
| //#if UNITY_EDITOR
 | |
| //            // Render to a dedicated target when monitors are enabled so they can show information
 | |
| //            // about the final render.
 | |
| //            // At runtime the output will always be the backbuffer or whatever render target is
 | |
| //            // currently set on the camera.
 | |
| //            if (profile.monitors.onFrameEndEditorOnly != null)
 | |
| //                dst = m_RenderTextureFactory.Get(src);
 | |
| //#endif
 | |
| 
 | |
| //            Texture autoExposure = null;
 | |
| //            if (m_EyeAdaptation.active)
 | |
| //            {
 | |
| //                uberActive = true;
 | |
| //                autoExposure = m_EyeAdaptation.Prepare(src, uberMaterial);
 | |
| //            }
 | |
| 
 | |
| //            if (dofActive)
 | |
| //            {
 | |
| //                uberActive = true;
 | |
| //                m_DepthOfField.Prepare(src, uberMaterial, taaActive);
 | |
| //            }
 | |
| 
 | |
| //            if (m_Bloom.active)
 | |
| //            {
 | |
| //                uberActive = true;
 | |
| //                m_Bloom.Prepare(src, uberMaterial, autoExposure);
 | |
| //            }
 | |
| 
 | |
| //            uberActive |= TryPrepareUberImageEffect(m_ChromaticAberration, uberMaterial);
 | |
| //            uberActive |= TryPrepareUberImageEffect(m_ColorGrading, uberMaterial);
 | |
| //            uberActive |= TryPrepareUberImageEffect(m_UserLut, uberMaterial);
 | |
| //            uberActive |= TryPrepareUberImageEffect(m_Grain, uberMaterial);
 | |
| //            uberActive |= TryPrepareUberImageEffect(m_Vignette, uberMaterial);
 | |
| 
 | |
| //            // Render to destination
 | |
| //            if (uberActive)
 | |
| //            {
 | |
| //                if (!GraphicsUtils.isLinearColorSpace)
 | |
| //                    uberMaterial.EnableKeyword("UNITY_COLORSPACE_GAMMA");
 | |
| 
 | |
| //                var input = src;
 | |
| //                var output = dst;
 | |
| //                if (fxaaActive)
 | |
| //                {
 | |
| //                    output = m_RenderTextureFactory.Get(src);
 | |
| //                    src = output;
 | |
| //                }
 | |
| 
 | |
| //                Graphics.Blit(input, output, uberMaterial, 0);
 | |
| //            }
 | |
| 
 | |
| //            if (fxaaActive)
 | |
| //                m_Fxaa.Render(src, dst);
 | |
| 
 | |
| //            if (!uberActive && !fxaaActive)
 | |
| //                Graphics.Blit(src, dst);
 | |
| 
 | |
| //#if UNITY_EDITOR
 | |
| //            if (profile.monitors.onFrameEndEditorOnly != null)
 | |
| //            {
 | |
| //                Graphics.Blit(dst, destination);
 | |
| 
 | |
| //                var oldRt = RenderTexture.active;
 | |
| //                profile.monitors.onFrameEndEditorOnly(dst);
 | |
| //                RenderTexture.active = oldRt;
 | |
| //            }
 | |
| //#endif
 | |
| 
 | |
| //            m_RenderTextureFactory.ReleaseAll();
 | |
| //        }
 | |
| 
 | |
| //        void OnGUI()
 | |
| //        {
 | |
| //            if (Event.current.type != EventType.Repaint)
 | |
| //                return;
 | |
| 
 | |
| //            if (profile == null || m_Camera == null)
 | |
| //                return;
 | |
| 
 | |
| //            if (m_EyeAdaptation.active && profile.debugViews.IsModeActive(DebugMode.EyeAdaptation))
 | |
| //                m_EyeAdaptation.OnGUI();
 | |
| //            else if (m_ColorGrading.active && profile.debugViews.IsModeActive(DebugMode.LogLut))
 | |
| //                m_ColorGrading.OnGUI();
 | |
| //            else if (m_UserLut.active && profile.debugViews.IsModeActive(DebugMode.UserLut))
 | |
| //                m_UserLut.OnGUI();
 | |
| //        }
 | |
| 
 | |
| //        void OnDisable()
 | |
| //        {
 | |
| //            // Clear command buffers
 | |
| //            foreach (var cb in m_CommandBuffers.Values)
 | |
| //            {
 | |
| //                m_Camera.RemoveCommandBuffer(cb.Key, cb.Value);
 | |
| //                cb.Value.Dispose();
 | |
| //            }
 | |
| 
 | |
| //            m_CommandBuffers.Clear();
 | |
| 
 | |
| //            // Clear components
 | |
| //            if (profile != null)
 | |
| //                DisableComponents();
 | |
| 
 | |
| //            m_Components.Clear();
 | |
| 
 | |
| //            // Reset camera mode
 | |
| //            if (m_Camera != null)
 | |
| //                m_Camera.depthTextureMode = DepthTextureMode.None;
 | |
| 
 | |
| //            // Factories
 | |
| //            m_MaterialFactory.Dispose();
 | |
| //            m_RenderTextureFactory.Dispose();
 | |
| //            GraphicsUtils.Dispose();
 | |
| //        }
 | |
| 
 | |
| //        public void ResetTemporalEffects()
 | |
| //        {
 | |
| //            m_Taa.ResetHistory();
 | |
| //            m_MotionBlur.ResetHistory();
 | |
| //        }
 | |
| 
 | |
| //        #region State management
 | |
| 
 | |
| //        List<PostProcessingComponentBase> m_ComponentsToEnable = new List<PostProcessingComponentBase>();
 | |
| //        List<PostProcessingComponentBase> m_ComponentsToDisable = new List<PostProcessingComponentBase>();
 | |
| 
 | |
| //        void CheckObservers()
 | |
| //        {
 | |
| //            foreach (var cs in m_ComponentStates)
 | |
| //            {
 | |
| //                var component = cs.Key;
 | |
| //                var state = component.GetModel().enabled;
 | |
| 
 | |
| //                if (state != cs.Value)
 | |
| //                {
 | |
| //                    if (state) m_ComponentsToEnable.Add(component);
 | |
| //                    else m_ComponentsToDisable.Add(component);
 | |
| //                }
 | |
| //            }
 | |
| 
 | |
| //            for (int i = 0; i < m_ComponentsToDisable.Count; i++)
 | |
| //            {
 | |
| //                var c = m_ComponentsToDisable[i];
 | |
| //                m_ComponentStates[c] = false;
 | |
| //                c.OnDisable();
 | |
| //            }
 | |
| 
 | |
| //            for (int i = 0; i < m_ComponentsToEnable.Count; i++)
 | |
| //            {
 | |
| //                var c = m_ComponentsToEnable[i];
 | |
| //                m_ComponentStates[c] = true;
 | |
| //                c.OnEnable();
 | |
| //            }
 | |
| 
 | |
| //            m_ComponentsToDisable.Clear();
 | |
| //            m_ComponentsToEnable.Clear();
 | |
| //        }
 | |
| 
 | |
| //        void DisableComponents()
 | |
| //        {
 | |
| //            foreach (var component in m_Components)
 | |
| //            {
 | |
| //                var model = component.GetModel();
 | |
| //                if (model != null && model.enabled)
 | |
| //                    component.OnDisable();
 | |
| //            }
 | |
| //        }
 | |
| 
 | |
| //        #endregion
 | |
| 
 | |
| //        #region Command buffer handling & rendering helpers
 | |
| //        // Placeholders before the upcoming Scriptable Render Loop as command buffers will be
 | |
| //        // executed on the go so we won't need of all that stuff
 | |
| //        CommandBuffer AddCommandBuffer<T>(CameraEvent evt, string name)
 | |
| //            where T : PostProcessingModel
 | |
| //        {
 | |
| //            var cb = new CommandBuffer { name = name };
 | |
| //            var kvp = new KeyValuePair<CameraEvent, CommandBuffer>(evt, cb);
 | |
| //            m_CommandBuffers.Add(typeof(T), kvp);
 | |
| //            m_Camera.AddCommandBuffer(evt, kvp.Value);
 | |
| //            return kvp.Value;
 | |
| //        }
 | |
| 
 | |
| //        void RemoveCommandBuffer<T>()
 | |
| //            where T : PostProcessingModel
 | |
| //        {
 | |
| //            KeyValuePair<CameraEvent, CommandBuffer> kvp;
 | |
| //            var type = typeof(T);
 | |
| 
 | |
| //            if (!m_CommandBuffers.TryGetValue(type, out kvp))
 | |
| //                return;
 | |
| 
 | |
| //            m_Camera.RemoveCommandBuffer(kvp.Key, kvp.Value);
 | |
| //            m_CommandBuffers.Remove(type);
 | |
| //            kvp.Value.Dispose();
 | |
| //        }
 | |
| 
 | |
| //        CommandBuffer GetCommandBuffer<T>(CameraEvent evt, string name)
 | |
| //            where T : PostProcessingModel
 | |
| //        {
 | |
| //            CommandBuffer cb;
 | |
| //            KeyValuePair<CameraEvent, CommandBuffer> kvp;
 | |
| 
 | |
| //            if (!m_CommandBuffers.TryGetValue(typeof(T), out kvp))
 | |
| //            {
 | |
| //                cb = AddCommandBuffer<T>(evt, name);
 | |
| //            }
 | |
| //            else if (kvp.Key != evt)
 | |
| //            {
 | |
| //                RemoveCommandBuffer<T>();
 | |
| //                cb = AddCommandBuffer<T>(evt, name);
 | |
| //            }
 | |
| //            else cb = kvp.Value;
 | |
| 
 | |
| //            return cb;
 | |
| //        }
 | |
| 
 | |
| //        void TryExecuteCommandBuffer<T>(PostProcessingComponentCommandBuffer<T> component)
 | |
| //            where T : PostProcessingModel
 | |
| //        {
 | |
| //            if (component.active)
 | |
| //            {
 | |
| //                var cb = GetCommandBuffer<T>(component.GetCameraEvent(), component.GetName());
 | |
| //                cb.Clear();
 | |
| //                component.PopulateCommandBuffer(cb);
 | |
| //            }
 | |
| //            else RemoveCommandBuffer<T>();
 | |
| //        }
 | |
| 
 | |
| //        bool TryPrepareUberImageEffect<T>(PostProcessingComponentRenderTexture<T> component, Material material)
 | |
| //            where T : PostProcessingModel
 | |
| //        {
 | |
| //            if (!component.active)
 | |
| //                return false;
 | |
| 
 | |
| //            component.Prepare(material);
 | |
| //            return true;
 | |
| //        }
 | |
| 
 | |
| //        T AddComponent<T>(T component)
 | |
| //            where T : PostProcessingComponentBase
 | |
| //        {
 | |
| //            m_Components.Add(component);
 | |
| //            return component;
 | |
| //        }
 | |
| 
 | |
| //        #endregion
 | |
| //    }
 | |
| //}
 |