using UnityEngine; using UnityEngine.UI; using System; using System.Collections; namespace BF { public class EnumFlagsAttribute : PropertyAttribute { } [Flags] public enum PostEffectType { None = 0, Bloom = 1, VividBloom = 2, Fxaa = 4, RadialBlur = 8, } public class RenderManager : ManagerBase { RenderTexture rt0; RenderTexture rt1; RenderTexture rt2; public int BlurSizeID { get; private set; } public int BloomID { get; private set; } Material uiDefaultMat; public Material UIDefaultMat { get { if (uiDefaultMat == null) { uiDefaultMat = new Material(Shader.Find("BF/UI/Default")); } return uiDefaultMat; } } Material uiTutorialMat; public Material UITutorialMat { get { if (uiTutorialMat == null) { uiTutorialMat = new Material(Shader.Find("BF/UI/UITutorial")); } return uiTutorialMat; } } Material blurMat; public Material BlurMat { get { if (blurMat == null) { blurMat = new Material(Shader.Find("BF/PostEffect/Blur")); } return blurMat; } } Material bloomMat; public Material BloomMat { get { if (bloomMat == null) { bloomMat = new Material(Shader.Find("BF/PostEffect/Bloom")); } return bloomMat; } } Material vividBloomMat; public Material VividBloomMat { get { if (vividBloomMat == null) { vividBloomMat = new Material(Shader.Find("BF/PostEffect/VividBloom")); } return vividBloomMat; } } Material blitCopyMat; public Material BlitCopyMat { get { if (blitCopyMat == null) { blitCopyMat = new Material(Shader.Find("BF/PostEffect/BlitCopy")); } return blitCopyMat; } } Material fxaaMat; public Material FxaaMat { get { if (fxaaMat == null) { fxaaMat = new Material(Shader.Find("BF/PostEffect/Fxaa")); } return fxaaMat; } } Material radialBlurMat; public Material RadialBlurMat { get { if (radialBlurMat == null) { radialBlurMat = new Material(Shader.Find("BF/PostEffect/RadialBlur")); } return radialBlurMat; } } Material meshOutlineMaskMat; public Material MeshOutlineMaskMat { get { if (meshOutlineMaskMat == null) { meshOutlineMaskMat = new Material(Shader.Find("BF/Mesh/OutlineMask")); } return meshOutlineMaskMat; } } Material meshOutlineFillMat; public Material MeshOutlineFillMat { get { if (meshOutlineFillMat == null) { meshOutlineFillMat = new Material(Shader.Find("BF/Mesh/OutlineFill")); } return meshOutlineFillMat; } } static RenderManager instance; public static RenderManager Create() { BFLog.LogAssert(instance == null, "This method only allows BFMain to call once"); instance = new RenderManager(); instance.Init(); return instance; } private RenderManager() { } public override void Init() { BlurSizeID = Shader.PropertyToID("_BlurSize"); BloomID = Shader.PropertyToID("_Bloom"); } public void SetUIDefaultMat(Material material) { uiDefaultMat = material; } public void SetUITutorialMat(Material material) { uiTutorialMat = material; } public void SetBlurMat(Material material) { blurMat = material; } public void SetBloomMat(Material material) { bloomMat = material; } public void SetBlitCopyMat(Material material) { blitCopyMat = material; } public void SetVividBloomMat(Material material) { vividBloomMat = material; } public void SetFxaaMat(Material material) { fxaaMat = material; } public void SetRadialBlur(Material material) { radialBlurMat = material; } public void SetMeshOutlineMaskMat(Material material) { meshOutlineMaskMat = material; } public void SetMeshOutlineFillMat(Material material) { meshOutlineFillMat = material; } public void SetGrey(MaskableGraphic mg, bool isGrey, byte greyLv = 10) { if (isGrey) { var greyColor = new Color32((byte)(11 - greyLv), 0, 255, 255); mg.color = greyColor; } else { mg.color = Color.white; } } /// /// 获取一张模糊图 /// public RenderTexture GetBlurBg(Camera[] targetCameras, int width, int height, int iteration = 4) { Array.Sort(targetCameras, (x, y) => x.depth.CompareTo(y.depth)); rt0 = RenderTexture.GetTemporary(width, height); var i = 0; for (; i < targetCameras.Length; i++) { targetCameras[i].targetTexture = rt0; targetCameras[i].Render(); targetCameras[i].targetTexture = null; } i = 0; for (; i < iteration; i++) { BlurMat.SetFloat(BlurSizeID, 1 + i); rt1 = RenderTexture.GetTemporary(width, height); Graphics.Blit(rt0, rt1, BlurMat, 0); RenderTexture.ReleaseTemporary(rt0); rt0 = RenderTexture.GetTemporary(width, height); Graphics.Blit(rt1, rt0, BlurMat, 1); RenderTexture.ReleaseTemporary(rt1); } return rt0; } /// /// 获取一张带bloom的模糊图 /// public RenderTexture GetBlurBgWithBloom(Camera[] targetCameras, int width, int height, int iteration = 4) { Array.Sort(targetCameras, (x, y) => x.depth.CompareTo(y.depth)); rt0 = RenderTexture.GetTemporary(width, height); var i = 0; for (; i < targetCameras.Length; i++) { targetCameras[i].targetTexture = rt0; targetCameras[i].Render(); targetCameras[i].targetTexture = null; } i = 0; for (; i < iteration; i++) { BloomMat.SetFloat(BlurSizeID, 1 + i); rt1 = RenderTexture.GetTemporary(width, height); Graphics.Blit(rt0, rt1, BloomMat, 1); RenderTexture.ReleaseTemporary(rt0); rt0 = RenderTexture.GetTemporary(width, height); Graphics.Blit(rt1, rt0, BloomMat, 2); RenderTexture.ReleaseTemporary(rt1); } rt2 = RenderTexture.GetTemporary(width, height); Graphics.Blit(rt0, rt2, BloomMat, 0); for (; i < iteration; i++) { BloomMat.SetFloat(BlurSizeID, 1 + i); rt1 = RenderTexture.GetTemporary(width / 4, height / 4); Graphics.Blit(rt2, rt1, BloomMat, 1); RenderTexture.ReleaseTemporary(rt2); rt2 = RenderTexture.GetTemporary(width / 4, height / 4); Graphics.Blit(rt1, rt2, BloomMat, 2); RenderTexture.ReleaseTemporary(rt1); } BloomMat.SetTexture(BloomID, rt2); rt1 = RenderTexture.GetTemporary(width, height); Graphics.Blit(rt0, rt1, BloomMat, 3); RenderTexture.ReleaseTemporary(rt2); RenderTexture.ReleaseTemporary(rt0); return rt1; } /// /// 获取一张截图 /// public void GetScreenShot(Action onTexture) { if (mono != null) { mono.StartCoroutine(GetScreenshot(onTexture)); } } IEnumerator GetScreenshot(Action onTexture) { yield return new WaitForEndOfFrame(); var texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false); texture.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, false); texture.Apply(); onTexture?.Invoke(texture); } /// /// 获取一张截图 /// public Texture2D GetScreenShot(Camera[] targetCameras, Rect rect) { Array.Sort(targetCameras, (x, y) => x.depth.CompareTo(y.depth)); rt0 = RenderTexture.GetTemporary((int)rect.width, (int)rect.height); for (var i = 0; i < targetCameras.Length; i++) { targetCameras[i].targetTexture = rt0; targetCameras[i].Render(); targetCameras[i].targetTexture = null; } RenderTexture.active = rt0; var texture = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false); texture.ReadPixels(rect, 0, 0); texture.Apply(); RenderTexture.active = null; RenderTexture.ReleaseTemporary(rt0); return texture; } /// /// 获取一张截图 /// public Texture2D GetScreenShot(Camera[] targetCameras) { return GetScreenShot(targetCameras, new Rect(0, 0, Screen.width, Screen.height)); } /// /// 打开后处理 /// public PostEffectBehaviour OpenPostEffect(int effectType, Camera camera) { return OpenPostEffect((PostEffectType)effectType, camera); } /// /// 打开后处理 /// public PostEffectBehaviour OpenPostEffect(PostEffectType effectType, Camera camera) { var peb = camera.gameObject.GetMissingComponent(); peb.OpenPostEffect(effectType); return peb; } /// /// 关闭后处理 /// public void ClosePostEffect(PostEffectType effectType, Camera camera) { var peb = camera.gameObject.GetComponent(); if (peb != null && peb.enabled) { peb.ClosePostEffect(effectType); } } /// /// 关闭后处理 /// public void ClosePostEffect(int effectType, Camera camera) { var peb = camera.gameObject.GetComponent(); if (peb != null && peb.enabled) { peb.ClosePostEffect((PostEffectType)effectType); } } public override void Destroy() { instance = null; } } }