diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RLPro/RLPRO_CRT.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RLPro/RLPRO_CRT.cs index e3ab14e6..75c07baa 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RLPro/RLPRO_CRT.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RLPro/RLPRO_CRT.cs @@ -10,25 +10,37 @@ namespace AxibugEmuOnline.Client.Filters protected override string ShaderName => null; #region BleedPass_Param - public FilterParameter<EnumBleedMode> BleedMode = new FilterParameter<EnumBleedMode>(EnumBleedMode.NTSCOld3Phase); + public FilterParameter<EnumBleedMode> BleedMode = EnumBleedMode.NTSCOld3Phase; [Range(0, 15)] - public FloatParameter BleedAmount = new FloatParameter(1f); + public FloatParameter BleedAmount = 1f; #endregion #region CRTAperture_Param [Range(0, 5)] - public FloatParameter GlowHalation = new FloatParameter(0.1f); + public FloatParameter GlowHalation = 0.1f; [Range(0, 2)] - public FloatParameter GlowDifusion = new FloatParameter(0.05f); + public FloatParameter GlowDifusion = 0.05f; [Range(0, 2)] - public FloatParameter MaskColors = new FloatParameter(2.0f); + public FloatParameter MaskColors = 2.0f; [Range(0, 1)] - public FloatParameter MaskStrength = new FloatParameter(0.3f); + public FloatParameter MaskStrength = 0.3f; [Range(0, 5)] - public FloatParameter GammaInput = new FloatParameter(2.4f); + public FloatParameter GammaInput = 2.4f; [Range(0, 5)] - public FloatParameter GammaOutput = new FloatParameter(2.4f); + public FloatParameter GammaOutput = 2.4f; [Range(0, 2.5f)] - public FloatParameter Brightness = new FloatParameter(1.5f); + public FloatParameter Brightness = 1.5f; + #endregion + #region TV_Effect_Param + public FilterParameter<EnumWrapMode> WrapMode = EnumWrapMode.SimpleWrap; + public FloatParameter maskDark = 0.5f; + public FloatParameter maskLight = 1.5f; + public FloatParameter hardScan = -8.0f; + public FloatParameter hardPix = -3.0f; + public Vector2Parameter warp = new Vector2(1.0f / 32.0f, 1.0f / 24.0f); + public Vector2Parameter res; + public FloatParameter resScale; + public FloatParameter scale; + public FloatParameter fade; #endregion Material m_bleedMat; @@ -39,17 +51,20 @@ namespace AxibugEmuOnline.Client.Filters { m_bleedMat = new Material(Shader.Find("Filter/RLPro_Bleed")); m_crtApertureMat = new Material(Shader.Find("Filter/RLPro_CRT_Aperture")); + m_tvEffectMat = new Material(Shader.Find("Filter/RLPro_TV_Effect")); } protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) { var rt1 = BleedPass(src); var rt2 = CRT_AperturePass(rt1); + var rt3 = TV_Effect_Pass(rt2); - Graphics.Blit(rt2, result); + Graphics.Blit(rt3, result); RenderTexture.ReleaseTemporary(rt1); RenderTexture.ReleaseTemporary(rt2); + RenderTexture.ReleaseTemporary(rt3); } private RenderTexture BleedPass(Texture src) @@ -95,6 +110,34 @@ namespace AxibugEmuOnline.Client.Filters return rt; } + private RenderTexture TV_Effect_Pass(Texture src) + { + var rt = RenderTexture.GetTemporary(src.width, src.height); + + m_tvEffectMat.DisableKeyword("_SimpleWrap"); + m_tvEffectMat.DisableKeyword("_CubicDistortion"); + + switch (WrapMode.GetValue()) + { + case EnumWrapMode.SimpleWrap: + m_tvEffectMat.EnableKeyword("_SimpleWrap"); break; + case EnumWrapMode.CubicDistortion: + m_tvEffectMat.EnableKeyword("_CubicDistortion"); break; + } + + m_tvEffectMat.SetFloat("maskDark", maskDark.GetValue()); + m_tvEffectMat.SetFloat("maskLight", maskLight.GetValue()); + m_tvEffectMat.SetFloat("hardScan", hardScan.GetValue()); + m_tvEffectMat.SetVector("warp", warp.GetValue()); + m_tvEffectMat.SetVector("res", res.GetValue()); + m_tvEffectMat.SetFloat("resScale", resScale.GetValue()); + m_tvEffectMat.SetFloat("scale", scale.GetValue()); + m_tvEffectMat.SetFloat("fade", fade.GetValue()); + + Graphics.Blit(src, rt, m_tvEffectMat); + + return rt; + } public enum EnumBleedMode { @@ -102,5 +145,11 @@ namespace AxibugEmuOnline.Client.Filters NTSC3Phase, NTSC2Phase, } + + public enum EnumWrapMode + { + SimpleWrap, + CubicDistortion + } } } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RLPro/RLPro_TV_Effect.shader b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RLPro/RLPro_TV_Effect.shader new file mode 100644 index 00000000..0be47b3d --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RLPro/RLPro_TV_Effect.shader @@ -0,0 +1,162 @@ +Shader "Filter/RLPro_TV_Effect" +{ + Properties + { + _MainTex ("Base (RGB)", 2D) = "white" {} + } + SubShader + { + Pass + { + CGPROGRAM + + #pragma shader_feature_local _SimpleWrap _CubicDistortion + #pragma vertex vert_img + #pragma fragment Frag + #include "UnityCG.cginc" + + sampler2D _MainTex; + float4 _MainTex_TexelSize; + float2 _iResolution; + + float maskDark = 0.5; + float maskLight = 1.5; + float hardScan = -8.0; + float hardPix = -3.0; + float2 warp = float2(1.0 / 32.0, 1.0 / 24.0); + float2 res; + float resScale; + float scale; + float fade; + + struct v2f + { + float4 pos : POSITION; + float2 uv : TEXCOORD0; + }; + + float3 Fetch(float2 pos, float2 off) + { + pos = floor(pos * res + off) / res; + return tex2Dlod(_MainTex, float4(pos.xy, 0, -16.0)).rgb; + } + + float2 Dist(float2 pos) { pos = pos * res; return -((pos - floor(pos)) - float2(0.5, 0.5)); } + float Gaus(float pos, float scale) { return exp2(scale * pos * pos); } + + float3 Horz3(float2 pos, float off) + { + float3 b = Fetch(pos, float2(-1.0, off)); + float3 c = Fetch(pos, float2(0.0, off)); + float3 d = Fetch(pos, float2(1.0, off)); + float dst = Dist(pos).x; + float scale = hardPix; + float wb = Gaus(dst - 1.0, scale); + float wc = Gaus(dst + 0.0, scale); + float wd = Gaus(dst + 1.0, scale); + return (b * wb + c * wc + d * wd) / (wb + wc + wd); + } + + float3 Horz5(float2 pos, float off) + { + float3 a = Fetch(pos, float2(-2.0, off)); + float3 b = Fetch(pos, float2(-1.0, off)); + float3 c = Fetch(pos, float2(0.0, off)); + float3 d = Fetch(pos, float2(1.0, off)); + float3 e = Fetch(pos, float2(2.0, off)); + float dst = Dist(pos).x; + float scale = hardPix; + float wa = Gaus(dst - 2.0, scale); + float wb = Gaus(dst - 1.0, scale); + float wc = Gaus(dst + 0.0, scale); + float wd = Gaus(dst + 1.0, scale); + float we = Gaus(dst + 2.0, scale); + return (a * wa + b * wb + c * wc + d * wd + e * we) / (wa + wb + wc + wd + we); + } + + float Scan(float2 pos, float off) + { + float dst = Dist(pos).y; + return Gaus(dst + off, hardScan); + } + + float3 Tri(float2 pos) + { + float3 a = Horz3(pos, -1.0); + float3 b = Horz5(pos, 0.0); + float3 c = Horz3(pos, 1.0); + float wa = Scan(pos, -1.0); + float wb = Scan(pos, 0.0); + float wc = Scan(pos, 1.0); + return a * wa + b * wb + c * wc; + } + + float2 Warp(float2 pos) + { + float2 h = pos - float2(0.5, 0.5); + float r2 = dot(h, h); + float f = 1.0 + r2 * (warp.x + warp.y * sqrt(r2)); + return f * scale * h + 0.5; + } + + float2 Warp1(float2 pos) + { + pos = pos * 2.0 - 1.0; + pos *= float2(1.0 + (pos.y * pos.y) * warp.x, 1.0 + (pos.x * pos.x) * warp.y); + return pos * scale + 0.5; + } + + float3 Mask(float2 pos) + { + pos.x += pos.y * 3.0; + float3 mask = float3(maskDark, maskDark, maskDark); + pos.x = frac(pos.x / 6.0); + if (pos.x < 0.333)mask.r = maskLight; + else if (pos.x < 0.666)mask.g = maskLight; + else mask.b = maskLight; + return mask; + } + + float4 SimpleWrapFrag(v2f i) + { + float2 uv = i.uv; + + float4 col = tex2D(_MainTex,uv); + res = _ScreenParams.xy / resScale; + float2 fragCoord = uv * _ScreenParams.xy; + float4 fragColor = 0; + float2 pos = Warp1(fragCoord.xy / _ScreenParams.xy); + fragColor.rgb = Tri(pos) * Mask(fragCoord); + fragColor.a = tex2D(_MainTex,pos).a; + + return lerp(col,fragColor,fade); + } + + float4 CubicDistortionFrag(v2f i) + { + float2 uv = i.uv; + + float4 col = tex2D(_MainTex,uv); + res = _iResolution.xy / resScale; + float2 fragCoord = uv * _ScreenParams.xy; + float4 fragColor = 0; + float2 pos = Warp(fragCoord.xy / _ScreenParams.xy); + fragColor.rgb = Tri(pos) * Mask(fragCoord); + fragColor.a = tex2D(_MainTex,pos).a; + + return lerp(col,fragColor,fade); + } + + float4 Frag(v2f i) : SV_Target + { +#if _SimpleWrap + return SimpleWrapFrag(i); +#else + return CubicDistortionFrag(i); +#endif + } + + ENDCG + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RLPro/RLPro_TV_Effect.shader.meta b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RLPro/RLPro_TV_Effect.shader.meta new file mode 100644 index 00000000..1aceaad1 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RLPro/RLPro_TV_Effect.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: bef4d98671a3c524f9bfdba0d25e5991 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: