using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; namespace GeNa.Core { public enum PW_RENDER_SIZE { FULL = -1, HALF = -2, QUARTER = -3 }; public static class CommandBufferManagerShaderID { public static readonly string _cbufName = "Echo_Refaction"; public static readonly int _grabID = 0; public static readonly int m_cameraOpaqueTexture; static CommandBufferManagerShaderID() { m_cameraOpaqueTexture = Shader.PropertyToID("_CameraOpaqueTexture"); } } [ExecuteAlways] public class CommandBufferManager : MonoBehaviour { #region Variables #region Public public bool m_allowHDR = true; public PW_RENDER_SIZE m_renderSize = PW_RENDER_SIZE.HALF; public CameraEvent m_cameraEventRefraction = CameraEvent.AfterImageEffectsOpaque; #endregion #region Private [SerializeField] private Constants.RenderPipeline RenderPipeline = Constants.RenderPipeline.BuiltIn; private const string m_bufferManagerObjectName = "Command Buffer Manager"; #region Events private Dictionary m_camerasRefraction = new Dictionary(); #endregion #endregion #endregion #region Unity Functions /// /// Start on enable /// private void OnEnable() { RebuildBuffers(); } /// /// OnDisable ClearData /// private void OnDisable() { RebuildBuffers(); } /// /// OnDestroy ClearData /// private void OnDestroy() { ClearBuffers(); } #endregion #region Methods /// /// Function used to rebuild buffers /// public void RebuildBuffers(bool clear = true) { RenderPipeline = GeNaUtility.GetActivePipeline(); if (clear) { ClearBuffers(); } StartBuffers(); } /// /// Clears all the buffers /// public void ClearBuffers() { if (RenderPipeline == Constants.RenderPipeline.BuiltIn) { Camera.onPreRender += PreRender; //Refraction foreach (KeyValuePair cam in m_camerasRefraction) { if (cam.Key) { cam.Key.RemoveCommandBuffer(m_cameraEventRefraction, cam.Value); } } m_camerasRefraction.Clear(); } } /// /// Starts the buffer render process /// private void StartBuffers() { if(RenderPipeline == Constants.RenderPipeline.BuiltIn) { Camera.onPreRender += PreRender; } } /// /// Process function to generate the buffers /// /// private void PreRender(Camera i_cam) { if (gameObject != null) { if (gameObject.activeInHierarchy) { RenderBuffers(i_cam); } else { ClearBuffers(); } } } /// /// Process function to generate the buffers /// /// private void PreRender(ScriptableRenderContext src, Camera i_cam) { if (gameObject != null) { if (gameObject.activeInHierarchy) { RenderBuffers(i_cam); } else { ClearBuffers(); } } } /// /// Function used to build the buffer data /// /// private void RenderBuffers(Camera i_cam) { if (i_cam != null) { if (i_cam.name.Contains("Reflection Probe")) { return; } } //Refraction if (m_camerasRefraction.ContainsKey(i_cam)) { return; } CommandBuffer cameraOpaqueBuffer = new CommandBuffer { name = CommandBufferManagerShaderID._cbufName }; m_camerasRefraction[i_cam] = cameraOpaqueBuffer; if (m_allowHDR) { cameraOpaqueBuffer.GetTemporaryRT(CommandBufferManagerShaderID._grabID, (int)m_renderSize, (int)m_renderSize, 0, FilterMode.Bilinear, RenderTextureFormat.DefaultHDR); } else { cameraOpaqueBuffer.GetTemporaryRT(CommandBufferManagerShaderID._grabID, (int)m_renderSize, (int)m_renderSize, 0, FilterMode.Bilinear); } cameraOpaqueBuffer.Blit(BuiltinRenderTextureType.CurrentActive, CommandBufferManagerShaderID._grabID); cameraOpaqueBuffer.SetGlobalTexture(CommandBufferManagerShaderID.m_cameraOpaqueTexture, CommandBufferManagerShaderID._grabID); cameraOpaqueBuffer.ReleaseTemporaryRT(CommandBufferManagerShaderID._grabID); i_cam.AddCommandBuffer(m_cameraEventRefraction, cameraOpaqueBuffer); } #endregion #region Static Methods /// /// Creates the buffer manager in the scene /// public static bool CreateBufferManager() { //Create Manager CommandBufferManager manager = GeNaEvents.FindObjectOfType(); if (manager == null) { GameObject managerGameObject = new GameObject(m_bufferManagerObjectName); manager = managerGameObject.AddComponent(); manager.RebuildBuffers(); //Parent manager.transform.SetParent(GeNaUtility.GeNaManagerTransform); } return true; } #endregion } }