2023-04-03 11:04:31 +08:00

419 lines
12 KiB
C#

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;
}
}
/// <summary>
/// 获取一张模糊图
/// </summary>
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;
}
/// <summary>
/// 获取一张带bloom的模糊图
/// </summary>
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;
}
/// <summary>
/// 获取一张截图
/// </summary>
public void GetScreenShot(Action<Texture2D> onTexture)
{
if (mono != null)
{
mono.StartCoroutine(GetScreenshot(onTexture));
}
}
IEnumerator GetScreenshot(Action<Texture2D> 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);
}
/// <summary>
/// 获取一张截图
/// </summary>
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;
}
/// <summary>
/// 获取一张截图
/// </summary>
public Texture2D GetScreenShot(Camera[] targetCameras)
{
return GetScreenShot(targetCameras, new Rect(0, 0, Screen.width, Screen.height));
}
/// <summary>
/// 打开后处理
/// </summary>
public PostEffectBehaviour OpenPostEffect(int effectType, Camera camera)
{
return OpenPostEffect((PostEffectType)effectType, camera);
}
/// <summary>
/// 打开后处理
/// </summary>
public PostEffectBehaviour OpenPostEffect(PostEffectType effectType, Camera camera)
{
var peb = camera.gameObject.GetMissingComponent<PostEffectBehaviour>();
peb.OpenPostEffect(effectType);
return peb;
}
/// <summary>
/// 关闭后处理
/// </summary>
public void ClosePostEffect(PostEffectType effectType, Camera camera)
{
var peb = camera.gameObject.GetComponent<PostEffectBehaviour>();
if (peb != null && peb.enabled)
{
peb.ClosePostEffect(effectType);
}
}
/// <summary>
/// 关闭后处理
/// </summary>
public void ClosePostEffect(int effectType, Camera camera)
{
var peb = camera.gameObject.GetComponent<PostEffectBehaviour>();
if (peb != null && peb.enabled)
{
peb.ClosePostEffect((PostEffectType)effectType);
}
}
public override void Destroy()
{
instance = null;
}
}
}