using System; using System.Collections.Generic; using UnityEngine; [Serializable] public class Class3dScreenOverlay { [Serializable] public class Overlay { public enum PostFilmMode { None, Lerp, Add, Mul, VignetteLerp, VignetteAdd, VignetteMul, Monochrome, ScreenBlend, VignetteScreenBlend } public enum LayerMode { Color, UVMovie, UVMovieNoScale } public enum ColorBlend { None, Lerp, Additive, Multiply } public static readonly string[] SHADER_KEYWORD_MODE = new string[10] { "MODE_NONE", "MODE_LERP", "MODE_ADD", "MODE_MUL", "MODE_VIGNETTE_LERP", "MODE_VIGNETTE_ADD", "MODE_VIGNETTE_MUL", "MODE_MONOCHROME", "MODE_SCREENBLEND", "MODE_VIGNETT_SCREENBLEND" }; public static readonly string[] SHADER_KEYWORD_BLEND = new string[5] { "COLOR_ONLY", "BLEND_NONE", "BLEND_LERP", "BLEND_ADD", "BLEND_MUL" }; public const float DEFAULT_DEPTH_CLIP = 2f; public PostFilmMode postFilmMode; public float postFilmPower; public float depthPower; public float DepthClip = 2f; public Vector2 postFilmOffsetParam = Vector2.zero; public Vector4 postFilmOptionParam = Vector4.zero; public Color postFilmColor0 = Color.black; public Color postFilmColor1 = Color.black; public Color postFilmColor2 = Color.black; public Color postFilmColor3 = Color.black; public bool inverseVignette; public LayerMode layerMode; public ColorBlend colorBlend; public int movieResId; private bool _isExistMovieMask; private Texture _movieTexture; private Texture _movieMaskTexture; private Vector2 _movieTextureScale = Vector2.one; private Vector2 _movieTextureOffset = Vector2.zero; public float colorBlendFactor; public Vector4 RollParameter; public Vector4 ScaleParameter = Vector4.one; private bool _isUVMovieNoScale; public bool IsEnableDepth = true; public void SetMovieInfo(Texture texMovie, Texture texMask, Vector2 scale, Vector2 offset) { _movieTexture = texMovie; _movieMaskTexture = texMask; _movieTextureScale = scale; _movieTextureOffset = offset; _isExistMovieMask = !(texMask == null); } public void SetScale(Vector2 scale) { ScaleParameter.x = 1f / scale.x; ScaleParameter.y = 1f / scale.y; } public void SetRollAngle(float angle) { RollParameter.x = Mathf.Sin(angle * (float)Math.PI / 180f); RollParameter.y = Mathf.Cos(angle * (float)Math.PI / 180f); } public Overlay() { SetRollAngle(0f); } private static void SetShaderKeyword(int id, string[] _arrKeywords, Material mtrl) { for (int i = 0; i < _arrKeywords.Length; i++) { if (id != i) { mtrl.DisableKeyword(_arrKeywords[i]); } } if (0 < id && id < _arrKeywords.Length) { mtrl.EnableKeyword(_arrKeywords[id]); } } public void Update(Material mtrl, RenderTexture mainTexture) { if (mtrl == null) { return; } SetShaderKeyword((int)postFilmMode, SHADER_KEYWORD_MODE, mtrl); switch (layerMode) { case LayerMode.Color: SetShaderKeyword((int)layerMode, SHADER_KEYWORD_BLEND, mtrl); break; case LayerMode.UVMovie: case LayerMode.UVMovieNoScale: SetShaderKeyword((int)layerMode + (int)colorBlend, SHADER_KEYWORD_BLEND, mtrl); if (_movieTexture != null) { mtrl.SetTexture("_texMovie", _movieTexture); float num = 0f; float num2 = (float)mainTexture.width / num; float num3 = (float)mainTexture.height / num; float num4 = 7f; float num5 = 3f; if (2.3333333f > num2 / num3) { num4 *= Mathf.Ceil(num2 / num4); num5 *= Mathf.Ceil(num3 / num5); } ScaleParameter.z = num2 / num4; ScaleParameter.w = num3 / num5; } break; } _isUVMovieNoScale = layerMode == LayerMode.UVMovieNoScale; if (_isExistMovieMask && _movieMaskTexture != null) { mtrl.SetTexture("_texMovieMask", _movieMaskTexture); } mtrl.SetVector("_movieScale", _movieTextureScale); mtrl.SetVector("_movieOffset", _movieTextureOffset); mtrl.SetFloat("_colorBlendFactor", colorBlendFactor); } public bool IsDepthValid() { if (!IsEnableDepth) { return false; } return IsValid(); } public bool IsValid() { bool result = true; switch (postFilmMode) { case PostFilmMode.Monochrome: result = postFilmColor0.a > 0f; break; case PostFilmMode.None: result = false; break; default: result = postFilmPower > 0f; break; case PostFilmMode.Mul: case PostFilmMode.VignetteLerp: case PostFilmMode.VignetteMul: break; } return result; } public void Blit(RenderTexture source, RenderTexture destination, Material material, int pass) { if (inverseVignette) { pass++; } Update(material, source); Vector4 value = new Vector4(postFilmOffsetParam.x, postFilmOffsetParam.y); material.SetFloat("_PostFilmPower", postFilmPower); material.SetFloat("_DepthPower", depthPower); float value2 = ((!(DepthClip > 1.5f)) ? (1.5f - DepthClip) : 0f); material.SetFloat("_DepthClip", value2); material.SetVector("_PostFilmOffsetParam", value); material.SetVector("_PostFilmOptionParam", postFilmOptionParam); material.SetColor("_PostFilmColor0", postFilmColor0); material.SetColor("_PostFilmColor1", postFilmColor1); material.SetColor("_PostFilmColor2", postFilmColor2); material.SetColor("_PostFilmColor3", postFilmColor3); RollParameter.z = (float)source.width / (float)source.height; material.SetVector("_PostFilmRollParameter", RollParameter); material.SetVector("_PostFilmScaleParameter", ScaleParameter); material.SetFloat("_PostFilmIsUVMovieNoScale", _isUVMovieNoScale ? 1f : 0f); material.SetFloat("_PostFilmIsInverseVignette", inverseVignette ? 1f : 0f); material.SetFloat("_PostFilmIsAlphaMasking", _isExistMovieMask ? 1f : 0f); material.SetFloat("_PostFilmIsWithoutDepth", IsEnableDepth ? 0f : 1f); Graphics.Blit(source, destination, material, pass); } } [SerializeField] [Header("Screen Overlay - First layer")] private Overlay _overlay1 = new Overlay(); [SerializeField] [Header("Screen Overlay - Second layer")] private Overlay _overlay2 = new Overlay(); [SerializeField] [Header("Screen Overlay - Third layer")] private Overlay _overlay3 = new Overlay(); public bool IsScreenOverlay = true; public Overlay Overlay1 => _overlay1; public Overlay Overlay2 => _overlay2; public Overlay Overlay3 => _overlay3; public bool IsEnable { get { if (!_overlay1.IsValid() && !_overlay2.IsValid()) { return _overlay3.IsValid(); } return true; } } public bool IsUseDepthTexture { get { if (!_overlay1.IsDepthValid() && !_overlay2.IsDepthValid()) { return _overlay3.IsDepthValid(); } return true; } } public void PostFilmBlit(RenderTexture source, RenderTexture destination, Material material, int defaultPass, int filmPass1st, int filmPass2nd) { if (material == null || !IsScreenOverlay) { Graphics.Blit(source, destination); return; } bool num = Overlay1.IsValid(); bool flag = Overlay2.IsValid(); bool flag2 = Overlay3.IsValid(); RenderTexture renderTexture = destination; RenderTexture source2 = source; if (flag || flag2) { renderTexture = RenderTexture.GetTemporary(source.width, source.height, source.depth); } if (num) { Overlay1.Blit(source2, renderTexture, material, filmPass1st); } else if (defaultPass >= 0) { Graphics.Blit(source2, renderTexture, material, defaultPass); } else { Graphics.Blit(source2, renderTexture); } source2 = renderTexture; renderTexture = destination; if (flag) { if (flag2) { renderTexture = RenderTexture.GetTemporary(source.width, source.height, source.depth); } Overlay2.Blit(source2, renderTexture, material, filmPass2nd); if (source2 != source) { RenderTexture.ReleaseTemporary(source2); source2 = renderTexture; renderTexture = destination; } } if (flag2) { Overlay3.Blit(source2, renderTexture, material, filmPass2nd); if (source2 != source) { RenderTexture.ReleaseTemporary(source2); source2 = renderTexture; renderTexture = destination; } } } public static void SetShaderVariantKeyword(List keywordList) { keywordList.AddRange(Overlay.SHADER_KEYWORD_MODE); keywordList.AddRange(Overlay.SHADER_KEYWORD_BLEND); } }