From ad3d090e75420ad58cebeaaecdd9ef2eded2a8d8 Mon Sep 17 00:00:00 2001 From: "ALIENJACK\\alien" Date: Sat, 25 Jan 2025 10:00:52 +0800 Subject: [PATCH 1/4] no descript --- .../Script/AppMain/Emulator/NesEmulator/CoreSupporter.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/CoreSupporter.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/CoreSupporter.cs index e1c2aea1..46eecf8b 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/CoreSupporter.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/CoreSupporter.cs @@ -120,7 +120,10 @@ namespace AxibugEmuOnline.Client m_sampledState = FromNet(replayData); } - else m_sampledState = default(ControllerState); + else + { + m_sampledState = default(ControllerState); + } var localState = m_controllerMapper.CreateState(); var rawData = ToNet(localState); From f11e36c83f7ee514788aeb77e387dcc5bd8f4e02 Mon Sep 17 00:00:00 2001 From: "ALIENJACK\\alien" Date: Sat, 25 Jan 2025 11:24:27 +0800 Subject: [PATCH 2/4] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=B7=A6=E4=B8=8B?= =?UTF-8?q?=E8=A7=92=E6=89=8B=E6=9F=84=E4=BF=A1=E6=81=AFUI,=E5=9C=A8?= =?UTF-8?q?=E6=94=B6=E5=88=B0=E6=8C=89=E9=94=AE=E4=BF=A1=E5=8F=B7=E6=97=B6?= =?UTF-8?q?=E6=8A=96=E5=8A=A8=E6=95=88=E6=9E=9C=E5=8F=AF=E8=83=BD=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E5=9D=90=E6=A0=87=E5=81=8F=E7=A7=BB=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98(=E8=BF=99=E6=98=AF=E4=B8=80=E4=B8=AA=E4=B8=B4?= =?UTF-8?q?=E6=97=B6=E6=95=88=E6=9E=9C,=E5=90=8E=E7=BB=AD=E6=94=B9?= =?UTF-8?q?=E6=88=90=E5=AF=B9=E5=BA=94=E9=94=AE=E5=80=BC=E6=8C=89=E4=B8=8B?= =?UTF-8?q?=E5=8A=A8=E7=94=BB)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Assets/Script/AppMain/UI/XMBTopGroupUI/ControllerInfo.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/XMBTopGroupUI/ControllerInfo.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/XMBTopGroupUI/ControllerInfo.cs index 261b64f5..c7146aed 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/XMBTopGroupUI/ControllerInfo.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/XMBTopGroupUI/ControllerInfo.cs @@ -45,6 +45,8 @@ public class ControllerInfo : MonoBehaviour Eventer.Instance.RegisterEvent(EEvent.OnLossLoginState, OnLossLoginState); Eventer.Instance.RegisterEvent(EEvent.OnControllerConnectChanged, OnControlConnectChanged); UpdateConnectInfo(); + + m_indexIcon.rectTransform.anchoredPosition = Vector3.zero; } private void OnDisable() From 8970c7e3350bbe6db165ca50ae91dff88ef07c18 Mon Sep 17 00:00:00 2001 From: "ALIENJACK\\alien" Date: Sat, 25 Jan 2025 16:14:10 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=BB=A4=E9=95=9C=E5=86=8D=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E4=B8=80=E4=B8=AA(=E5=BD=93=E7=84=B6,=E8=B7=9Fpsv?= =?UTF-8?q?=E6=B2=A1=E5=85=B3=E7=B3=BB)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Filter/1990-esque/Filter1990_esque.cs | 22 +- .../AppSettings/Filter/FilterEffect.cs | 9 +- .../FixingPixelArtGrille.cs | 123 ++-- .../Filter/LCDPostEffect/LCDPostEffect.cs | 22 +- .../Filter/MattiasCRT/MattiasCRT.cs | 71 +- .../RetroArch_Glow/RetroArchMattiasCRTGlow.cs | 114 +-- .../AppSettings/Filter/SimpleCRT/SimpleCRT.cs | 296 ++++---- .../AppSettings/Filter/UltimateCRT.meta | 8 + .../Filter/UltimateCRT/Shaders.meta | 8 + .../UltimateCRT/Shaders/CRTBlur.cg.shader | 71 ++ .../Shaders/CRTBlur.cg.shader.meta | 9 + .../Shaders/CRTFinalPostprocess.cg.shader | 192 +++++ .../CRTFinalPostprocess.cg.shader.meta | 9 + .../Shaders/CRTPostprocess.cg.shader | 220 ++++++ .../Shaders/CRTPostprocess.cg.shader.meta | 9 + .../Filter/UltimateCRT/UltimateCRT.cs | 663 ++++++++++++++++++ .../Filter/UltimateCRT/UltimateCRT.cs.meta | 2 + .../OptionUI_ValueEditItem_FloatEdit.cs | 2 +- 18 files changed, 1530 insertions(+), 320 deletions(-) create mode 100644 AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT.meta create mode 100644 AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders.meta create mode 100644 AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTBlur.cg.shader create mode 100644 AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTBlur.cg.shader.meta create mode 100644 AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTFinalPostprocess.cg.shader create mode 100644 AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTFinalPostprocess.cg.shader.meta create mode 100644 AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTPostprocess.cg.shader create mode 100644 AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTPostprocess.cg.shader.meta create mode 100644 AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/UltimateCRT.cs create mode 100644 AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/UltimateCRT.cs.meta diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/1990-esque/Filter1990_esque.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/1990-esque/Filter1990_esque.cs index 66806c4c..46a6f012 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/1990-esque/Filter1990_esque.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/1990-esque/Filter1990_esque.cs @@ -1,14 +1,16 @@ -using AxibugEmuOnline.Client; -using UnityEngine; +using UnityEngine; -public class Filter1990_esque : FilterEffect +namespace AxibugEmuOnline.Client.Filters { - public override string Name => "1990-esque"; - - protected override string ShaderName => "Filter/1990-esque"; - - protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) + public class Filter1990_esque : FilterEffect { - Graphics.Blit(src, result, renderMat, 1); + public override string Name => "1990-esque"; + + protected override string ShaderName => "Filter/1990-esque"; + + protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) + { + Graphics.Blit(src, result, renderMat, 1); + } } -} +} diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/FilterEffect.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/FilterEffect.cs index c8c37020..feb1eb88 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/FilterEffect.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/FilterEffect.cs @@ -34,7 +34,12 @@ namespace AxibugEmuOnline.Client protected virtual void Init() { - m_material = new Material(Shader.Find(ShaderName)); + if (ShaderName != null) + { + var shader = Shader.Find(ShaderName); + if (shader != null) m_material = new Material(Shader.Find(ShaderName)); + } + OnInit(m_material); } @@ -66,7 +71,7 @@ namespace AxibugEmuOnline.Client public virtual void Render(Texture src, RenderTexture result) { - m_material.SetVector(m_iResolutionID, new Vector4(result.width, result.height)); + if (m_material != null) m_material.SetVector(m_iResolutionID, new Vector4(result.width, result.height)); OnRenderer(m_material, src, result); } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/FixingPixelArtGrille/FixingPixelArtGrille.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/FixingPixelArtGrille/FixingPixelArtGrille.cs index 63840bd9..a138add2 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/FixingPixelArtGrille/FixingPixelArtGrille.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/FixingPixelArtGrille/FixingPixelArtGrille.cs @@ -1,72 +1,75 @@ using Assets.Script.AppMain.Filter; -using AxibugEmuOnline.Client; using UnityEngine; -[Strip(RuntimePlatform.PSP2)] -public sealed class FixingPixelArtGrille : FilterEffect +namespace AxibugEmuOnline.Client.Filters { - public override string Name => nameof(FixingPixelArtGrille); - protected override string ShaderName => "PostEffect/FixingPixcelArtGrille"; - public FilterParameter MaskStyle = new FilterParameter(EnumMaskStyle.ApertureGrille); - public Vector2Parameter DrawResolution = new Vector2Parameter(new Vector2(272, 240)); - [Range(-32, 0)] - public FloatParameter HardScan = new FloatParameter(-10); - [Range(-6, 0)] - public FloatParameter HardPix = new FloatParameter(-2); - [Range(-8, 0)] - public FloatParameter HardBloomScan = new FloatParameter(-4.0f); - [Range(-4, 0)] - public FloatParameter HardBloomPix = new FloatParameter(-1.5f); - [Range(0, 1)] - public FloatParameter BloomAmount = new FloatParameter(1 / 16f); - public Vector2Parameter Warp = new Vector2Parameter(new Vector2(1f / 64f, 1f / 24f)); - [Range(1, 3)] - public FloatParameter MaskLight = new FloatParameter(1.5f); - [Range(0.1f, 1)] - public FloatParameter MaskDrak = new FloatParameter(0.5f); - - public enum EnumMaskStyle + [Strip(RuntimePlatform.PSP2)] + public sealed class FixingPixelArtGrille : FilterEffect { - TVStyle, - ApertureGrille, - StretchedVGA, - VGAStyle - } + public override string Name => nameof(FixingPixelArtGrille); + protected override string ShaderName => "PostEffect/FixingPixcelArtGrille"; + public FilterParameter MaskStyle = new FilterParameter(EnumMaskStyle.ApertureGrille); + public Vector2Parameter DrawResolution = new Vector2Parameter(new Vector2(272, 240)); + [Range(-32, 0)] + public FloatParameter HardScan = new FloatParameter(-10); + [Range(-6, 0)] + public FloatParameter HardPix = new FloatParameter(-2); + [Range(-8, 0)] + public FloatParameter HardBloomScan = new FloatParameter(-4.0f); + [Range(-4, 0)] + public FloatParameter HardBloomPix = new FloatParameter(-1.5f); + [Range(0, 1)] + public FloatParameter BloomAmount = new FloatParameter(1 / 16f); + public Vector2Parameter Warp = new Vector2Parameter(new Vector2(1f / 64f, 1f / 24f)); + [Range(1, 3)] + public FloatParameter MaskLight = new FloatParameter(1.5f); + [Range(0.1f, 1)] + public FloatParameter MaskDrak = new FloatParameter(0.5f); - protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) - { - renderMat.SetVector("_res", new Vector4(DrawResolution.GetValue().x, DrawResolution.GetValue().y, 0, 0)); - renderMat.SetFloat("_hardScan", HardScan.GetValue()); - renderMat.SetFloat("_hardPix", HardPix.GetValue()); - renderMat.SetFloat("_hardBloomScan", HardBloomScan.GetValue()); - renderMat.SetFloat("_hardBloomPix", HardBloomPix.GetValue()); - renderMat.SetFloat("_bloomAmount", BloomAmount.GetValue()); - renderMat.SetVector("_warp", Warp.GetValue()); - renderMat.SetFloat("_maskDark", MaskDrak.GetValue()); - renderMat.SetFloat("_maskLight", MaskLight.GetValue()); - - renderMat.DisableKeyword("_MASKSTYLE_VGASTYLE"); - renderMat.DisableKeyword("_MASKSTYLE_TVSTYLE"); - renderMat.DisableKeyword("_MASKSTYLE_APERTUREGRILLE"); - renderMat.DisableKeyword("_MASKSTYLE_STRETCHEDVGA"); - - switch (MaskStyle.GetValue()) + public enum EnumMaskStyle { - case EnumMaskStyle.VGAStyle: - renderMat.EnableKeyword("_MASKSTYLE_VGASTYLE"); - break; - case EnumMaskStyle.TVStyle: - renderMat.EnableKeyword("_MASKSTYLE_TVSTYLE"); - break; - case EnumMaskStyle.ApertureGrille: - renderMat.EnableKeyword("_MASKSTYLE_APERTUREGRILLE"); - break; - case EnumMaskStyle.StretchedVGA: - renderMat.EnableKeyword("_MASKSTYLE_STRETCHEDVGA"); - break; + TVStyle, + ApertureGrille, + StretchedVGA, + VGAStyle + } + + + protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) + { + renderMat.SetVector("_res", new Vector4(DrawResolution.GetValue().x, DrawResolution.GetValue().y, 0, 0)); + renderMat.SetFloat("_hardScan", HardScan.GetValue()); + renderMat.SetFloat("_hardPix", HardPix.GetValue()); + renderMat.SetFloat("_hardBloomScan", HardBloomScan.GetValue()); + renderMat.SetFloat("_hardBloomPix", HardBloomPix.GetValue()); + renderMat.SetFloat("_bloomAmount", BloomAmount.GetValue()); + renderMat.SetVector("_warp", Warp.GetValue()); + renderMat.SetFloat("_maskDark", MaskDrak.GetValue()); + renderMat.SetFloat("_maskLight", MaskLight.GetValue()); + + renderMat.DisableKeyword("_MASKSTYLE_VGASTYLE"); + renderMat.DisableKeyword("_MASKSTYLE_TVSTYLE"); + renderMat.DisableKeyword("_MASKSTYLE_APERTUREGRILLE"); + renderMat.DisableKeyword("_MASKSTYLE_STRETCHEDVGA"); + + switch (MaskStyle.GetValue()) + { + case EnumMaskStyle.VGAStyle: + renderMat.EnableKeyword("_MASKSTYLE_VGASTYLE"); + break; + case EnumMaskStyle.TVStyle: + renderMat.EnableKeyword("_MASKSTYLE_TVSTYLE"); + break; + case EnumMaskStyle.ApertureGrille: + renderMat.EnableKeyword("_MASKSTYLE_APERTUREGRILLE"); + break; + case EnumMaskStyle.StretchedVGA: + renderMat.EnableKeyword("_MASKSTYLE_STRETCHEDVGA"); + break; + } + Graphics.Blit(src, result, renderMat); } - Graphics.Blit(src, result, renderMat); } } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/LCDPostEffect/LCDPostEffect.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/LCDPostEffect/LCDPostEffect.cs index 13aaee9e..e9492b80 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/LCDPostEffect/LCDPostEffect.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/LCDPostEffect/LCDPostEffect.cs @@ -1,14 +1,16 @@ -using AxibugEmuOnline.Client; -using UnityEngine; +using UnityEngine; -public sealed class LCDPostEffect : FilterEffect +namespace AxibugEmuOnline.Client.Filters { - public override string Name => nameof(LCDPostEffect); - - protected override string ShaderName => "Filter/LCDPostEffect"; - - protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) + public sealed class LCDPostEffect : FilterEffect { - Graphics.Blit(src, result, renderMat); + public override string Name => nameof(LCDPostEffect); + + protected override string ShaderName => "Filter/LCDPostEffect"; + + protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) + { + Graphics.Blit(src, result, renderMat); + } } -} +} diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/MattiasCRT/MattiasCRT.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/MattiasCRT/MattiasCRT.cs index 3e4a30ee..24e3b862 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/MattiasCRT/MattiasCRT.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/MattiasCRT/MattiasCRT.cs @@ -3,43 +3,46 @@ using AxibugEmuOnline.Client; using UnityEngine; using UnityEngine.Rendering; -public sealed class MattiasCRT : FilterEffect -{ - public override string Name => nameof(MattiasCRT); - - protected override string ShaderName => "Filter/MattiasCRT"; - - public FilterParameter Quality = new FilterParameter(EnumQuality.High); - private LocalKeyword _kw_qualityLow; - private LocalKeyword _kw_qualityMid; - private LocalKeyword _kw_qualityHigh; - - protected override void OnInit(Material renderMat) - { - _kw_qualityLow = new LocalKeyword(renderMat.shader, "_QUALITY_LOW"); - _kw_qualityMid = new LocalKeyword(renderMat.shader, "_QUALITY_MID"); - _kw_qualityHigh = new LocalKeyword(renderMat.shader, "_QUALITY_HIGH"); - } - - protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) +namespace AxibugEmuOnline.Client.Filters +{ + public sealed class MattiasCRT : FilterEffect { - renderMat.DisableKeyword(_kw_qualityLow); - renderMat.DisableKeyword(_kw_qualityMid); - renderMat.DisableKeyword(_kw_qualityHigh); - switch (Quality.GetValue()) + public override string Name => nameof(MattiasCRT); + + protected override string ShaderName => "Filter/MattiasCRT"; + + public FilterParameter Quality = new FilterParameter(EnumQuality.High); + private LocalKeyword _kw_qualityLow; + private LocalKeyword _kw_qualityMid; + private LocalKeyword _kw_qualityHigh; + + protected override void OnInit(Material renderMat) { - case EnumQuality.Low: renderMat.EnableKeyword(_kw_qualityLow); break; - case EnumQuality.Mid: renderMat.EnableKeyword(_kw_qualityMid); break; - case EnumQuality.High: renderMat.EnableKeyword(_kw_qualityHigh); break; + _kw_qualityLow = new LocalKeyword(renderMat.shader, "_QUALITY_LOW"); + _kw_qualityMid = new LocalKeyword(renderMat.shader, "_QUALITY_MID"); + _kw_qualityHigh = new LocalKeyword(renderMat.shader, "_QUALITY_HIGH"); } - Graphics.Blit(src, result, renderMat); - } + protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) + { + renderMat.DisableKeyword(_kw_qualityLow); + renderMat.DisableKeyword(_kw_qualityMid); + renderMat.DisableKeyword(_kw_qualityHigh); + switch (Quality.GetValue()) + { + case EnumQuality.Low: renderMat.EnableKeyword(_kw_qualityLow); break; + case EnumQuality.Mid: renderMat.EnableKeyword(_kw_qualityMid); break; + case EnumQuality.High: renderMat.EnableKeyword(_kw_qualityHigh); break; + } - public enum EnumQuality - { - Low, - Mid, - High - } + Graphics.Blit(src, result, renderMat); + } + + public enum EnumQuality + { + Low, + Mid, + High + } + } } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RetroArch_Glow/RetroArchMattiasCRTGlow.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RetroArch_Glow/RetroArchMattiasCRTGlow.cs index aeca378a..6d4719d6 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RetroArch_Glow/RetroArchMattiasCRTGlow.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/RetroArch_Glow/RetroArchMattiasCRTGlow.cs @@ -1,69 +1,71 @@ -using Assets.Script.AppMain.Filter; -using AxibugEmuOnline.Client; +using Assets.Script.AppMain.Filter; using UnityEngine; using UnityEngine.Rendering; -[Strip(RuntimePlatform.PSP2)] -public class RetroArchMattiasCRTGlow : FilterEffect +namespace AxibugEmuOnline.Client.Filters { - public override string Name => nameof(RetroArchMattiasCRTGlow); - protected override string ShaderName => "Filter/RetroArch/MattiasCRTWithGlow"; - - [Range(0.02f, 20f)] - public FloatParameter InputGamma = new FloatParameter(11); - [Range(0.02f, 1f)] - public FloatParameter GaussianWidth = new FloatParameter(0.4f); - [Range(0.02f, 1f)] - public FloatParameter ColorBoost = new FloatParameter(0.4f); - [Range(0.02f, 1f)] - public FloatParameter GlowWhitePoint = new FloatParameter(0.4f); - [Range(0.1f, 6f)] - public FloatParameter GlowRolloff = new FloatParameter(2.2f); - [Range(0.05f, 0.8f)] - public FloatParameter GlowStrength = new FloatParameter(0.45f); - [Range(0.02f, 2.6f)] - public FloatParameter MonitorGamma = new FloatParameter(2.2f); - - int m_gamma_ID = Shader.PropertyToID("_gamma"); - int m_horiz_gauss_width_ID = Shader.PropertyToID("_horiz_gauss_width"); - int m_BOOST_ID = Shader.PropertyToID("_BOOST"); - int m_GLOW_WHITEPOINT_ID = Shader.PropertyToID("_GLOW_WHITEPOINT"); - int m_GLOW_ROLLOFF_ID = Shader.PropertyToID("_GLOW_ROLLOFF"); - int m_BLOOM_STRENGTH_ID = Shader.PropertyToID("_BLOOM_STRENGTH"); - int m_OUTPUT_GAMMA_ID = Shader.PropertyToID("_OUTPUT_GAMMA"); - - - CommandBuffer m_multipPassCmd; - int m_wrapRT; - - protected override void OnInit(Material renderMat) + [Strip(RuntimePlatform.PSP2)] + public class RetroArchMattiasCRTGlow : FilterEffect { - m_multipPassCmd = new CommandBuffer(); - m_wrapRT = Shader.PropertyToID($"{Name}.WrapRT"); - } + public override string Name => nameof(RetroArchMattiasCRTGlow); + protected override string ShaderName => "Filter/RetroArch/MattiasCRTWithGlow"; - protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) - { - m_multipPassCmd.Clear(); + [Range(0.02f, 20f)] + public FloatParameter InputGamma = new FloatParameter(11); + [Range(0.02f, 1f)] + public FloatParameter GaussianWidth = new FloatParameter(0.4f); + [Range(0.02f, 1f)] + public FloatParameter ColorBoost = new FloatParameter(0.4f); + [Range(0.02f, 1f)] + public FloatParameter GlowWhitePoint = new FloatParameter(0.4f); + [Range(0.1f, 6f)] + public FloatParameter GlowRolloff = new FloatParameter(2.2f); + [Range(0.05f, 0.8f)] + public FloatParameter GlowStrength = new FloatParameter(0.45f); + [Range(0.02f, 2.6f)] + public FloatParameter MonitorGamma = new FloatParameter(2.2f); - m_multipPassCmd.GetTemporaryRT(m_wrapRT, result.width, result.height); + int m_gamma_ID = Shader.PropertyToID("_gamma"); + int m_horiz_gauss_width_ID = Shader.PropertyToID("_horiz_gauss_width"); + int m_BOOST_ID = Shader.PropertyToID("_BOOST"); + int m_GLOW_WHITEPOINT_ID = Shader.PropertyToID("_GLOW_WHITEPOINT"); + int m_GLOW_ROLLOFF_ID = Shader.PropertyToID("_GLOW_ROLLOFF"); + int m_BLOOM_STRENGTH_ID = Shader.PropertyToID("_BLOOM_STRENGTH"); + int m_OUTPUT_GAMMA_ID = Shader.PropertyToID("_OUTPUT_GAMMA"); - renderMat.SetFloat(m_gamma_ID, InputGamma.GetValue()); - renderMat.SetFloat(m_horiz_gauss_width_ID, GaussianWidth.GetValue()); - renderMat.SetFloat(m_BOOST_ID, ColorBoost.GetValue()); - renderMat.SetFloat(m_GLOW_WHITEPOINT_ID, GlowWhitePoint.GetValue()); - renderMat.SetFloat(m_GLOW_ROLLOFF_ID, GlowRolloff.GetValue()); - renderMat.SetFloat(m_BLOOM_STRENGTH_ID, GlowStrength.GetValue()); - renderMat.SetFloat(m_OUTPUT_GAMMA_ID, MonitorGamma.GetValue()); - m_multipPassCmd.Blit(src, result); - for (int i = 0; i < renderMat.shader.passCount; i++) + CommandBuffer m_multipPassCmd; + int m_wrapRT; + + protected override void OnInit(Material renderMat) { - m_multipPassCmd.Blit(result, m_wrapRT, renderMat, i); - m_multipPassCmd.Blit(m_wrapRT, result); + m_multipPassCmd = new CommandBuffer(); + m_wrapRT = Shader.PropertyToID($"{Name}.WrapRT"); } - m_multipPassCmd.ReleaseTemporaryRT(m_wrapRT); - Graphics.ExecuteCommandBuffer(m_multipPassCmd); + protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) + { + m_multipPassCmd.Clear(); + + m_multipPassCmd.GetTemporaryRT(m_wrapRT, result.width, result.height); + + renderMat.SetFloat(m_gamma_ID, InputGamma.GetValue()); + renderMat.SetFloat(m_horiz_gauss_width_ID, GaussianWidth.GetValue()); + renderMat.SetFloat(m_BOOST_ID, ColorBoost.GetValue()); + renderMat.SetFloat(m_GLOW_WHITEPOINT_ID, GlowWhitePoint.GetValue()); + renderMat.SetFloat(m_GLOW_ROLLOFF_ID, GlowRolloff.GetValue()); + renderMat.SetFloat(m_BLOOM_STRENGTH_ID, GlowStrength.GetValue()); + renderMat.SetFloat(m_OUTPUT_GAMMA_ID, MonitorGamma.GetValue()); + + m_multipPassCmd.Blit(src, result); + for (int i = 0; i < renderMat.shader.passCount; i++) + { + m_multipPassCmd.Blit(result, m_wrapRT, renderMat, i); + m_multipPassCmd.Blit(m_wrapRT, result); + } + + m_multipPassCmd.ReleaseTemporaryRT(m_wrapRT); + Graphics.ExecuteCommandBuffer(m_multipPassCmd); + } } -} +} diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/SimpleCRT/SimpleCRT.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/SimpleCRT/SimpleCRT.cs index 3d84b008..f8252554 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/SimpleCRT/SimpleCRT.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/SimpleCRT/SimpleCRT.cs @@ -1,172 +1,174 @@ using Assets.Script.AppMain.Filter; -using AxibugEmuOnline.Client; using System.ComponentModel; using UnityEngine; using Random = UnityEngine.Random; - -public class SimpleCRT : FilterEffect +namespace AxibugEmuOnline.Client.Filters { - public override string Name => nameof(SimpleCRT); - protected override string ShaderName => "Filter/yunoda-3DCG/SimpleCRT"; - - [Range(0, 1000)][Description("White Noise Freq")] public IntParameter whiteNoiseFrequency = new IntParameter(1); - [Range(0, 1)][Description("White Noise Time Left (sec)")] public FloatParameter whiteNoiseLength = new FloatParameter(0.1f); - private float whiteNoiseTimeLeft; - - [Range(0, 1000)][Description("Screen Jump Freq")] public IntParameter screenJumpFrequency = 1; - [Range(0, 1f)][Description("Screen Jump Length")] public FloatParameter screenJumpLength = 0.2f; - [Range(0, 1f)][Description("Jump Min")] public FloatParameter screenJumpMinLevel = 0.1f; - [Range(0, 1f)][Description("Jump Max")] public FloatParameter screenJumpMaxLevel = 0.9f; - private float screenJumpTimeLeft; - - [Range(0, 1f)][Description("Flickering Strength")] public FloatParameter flickeringStrength = 0.002f; - [Range(0, 333f)][Description("Flickering Cycle")] public FloatParameter flickeringCycle = 111f; - - [Description("Slip Page")] public BoolParameter isSlippage = true; - [Description("Slip Noise")] public BoolParameter isSlippageNoise = true; - [Range(0, 1)][Description("Slip Strength")] public FloatParameter slippageStrength = 0.005f; - [Range(0, 100)][Description("Slip Intervalw")] public float slippageInterval = 1f; - [Range(0, 330)][Description("Slip Scroll Speed")] public float slippageScrollSpeed = 33f; - [Range(0, 100f)][Description("Slip Size")] public FloatParameter slippageSize = 11f; - - [Range(0, 1f)][Description("Chromatic Aberration Strength")] public FloatParameter chromaticAberrationStrength = 0.005f; - [Description("Chromatic Aberration")] public bool isChromaticAberration = true; - - [Description("Multiple Ghost")] public BoolParameter isMultipleGhost = true; - [Range(0, 1f)][Description("Multiple Ghost Strength")] public FloatParameter multipleGhostStrength = 0.01f; - - [Description("Scanline")] public BoolParameter isScanline = true; - [Description("Monochrome")] public BoolParameter isMonochrome = false; - - [Description("Letter Box")] public bool isLetterBox = false; - public bool isLetterBoxEdgeBlur = false; - [Description("Letter Box Type")] public FilterParameter letterBoxType = default(LeterBoxType); - public enum LeterBoxType + public class SimpleCRT : FilterEffect { - Black, - Blur - } + public override string Name => nameof(SimpleCRT); - #region Properties in shader - private int _WhiteNoiseOnOff; - private int _ScanlineOnOff; - private int _MonochormeOnOff; - private int _ScreenJumpLevel; - private int _FlickeringStrength; - private int _FlickeringCycle; - private int _SlippageStrength; - private int _SlippageSize; - private int _SlippageInterval; - private int _SlippageScrollSpeed; - private int _SlippageNoiseOnOff; - private int _SlippageOnOff; - private int _ChromaticAberrationStrength; - private int _ChromaticAberrationOnOff; - private int _MultipleGhostOnOff; - private int _MultipleGhostStrength; - private int _LetterBoxOnOff; - private int _LetterBoxType; - private int _LetterBoxEdgeBlurOnOff; - private int _DecalTex; - private int _DecalTexOnOff; - private int _DecalTexPos; - private int _DecalTexScale; - private int _FilmDirtOnOff; - private int _FilmDirtTex; - #endregion + protected override string ShaderName => "Filter/yunoda-3DCG/SimpleCRT"; - protected override void OnInit(Material renderMat) - { - base.OnInit(renderMat); + [Range(0, 1000)][Description("White Noise Freq")] public IntParameter whiteNoiseFrequency = new IntParameter(1); + [Range(0, 1)][Description("White Noise Time Left (sec)")] public FloatParameter whiteNoiseLength = new FloatParameter(0.1f); + private float whiteNoiseTimeLeft; - _WhiteNoiseOnOff = Shader.PropertyToID("_WhiteNoiseOnOff"); - _ScanlineOnOff = Shader.PropertyToID("_ScanlineOnOff"); - _MonochormeOnOff = Shader.PropertyToID("_MonochormeOnOff"); - _ScreenJumpLevel = Shader.PropertyToID("_ScreenJumpLevel"); - _FlickeringStrength = Shader.PropertyToID("_FlickeringStrength"); - _FlickeringCycle = Shader.PropertyToID("_FlickeringCycle"); - _SlippageStrength = Shader.PropertyToID("_SlippageStrength"); - _SlippageSize = Shader.PropertyToID("_SlippageSize"); - _SlippageInterval = Shader.PropertyToID("_SlippageInterval"); - _SlippageScrollSpeed = Shader.PropertyToID("_SlippageScrollSpeed"); - _SlippageNoiseOnOff = Shader.PropertyToID("_SlippageNoiseOnOff"); - _SlippageOnOff = Shader.PropertyToID("_SlippageOnOff"); - _ChromaticAberrationStrength = Shader.PropertyToID("_ChromaticAberrationStrength"); - _ChromaticAberrationOnOff = Shader.PropertyToID("_ChromaticAberrationOnOff"); - _MultipleGhostOnOff = Shader.PropertyToID("_MultipleGhostOnOff"); - _MultipleGhostStrength = Shader.PropertyToID("_MultipleGhostStrength"); - _LetterBoxOnOff = Shader.PropertyToID("_LetterBoxOnOff"); - _LetterBoxType = Shader.PropertyToID("_LetterBoxType"); - _DecalTex = Shader.PropertyToID("_DecalTex"); - _DecalTexOnOff = Shader.PropertyToID("_DecalTexOnOff"); - _DecalTexPos = Shader.PropertyToID("_DecalTexPos"); - _DecalTexScale = Shader.PropertyToID("_DecalTexScale"); - _FilmDirtOnOff = Shader.PropertyToID("_FilmDirtOnOff"); - _FilmDirtTex = Shader.PropertyToID("_FilmDirtTex"); - } + [Range(0, 1000)][Description("Screen Jump Freq")] public IntParameter screenJumpFrequency = 1; + [Range(0, 1f)][Description("Screen Jump Length")] public FloatParameter screenJumpLength = 0.2f; + [Range(0, 1f)][Description("Jump Min")] public FloatParameter screenJumpMinLevel = 0.1f; + [Range(0, 1f)][Description("Jump Max")] public FloatParameter screenJumpMaxLevel = 0.9f; + private float screenJumpTimeLeft; - protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) - { - SetShaderParameter(renderMat); + [Range(0, 1f)][Description("Flickering Strength")] public FloatParameter flickeringStrength = 0.002f; + [Range(0, 333f)][Description("Flickering Cycle")] public FloatParameter flickeringCycle = 111f; - Graphics.Blit(src, result, renderMat); - } + [Description("Slip Page")] public BoolParameter isSlippage = true; + [Description("Slip Noise")] public BoolParameter isSlippageNoise = true; + [Range(0, 1)][Description("Slip Strength")] public FloatParameter slippageStrength = 0.005f; + [Range(0, 100)][Description("Slip Intervalw")] public float slippageInterval = 1f; + [Range(0, 330)][Description("Slip Scroll Speed")] public float slippageScrollSpeed = 33f; + [Range(0, 100f)][Description("Slip Size")] public FloatParameter slippageSize = 11f; - private void SetShaderParameter(Material material) - { - ///////White noise - whiteNoiseTimeLeft -= 0.01f; - if (whiteNoiseTimeLeft <= 0) + [Range(0, 1f)][Description("Chromatic Aberration Strength")] public FloatParameter chromaticAberrationStrength = 0.005f; + [Description("Chromatic Aberration")] public bool isChromaticAberration = true; + + [Description("Multiple Ghost")] public BoolParameter isMultipleGhost = true; + [Range(0, 1f)][Description("Multiple Ghost Strength")] public FloatParameter multipleGhostStrength = 0.01f; + + [Description("Scanline")] public BoolParameter isScanline = true; + [Description("Monochrome")] public BoolParameter isMonochrome = false; + + [Description("Letter Box")] public bool isLetterBox = false; + public bool isLetterBoxEdgeBlur = false; + [Description("Letter Box Type")] public FilterParameter letterBoxType = default(LeterBoxType); + public enum LeterBoxType { - if (Random.Range(0, 1000) < whiteNoiseFrequency) - { - material.SetInteger(_WhiteNoiseOnOff, 1); - whiteNoiseTimeLeft = whiteNoiseLength; - } - else - { - material.SetInteger(_WhiteNoiseOnOff, 0); - } + Black, + Blur } - ////// - material.SetInteger(_LetterBoxOnOff, isLetterBox ? 0 : 1); - //material.SetInteger(_LetterBoxEdgeBlurOnOff, isLetterBoxEdgeBlur ? 0 : 1); - material.SetInteger(_LetterBoxType, (int)letterBoxType.GetValue()); + #region Properties in shader + private int _WhiteNoiseOnOff; + private int _ScanlineOnOff; + private int _MonochormeOnOff; + private int _ScreenJumpLevel; + private int _FlickeringStrength; + private int _FlickeringCycle; + private int _SlippageStrength; + private int _SlippageSize; + private int _SlippageInterval; + private int _SlippageScrollSpeed; + private int _SlippageNoiseOnOff; + private int _SlippageOnOff; + private int _ChromaticAberrationStrength; + private int _ChromaticAberrationOnOff; + private int _MultipleGhostOnOff; + private int _MultipleGhostStrength; + private int _LetterBoxOnOff; + private int _LetterBoxType; + private int _LetterBoxEdgeBlurOnOff; + private int _DecalTex; + private int _DecalTexOnOff; + private int _DecalTexPos; + private int _DecalTexScale; + private int _FilmDirtOnOff; + private int _FilmDirtTex; + #endregion - material.SetInteger(_ScanlineOnOff, isScanline ? 1 : 0); - material.SetInteger(_MonochormeOnOff, isMonochrome ? 1 : 0); - material.SetFloat(_FlickeringStrength, flickeringStrength); - material.SetFloat(_FlickeringCycle, flickeringCycle); - material.SetFloat(_ChromaticAberrationStrength, chromaticAberrationStrength); - material.SetInteger(_ChromaticAberrationOnOff, isChromaticAberration ? 1 : 0); - material.SetInteger(_MultipleGhostOnOff, isMultipleGhost ? 1 : 0); - material.SetFloat(_MultipleGhostStrength, multipleGhostStrength); - - //////Slippage - material.SetInteger(_SlippageOnOff, isSlippage ? 1 : 0); - material.SetFloat(_SlippageInterval, slippageInterval); - material.SetFloat(_SlippageNoiseOnOff, isSlippageNoise ? Random.Range(0, 1f) : 1); - material.SetFloat(_SlippageScrollSpeed, slippageScrollSpeed); - material.SetFloat(_SlippageStrength, slippageStrength); - material.SetFloat(_SlippageSize, slippageSize); - ////// - - //////Screen Jump Noise - screenJumpTimeLeft -= 0.01f; - if (screenJumpTimeLeft <= 0) + protected override void OnInit(Material renderMat) { - if (Random.Range(0, 1000) < screenJumpFrequency) + base.OnInit(renderMat); + + _WhiteNoiseOnOff = Shader.PropertyToID("_WhiteNoiseOnOff"); + _ScanlineOnOff = Shader.PropertyToID("_ScanlineOnOff"); + _MonochormeOnOff = Shader.PropertyToID("_MonochormeOnOff"); + _ScreenJumpLevel = Shader.PropertyToID("_ScreenJumpLevel"); + _FlickeringStrength = Shader.PropertyToID("_FlickeringStrength"); + _FlickeringCycle = Shader.PropertyToID("_FlickeringCycle"); + _SlippageStrength = Shader.PropertyToID("_SlippageStrength"); + _SlippageSize = Shader.PropertyToID("_SlippageSize"); + _SlippageInterval = Shader.PropertyToID("_SlippageInterval"); + _SlippageScrollSpeed = Shader.PropertyToID("_SlippageScrollSpeed"); + _SlippageNoiseOnOff = Shader.PropertyToID("_SlippageNoiseOnOff"); + _SlippageOnOff = Shader.PropertyToID("_SlippageOnOff"); + _ChromaticAberrationStrength = Shader.PropertyToID("_ChromaticAberrationStrength"); + _ChromaticAberrationOnOff = Shader.PropertyToID("_ChromaticAberrationOnOff"); + _MultipleGhostOnOff = Shader.PropertyToID("_MultipleGhostOnOff"); + _MultipleGhostStrength = Shader.PropertyToID("_MultipleGhostStrength"); + _LetterBoxOnOff = Shader.PropertyToID("_LetterBoxOnOff"); + _LetterBoxType = Shader.PropertyToID("_LetterBoxType"); + _DecalTex = Shader.PropertyToID("_DecalTex"); + _DecalTexOnOff = Shader.PropertyToID("_DecalTexOnOff"); + _DecalTexPos = Shader.PropertyToID("_DecalTexPos"); + _DecalTexScale = Shader.PropertyToID("_DecalTexScale"); + _FilmDirtOnOff = Shader.PropertyToID("_FilmDirtOnOff"); + _FilmDirtTex = Shader.PropertyToID("_FilmDirtTex"); + } + + protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) + { + SetShaderParameter(renderMat); + + Graphics.Blit(src, result, renderMat); + } + + private void SetShaderParameter(Material material) + { + ///////White noise + whiteNoiseTimeLeft -= 0.01f; + if (whiteNoiseTimeLeft <= 0) { - var level = Random.Range(screenJumpMinLevel, screenJumpMaxLevel); - material.SetFloat(_ScreenJumpLevel, level); - screenJumpTimeLeft = screenJumpLength; + if (Random.Range(0, 1000) < whiteNoiseFrequency) + { + material.SetInteger(_WhiteNoiseOnOff, 1); + whiteNoiseTimeLeft = whiteNoiseLength; + } + else + { + material.SetInteger(_WhiteNoiseOnOff, 0); + } } - else + ////// + + material.SetInteger(_LetterBoxOnOff, isLetterBox ? 0 : 1); + //material.SetInteger(_LetterBoxEdgeBlurOnOff, isLetterBoxEdgeBlur ? 0 : 1); + material.SetInteger(_LetterBoxType, (int)letterBoxType.GetValue()); + + material.SetInteger(_ScanlineOnOff, isScanline ? 1 : 0); + material.SetInteger(_MonochormeOnOff, isMonochrome ? 1 : 0); + material.SetFloat(_FlickeringStrength, flickeringStrength); + material.SetFloat(_FlickeringCycle, flickeringCycle); + material.SetFloat(_ChromaticAberrationStrength, chromaticAberrationStrength); + material.SetInteger(_ChromaticAberrationOnOff, isChromaticAberration ? 1 : 0); + material.SetInteger(_MultipleGhostOnOff, isMultipleGhost ? 1 : 0); + material.SetFloat(_MultipleGhostStrength, multipleGhostStrength); + + //////Slippage + material.SetInteger(_SlippageOnOff, isSlippage ? 1 : 0); + material.SetFloat(_SlippageInterval, slippageInterval); + material.SetFloat(_SlippageNoiseOnOff, isSlippageNoise ? Random.Range(0, 1f) : 1); + material.SetFloat(_SlippageScrollSpeed, slippageScrollSpeed); + material.SetFloat(_SlippageStrength, slippageStrength); + material.SetFloat(_SlippageSize, slippageSize); + ////// + + //////Screen Jump Noise + screenJumpTimeLeft -= 0.01f; + if (screenJumpTimeLeft <= 0) { - material.SetFloat(_ScreenJumpLevel, 0); + if (Random.Range(0, 1000) < screenJumpFrequency) + { + var level = Random.Range(screenJumpMinLevel, screenJumpMaxLevel); + material.SetFloat(_ScreenJumpLevel, level); + screenJumpTimeLeft = screenJumpLength; + } + else + { + material.SetFloat(_ScreenJumpLevel, 0); + } } } } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT.meta b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT.meta new file mode 100644 index 00000000..2f6440a1 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 37f669e0d7f0e9a4f8b2af15b61cb06c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders.meta b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders.meta new file mode 100644 index 00000000..bff7cfb1 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f6017d76f5000d0469311092e8f58b74 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTBlur.cg.shader b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTBlur.cg.shader new file mode 100644 index 00000000..c02cf777 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTBlur.cg.shader @@ -0,0 +1,71 @@ +// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' + +Shader "CRT/Blur" { + Properties { + _MainTex ("Texture Image", 2D) = "white" {} + } + SubShader { + // No culling or depth + Cull Off ZWrite Off ZTest Always + + Pass { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + + struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + }; + + sampler2D _MainTex; + float4 _MainTex_TexelSize; + float pixelSizeX; + float pixelSizeY; + float blurSigma; // in pixels + float4 blurKernel; + half blurZ; + + v2f vert(appdata_img v) { + v2f o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord; + + #if UNITY_UV_STARTS_AT_TOP + if (_MainTex_TexelSize.y < 0) + o.uv.y = 1.0 - o.uv.y; + #endif + + return o; + } + + half4 blur(half2 uv, half sigma) { + half3 final = half3(0.0, 0.0, 0.0); + + float cornerWeight = blurKernel.x * blurKernel.x; + float edgeWeight = blurKernel.x * blurKernel.y; + float centerWeight = blurKernel.y * blurKernel.y; + + final += tex2D(_MainTex, uv + float2(-pixelSizeX, -pixelSizeY)).rgb * cornerWeight; + final += tex2D(_MainTex, uv + float2(0, -pixelSizeY)).rgb * edgeWeight; + final += tex2D(_MainTex, uv + float2(pixelSizeX, -pixelSizeY)).rgb * cornerWeight; + + final += tex2D(_MainTex, uv + float2(-pixelSizeX, 0)).rgb * edgeWeight; + final += tex2D(_MainTex, uv + float2(0, 0)).rgb * centerWeight; + final += tex2D(_MainTex, uv + float2(pixelSizeX, 0)).rgb * edgeWeight; + + final += tex2D(_MainTex, uv + float2(-pixelSizeX, pixelSizeY)).rgb * cornerWeight; + final += tex2D(_MainTex, uv + float2(0, pixelSizeY)).rgb * edgeWeight; + final += tex2D(_MainTex, uv + float2(pixelSizeX, pixelSizeY)).rgb * cornerWeight; + + return half4(final / half3(blurZ, blurZ, blurZ), 1.0); + } + + half4 frag(v2f i) : SV_Target { + return blur(i.uv, blurSigma); + } + ENDCG + } + } +} \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTBlur.cg.shader.meta b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTBlur.cg.shader.meta new file mode 100644 index 00000000..aafc50a3 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTBlur.cg.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: e36189d8343a744ff946d70df1adb684 +timeCreated: 1483471380 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTFinalPostprocess.cg.shader b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTFinalPostprocess.cg.shader new file mode 100644 index 00000000..144720f0 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTFinalPostprocess.cg.shader @@ -0,0 +1,192 @@ +// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' + +Shader "CRT/FinalPostprocess" { + Properties { + _MainTex ("Texture", 2D) = "white" {} + } + SubShader { + // No culling or depth + Cull Off ZWrite Off ZTest Always + + Pass { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + + struct v2f { + float4 pos : SV_POSITION; + float2 uv : TEXCOORD0; + }; + + sampler2D _MainTex; + float4 _MainTex_TexelSize; + float pixelSizeX; + float pixelSizeY; + + int maskMode; + float maskStr; // 0.0 - 1.0 + float vignetteStr; // 0.0 - 1.0 + float vignetteSize; // 0.0 - 1. + float crtBendX; + float crtBendY; + float crtOverscan; // 0.0 - 1.0 + int flipV; + + v2f vert(appdata_img v) { + v2f o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uv = v.texcoord; + + #if UNITY_UV_STARTS_AT_TOP + if (flipV) + o.uv.y = 1.0 - o.uv.y; + #endif + + return o; + } + + half4 alphaBlend(half4 top, half4 bottom) { + half4 result; + result.a = top.a + bottom.a * (1.0 - top.a); + result.rgb = (top.rgb * top.aaa + bottom.rgb * bottom.aaa * (half3(1.0, 1.0, 1.0) - top.aaa)) / result.aaa; + + return result; + } + + half3 vignette(float2 uv) { + half outer = 1.0; + half inner = vignetteSize; + half2 center = half2(0.5, 0.5); // Center of Screen + + float dist = distance(center, uv) * 1.414213; // multiplyed by 1.414213 to fit in the range of 0.0 to 1.0 + float vig = clamp((outer - dist) / (outer - inner), 0.0, 1.0); + + return half3(vig, vig, vig); + } + + float2 crt(float2 coord, float bendX, float bendY) { + // to symmetrical coords + coord = (coord - 0.5) * 2.0 / (crtOverscan + 1.0); + + // overscane a bit by default + coord *= 1.1; + + // bend + coord.x *= 1.0 + pow((abs(coord.y) / bendX), 3.0); + coord.y *= 1.0 + pow((abs(coord.x) / bendY), 3.0); + + // transform back to 0.0 - 1.0 + coord = (coord / 2.0) + 0.5; + + return coord; + } + + half4 frag(v2f i) : SV_Target { + //return tex2D(_MainTex, i.uv); + + float2 crtCoords = crt(i.uv, crtBendX, crtBendY); + + if(crtCoords.x < 0.0 || crtCoords.x > 1.0 || crtCoords.y < 0.0 || crtCoords.y > 1.0) { + return half4(0.0, 0.0, 0.0, 1.0); + //discard; + } + else { + half4 zero = half4(0.0, 0.0, 0.0, 0.0); + half4 one = half4(1.0, 1.0, 1.0, 1.0); + + half4 final = tex2D(_MainTex, crtCoords); + + // 9. mix mask with final + half3 tmp; + + if(maskMode == 0) { + float moduloX = floor(fmod(i.uv.x / pixelSizeX, 6.0)); + float moduloY = floor(fmod(i.uv.y / pixelSizeY, 4.0)); + + if(moduloX < 3.0) { + if(moduloY < 3.0) + tmp.rgb = one.rgb; + else + tmp.rgb = zero.rgb; + } + else { + if(moduloY == 1.0) + tmp.rgb = zero.rgb; + else + tmp.rgb = one.rgb; + } + } + else if(maskMode == 1) { + float moduloX = floor(fmod(i.uv.x / pixelSizeX, 6.0)); + float moduloY = floor(fmod(i.uv.y / pixelSizeY, 6.0)); + + if(moduloX < 3.0) { + if(moduloY == 0.0 || moduloY == 5.0) + tmp.rgb = zero.rgb; + else + tmp.rgb = one.rgb; + } + else { + if(moduloY == 2.0 || moduloY == 3.0) + tmp.rgb = zero.rgb; + else + tmp.rgb = one.rgb; + } + } + else if(maskMode == 2) { + float moduloX = floor(fmod(i.uv.x / pixelSizeX, 6.0)); + float moduloY = floor(fmod(i.uv.y / pixelSizeY, 5.0)); + + if(moduloX < 3.0) { + if(moduloY < 3.0) + tmp.rgb = one.rgb; + else + tmp.rgb = zero.rgb; + } + else { + if(moduloY < 2.0) + tmp.rgb = zero.rgb; + else + tmp.rgb = one.rgb; + } + } + else if(maskMode == 3) { + float moduloY = floor(fmod(i.uv.y / pixelSizeY, 4.0)); + + if(moduloY < 1.0) + tmp.rgb = zero.rgb; + else + tmp.rgb = one.rgb; + } + else if(maskMode == 4) { + float moduloY = floor(fmod(i.uv.y / pixelSizeY, 4.0)); + + if(moduloY < 2.0) + tmp.rgb = zero.rgb; + else + tmp.rgb = one.rgb; + } + else if(maskMode == 5) { + float moduloY = floor(fmod(i.uv.y / pixelSizeY, 5.0)); + + if(moduloY < 2.0) + tmp.rgb = one.rgb; + else + tmp.rgb = zero.rgb; + } + + tmp = final.rgb * tmp; + final.rgb = alphaBlend(half4(tmp, maskStr), final).rgb; + + // 10. vignette + tmp = final.rgb * vignette(crtCoords); + final.rgb = alphaBlend(half4(tmp, vignetteStr), final).rgb; + + return final; + } + } + ENDCG + } + } +} \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTFinalPostprocess.cg.shader.meta b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTFinalPostprocess.cg.shader.meta new file mode 100644 index 00000000..4bfe1897 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTFinalPostprocess.cg.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 1fed85d45421d45a6ac770579285b756 +timeCreated: 1483529480 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTPostprocess.cg.shader b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTPostprocess.cg.shader new file mode 100644 index 00000000..53c74731 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTPostprocess.cg.shader @@ -0,0 +1,220 @@ +// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' + +Shader "CRT/Postprocess" { + Properties { + _MainTex ("Texture", 2D) = "white" {} + _BlurTex ("Texture", 2D) = "white" {} + } + SubShader { + // No culling or depth + Cull Off ZWrite Off ZTest Always + + Pass { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + #include "UnityCG.cginc" + + struct v2f { + float4 pos : SV_POSITION; + float2 uvBase : TEXCOORD0; + float2 uvBlur : TEXCOORD1; + }; + + sampler2D _MainTex; + float4 _MainTex_TexelSize; + sampler2D _BlurTex; + float4 _BlurTex_TexelSize; + float pixelSizeX; + float pixelSizeY; + float seconds; + + float bleedDist; // in pixels + float bleedStr; // 0.0 - 1.0 + float blurStr; // 0.0 - 1.0 + float rgbMaskSub; + float rgbMaskSep; + float rgbMaskStr; // 0.0 - 1.0 + int colorNoiseMode; + float colorNoiseStr; // 0.0 - 1.0 + int monoNoiseMode; + float monoNoiseScale; // 0.0 - 1.0 + float monoNoiseStr; // 0.0 - 1.0 + + float4x4 colorMat; + + half3 minLevels; + half3 maxLevels; + half3 blackPoint; + half3 whitePoint; + + float interWidth; // in pixels + float interSpeed; // in px per second + float interStr; // 0.0 - 1.0 + float interSplit; + + float aberStr; // in pixels + + half4 alphaBlend(half4 top, half4 bottom) { + half4 result; + result.a = top.a + bottom.a * (1.0 - top.a); + result.rgb = (top.rgb * top.aaa + bottom.rgb * bottom.aaa * (half3(1.0, 1.0, 1.0) - top.aaa)) / result.aaa; + + return result; + } + + half4 blur(float2 uv) { + if(aberStr == 0.0) { + return tex2D(_BlurTex, uv); + } + else { + return half4( + tex2D(_BlurTex, uv + half2(-pixelSizeX * aberStr, 0.0)).r, + tex2D(_BlurTex, uv).g, + tex2D(_BlurTex, uv + half2(pixelSizeX * aberStr, 0.0)).b, + 1.0 + ); + } + } + + half4 bleed(float2 uv) { + half4 a = blur(uv + half2(0.0, bleedDist * pixelSizeY)); + half4 b = blur(uv + half2(0.0, -bleedDist * pixelSizeY)); + half4 c = blur(uv + half2(bleedDist * pixelSizeX, 0.0)); + half4 d = blur(uv + half2(-bleedDist * pixelSizeX, 0.0)); + + return max(max(a, b), max(c, d)); + } + + half noise(float n) { + return frac(cos(n * 89.42) * 343.42); + } + + half3 interference(float2 coord, half3 screen) { + screen.r += sin((interSplit * pixelSizeY + coord.y / (interWidth * pixelSizeY) + (seconds * interSpeed))) * interStr; + screen.g += sin((coord.y / (interWidth * pixelSizeY) + (seconds * interSpeed))) * interStr; + screen.b += sin((-interSplit + coord.y / (interWidth * pixelSizeY) + (seconds * interSpeed))) * interStr; + + screen = clamp(screen, half3(0.0, 0.0, 0.0), half3(1.0, 1.0, 1.0)); + + return screen; + } + + v2f vert(appdata_img v) { + v2f o; + o.pos = UnityObjectToClipPos(v.vertex); + o.uvBase = v.texcoord; + o.uvBlur = v.texcoord; + + #if UNITY_UV_STARTS_AT_TOP + //if (_MainTex_TexelSize.y < 0) + // o.uvBase.y = 1.0 - o.uvBase.y; + + //if (_MainTex_TexelSize.y < 0) + // o.uvBlur.y = 1.0 - o.uvBlur.y; + #endif + + return o; + } + + half4 frag(v2f i) : SV_Target { + //return tex2D(_BlurTex, i.uv); + + half4 zero = half4(0.0, 0.0, 0.0, 0.0); + half4 one = half4(1.0, 1.0, 1.0, 1.0); + + half4 base = tex2D(_MainTex, i.uvBase); + half4 blured = blur(i.uvBlur); + half4 bleeded = bleed(i.uvBlur); + half4 final; + + final.a = 1.0; + half3 tmp; + + // 1. mix tmp with blured in lighten mode + tmp = max(base.rgb, blured.rgb); + final.rgb = alphaBlend(half4(tmp, blurStr), blured).rgb; + + // 2. mix bleeded with base in lighten mode + tmp = max(bleeded.rgb, final.rgb); + final.rgb = alphaBlend(half4(tmp, bleedStr), final).rgb; + + float delta = fmod(seconds, 60.0); + + // 3. add color noise + half3 colorNoise = half3( + noise(sin(i.uvBase.x / pixelSizeX) * i.uvBase.y / pixelSizeY + delta), + noise(sin(i.uvBase.y / pixelSizeY) * i.uvBase.x / pixelSizeX + delta), + noise(sin(i.uvBase.x / pixelSizeX) * sin(i.uvBase.y / pixelSizeY) + delta) + ); + + if(colorNoiseMode == 0) + tmp = final.rgb + colorNoise; + else if(colorNoiseMode == 1) + tmp = final.rgb - colorNoise; + else if(colorNoiseMode == 2) + tmp = final.rgb * colorNoise; + else if(colorNoiseMode == 3) + tmp = final.rgb / colorNoise; + else if(colorNoiseMode == 4) + tmp = max(colorNoise, final.rgb); + else if(colorNoiseMode == 5) + tmp = min(colorNoise, final.rgb); + + tmp = clamp(tmp, zero.rgb, one.rgb); + final.rgb = alphaBlend(half4(tmp, colorNoiseStr), final).rgb; + + // 4. add monochromatic noise + float monoNoiseVal = noise(sin(i.uvBase.x / pixelSizeX) * i.uvBase.y / pixelSizeY + delta); + half3 monoNoise = half3(monoNoiseVal, monoNoiseVal, monoNoiseVal); + + if(monoNoiseMode == 0) + tmp = final.rgb + monoNoise; + else if(monoNoiseMode == 1) + tmp = final.rgb - monoNoise; + else if(monoNoiseMode == 2) + tmp = final.rgb * monoNoise; + else if(monoNoiseMode == 3) + tmp = final.rgb / monoNoise; + else if(monoNoiseMode == 4) + tmp = max(monoNoise, final.rgb); + else if(monoNoiseMode == 5) + tmp = min(monoNoise, final.rgb); + + tmp = clamp(tmp, zero.rgb, one.rgb); + final.rgb = alphaBlend(half4(tmp, monoNoiseStr), final).rgb; + + // 5. mix rgb mask with final + float modulo = floor(fmod(i.uvBase.x / pixelSizeX, 3.0)); + tmp = final.rgb; + + if(modulo == 0.0) + tmp -= half3(0, rgbMaskSub * rgbMaskSep, rgbMaskSub * rgbMaskSep * 2.0); + else if(modulo == 1.0) + tmp -= half3(rgbMaskSub * rgbMaskSep, 0, rgbMaskSub * rgbMaskSep); + else + tmp -= half3(rgbMaskSub * rgbMaskSep * 2.0, rgbMaskSub * rgbMaskSep, 0); + + final.rgb = alphaBlend(half4(tmp, rgbMaskStr), final).rgb; + + // 6. interference + final.rgb = interference(i.uvBase, final.rgb); + + // 7. color adjustment + final = mul(colorMat, final); + + // 8. levels adjustment + final.rgb = lerp( + zero.rgb, + one.rgb, + final.rgb / (maxLevels - minLevels) + minLevels); + + final.rgb = clamp(final.rgb, blackPoint, whitePoint); + + return final; + + } + ENDCG + } + } +} \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTPostprocess.cg.shader.meta b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTPostprocess.cg.shader.meta new file mode 100644 index 00000000..dcda1b8e --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/Shaders/CRTPostprocess.cg.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: d96e49db3173e49a4a0fcf6125cc7f4e +timeCreated: 1483527217 +licenseType: Store +ShaderImporter: + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/UltimateCRT.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/UltimateCRT.cs new file mode 100644 index 00000000..15a3f506 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/UltimateCRT.cs @@ -0,0 +1,663 @@ +using Assets.Script.AppMain.Filter; +using System.Drawing.Imaging; +using UnityEngine; +using static Coffee.UIExtensions.UIEffect; + +namespace AxibugEmuOnline.Client.Filters +{ + [Strip(RuntimePlatform.PSP2)] + public class UltimateCRT : FilterEffect + { + public override string Name => nameof(UltimateCRT); + + protected override string ShaderName => null; + + float blurSize = 0.7f; + float blurStrength = 0.6f; + float bleedingSize = 0.75f; + float bleedingStrength = 0.5f; + float chromaticAberrationOffset = 1.25f; + float RGBMaskIntensivity = 0.6f; + float RGBMaskStrength = 0.6f; + float RGBMaskBleeding = 0.1f; + NoiseMode colorNoiseMode = NoiseMode.Add; + float colorNoiseStrength = 0.15f; + NoiseMode whiteNoiseMode = NoiseMode.Lighten; + float whiteNoiseStrength = 0.25f; + Color darkestLevel = Color.black; + Color brightestLevel = Color.Lerp(Color.black, Color.white, 235.0f / 255.0f); + Color darkestColor = Color.Lerp(Color.black, Color.white, 40.0f / 255.0f); + Color brightestColor = Color.white; + float brightness = 0.2f; + float contrast = 0.1f; + float saturation = -0.05f; + float interferenceWidth = 25.0f; + float interferenceSpeed = 3.0f; + float interferenceStrength = 0.0f; + float interferenceSplit = 0.25f; + MaskMode maskMode = MaskMode.Dense; + float maskStrength = 0.35f; // 0.0 - 1.0 + float curvatureX = 0.6f; // uniform float crtBend; + float curvatureY = 0.6f; // uniform float crtBend; + float overscan = 0.0f; // uniform float crtOverscan; // 0.0 - 1.0 + float vignetteSize = 0.35f; + float vignetteStrength = 0.1f; + TextureScalingMode textureScaling = TextureScalingMode.AdjustForHeight; + TextureScalingPolicy scalingPolicy = TextureScalingPolicy.DownscaleOnly; + int textureSize = 768; + + protected float seconds = 0.0f; + + protected float blurSigma = float.NaN; + protected float[] blurKernel = new float[2]; + protected float blurZ = float.NaN; + + protected float currentBrightness = float.NaN; + protected Matrix4x4 brightnessMat = new Matrix4x4(); + + protected float currentContrast = float.NaN; + protected Matrix4x4 contrastMat = new Matrix4x4(); + + protected float currentSaturation = float.NaN; + protected Matrix4x4 saturationMat = new Matrix4x4(); + + protected Matrix4x4 colorMat = new Matrix4x4(); + protected Vector4 colorTransform; + + Material blurMaterial; + Material postProMaterial; + Material finalPostProMaterial; + + public FilterParameter style = Preset.Default; + + + Preset m_lastStyle; + protected override void OnInit(Material renderMat) + { + blurMaterial = new Material(Shader.Find("CRT/Blur")); + postProMaterial = new Material(Shader.Find("CRT/Postprocess")); + finalPostProMaterial = new Material(Shader.Find("CRT/FinalPostprocess")); + + UpdatePreset(); + m_lastStyle = style.GetValue(); + } + + void UpdatePreset() + { + switch (style.GetValue()) + { + case Preset.Default: + SetupDefaultPreset(this); + break; + + case Preset.KitchenTV: + SetupKitchenTVPreset(this); + break; + + case Preset.MiniCRT: + SetupMiniCRTPreset(this); + break; + + case Preset.ColorTV: + SetupColorTVPreset(this); + break; + + case Preset.OldTV: + SetupOldTVPreset(this); + break; + + case Preset.HighEndMonitor: + SetupHighEndMonitorPreset(this); + break; + + case Preset.ArcadeDisplay: + SetupArcadeDisplayPreset(this); + break; + + case Preset.BrokenBlackAndWhite: + SetupBrokenBlackAndWhitePreset(this); + break; + + case Preset.GreenTerminal: + SetupGreenTerminalPreset(this); + break; + + case Preset.YellowMonitor: + SetupYellowMonitorPreset(this); + break; + } + } + + protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) + { + seconds += Time.deltaTime; + if (m_lastStyle != style.GetValue()) + { + m_lastStyle = style.GetValue(); + UpdatePreset(); + } + + var tempBlurTex = RenderTexture.GetTemporary(src.width, src.height, 0); + var tempPostProTex = RenderTexture.GetTemporary(src.width, src.height, 0); + + var realBlurSize = Mathf.Lerp(0.00001f, 1.99999f, blurSize); + + UpdateBlurKernel(realBlurSize); + + var realBrightness = Mathf.Lerp(0.8f, 1.2f, (brightness + 1.0f) / 2.0f); + var realContrast = Mathf.Lerp(0.5f, 1.5f, (contrast + 1.0f) / 2.0f); + var realSaturation = Mathf.Lerp(0.0f, 2.0f, (saturation + 1.0f) / 2.0f); + + UpdateColorMatrices(realBrightness - 1.5f, realContrast, realSaturation); + + blurMaterial.SetFloat("pixelSizeX", (float)(1.0 / src.width)); + blurMaterial.SetFloat("pixelSizeY", (float)(1.0 / src.height)); + blurMaterial.SetFloat("blurSigma", realBlurSize); + blurMaterial.SetVector("blurKernel", new Vector4(blurKernel[0], blurKernel[1])); + blurMaterial.SetFloat("blurZ", blurZ); + + postProMaterial.SetTexture("_BlurTex", tempBlurTex); + postProMaterial.SetFloat("pixelSizeX", (float)(1.0 / src.width)); + postProMaterial.SetFloat("pixelSizeY", (float)(1.0 / src.height)); + postProMaterial.SetFloat("seconds", seconds); + postProMaterial.SetFloat("blurStr", 1.0f - blurStrength); + postProMaterial.SetFloat("bleedDist", bleedingSize); + postProMaterial.SetFloat("bleedStr", bleedingStrength); + postProMaterial.SetFloat("rgbMaskStr", Mathf.Lerp(0.0f, 0.3f, RGBMaskStrength)); + postProMaterial.SetFloat("rgbMaskSub", RGBMaskIntensivity); + postProMaterial.SetFloat("rgbMaskSep", 1.0f - RGBMaskBleeding); + postProMaterial.SetFloat("colorNoiseStr", Mathf.Lerp(0.0f, 0.4f, colorNoiseStrength)); + postProMaterial.SetInt("colorNoiseMode", (int)colorNoiseMode); + postProMaterial.SetFloat("monoNoiseStr", Mathf.Lerp(0.0f, 0.4f, whiteNoiseStrength)); + postProMaterial.SetInt("monoNoiseMode", (int)whiteNoiseMode); + postProMaterial.SetMatrix("colorMat", colorMat); + postProMaterial.SetColor("minLevels", darkestLevel); + postProMaterial.SetColor("maxLevels", brightestLevel); + postProMaterial.SetColor("blackPoint", darkestColor); + postProMaterial.SetColor("whitePoint", brightestColor); + postProMaterial.SetFloat("interWidth", interferenceWidth); + postProMaterial.SetFloat("interSpeed", interferenceSpeed); + postProMaterial.SetFloat("interStr", interferenceStrength); + postProMaterial.SetFloat("interSplit", interferenceSplit); + postProMaterial.SetFloat("aberStr", -chromaticAberrationOffset); + + var realCurvatureX = Mathf.Lerp(0.25f, 0.45f, curvatureX); + var realCurvatureY = Mathf.Lerp(0.25f, 0.45f, curvatureY); + + finalPostProMaterial.SetFloat("pixelSizeX", (float)(1.0 / src.width)); + finalPostProMaterial.SetFloat("pixelSizeY", (float)(1.0 / src.height)); + finalPostProMaterial.SetFloat("vignetteStr", vignetteStrength); + finalPostProMaterial.SetFloat("vignetteSize", 1.0f - vignetteSize); + finalPostProMaterial.SetFloat("maskStr", maskStrength / 10.0f); + finalPostProMaterial.SetInt("maskMode", (int)maskMode); + finalPostProMaterial.SetFloat("crtBendX", Mathf.Lerp(1.0f, 100.0f, (1.0f - realCurvatureX) / Mathf.Exp(10.0f * realCurvatureX))); + finalPostProMaterial.SetFloat("crtBendY", Mathf.Lerp(1.0f, 100.0f, (1.0f - realCurvatureY) / Mathf.Exp(10.0f * realCurvatureY))); + finalPostProMaterial.SetFloat("crtOverscan", Mathf.Lerp(0.1f, 0.25f, overscan)); + finalPostProMaterial.SetInt("flipV", 0); + + Graphics.Blit(src, tempBlurTex, blurMaterial); + Graphics.Blit(src, tempPostProTex, postProMaterial); + + Graphics.Blit(tempPostProTex, result, finalPostProMaterial); + + tempBlurTex.DiscardContents(); + tempPostProTex.DiscardContents(); + + RenderTexture.ReleaseTemporary(tempBlurTex); + RenderTexture.ReleaseTemporary(tempPostProTex); + } + protected void UpdateBlurKernel(float sigma) + { + if (sigma == blurSigma) + return; + + blurSigma = sigma; + const int kSize = 1; + + blurZ = 0.0f; + for (int j = 0; j <= kSize; ++j) + { + var normal = CalculateBlurWeight(j, sigma); + blurKernel[kSize - j] = normal; + + if (j > 0) + blurZ += 2 * normal; + else + blurZ += normal; + } + + blurZ *= blurZ; + } + + protected float CalculateBlurWeight(float x, float sigma) + { + return 0.39894f * Mathf.Exp(-0.5f * x * x / (sigma * sigma)) / sigma; + } + + protected void UpdateColorMatrices(float b, float c, float s) + { + var rebuildColorMat = false; + + if (b != currentBrightness) + { + rebuildColorMat = true; + currentBrightness = b; + + brightnessMat.SetColumn(0, new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); + brightnessMat.SetColumn(1, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); + brightnessMat.SetColumn(2, new Vector4(0.0f, 0.0f, 1.0f, 0.0f)); + brightnessMat.SetColumn(3, new Vector4(b, b, b, 1.0f)); + } + + if (c != currentContrast) + { + rebuildColorMat = true; + currentContrast = c; + + float t = (1.0f - contrast) / 2.0f; + + contrastMat.SetColumn(0, new Vector4(c, 0.0f, 0.0f, 0.0f)); + contrastMat.SetColumn(1, new Vector4(0.0f, c, 0.0f, 0.0f)); + contrastMat.SetColumn(2, new Vector4(0.0f, 0.0f, c, 0.0f)); + contrastMat.SetColumn(3, new Vector4(t, t, t, 1.0f)); + } + + if (s != currentSaturation) + { + rebuildColorMat = true; + currentSaturation = s; + + Vector3 luminance = new Vector3(0.3086f, 0.6094f, 0.0820f); + float t = 1.0f - s; + + Vector4 red = new Vector4(luminance.x * t + s, luminance.x * t, luminance.x * t, 0.0f); + Vector4 green = new Vector4(luminance.y * t, luminance.y * t + s, luminance.y * t, 0.0f); + Vector4 blue = new Vector4(luminance.z * t, luminance.z * t, luminance.z * t + s, 0.0f); + + saturationMat.SetColumn(0, red); + saturationMat.SetColumn(1, green); + saturationMat.SetColumn(2, blue); + saturationMat.SetColumn(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f)); + } + + if (rebuildColorMat) + colorMat = brightnessMat * contrastMat * saturationMat; + + } + public enum Preset { Default, KitchenTV, MiniCRT, ColorTV, OldTV, HighEndMonitor, ArcadeDisplay, BrokenBlackAndWhite, GreenTerminal, YellowMonitor }; + public enum NoiseMode { Add, Subtract, Multiply, Divide, Lighten, Darken }; + public enum MaskMode { Thin, Dense, Denser, ThinScanline, Scanline, DenseScanline }; + public enum TextureScalingMode { Off, AdjustForWidth, AdjustForHeight }; + public enum TextureScalingPolicy { Always, UpscaleOnly, DownscaleOnly }; + + public static void SetupDefaultPreset(UltimateCRT effect) + { + effect.blurSize = 0.7f; + effect.blurStrength = 0.6f; + effect.bleedingSize = 0.75f; + effect.bleedingStrength = 0.5f; + effect.chromaticAberrationOffset = 1.25f; + effect.RGBMaskIntensivity = 0.6f; + effect.RGBMaskStrength = 0.6f; + effect.RGBMaskBleeding = 0.1f; + effect.colorNoiseMode = NoiseMode.Add; + effect.colorNoiseStrength = 0.15f; + effect.whiteNoiseMode = NoiseMode.Lighten; + effect.whiteNoiseStrength = 0.25f; + effect.darkestLevel = Color.black; + effect.brightestLevel = Color.Lerp(Color.black, Color.white, 235.0f / 255.0f); + effect.darkestColor = Color.Lerp(Color.black, Color.white, 40.0f / 255.0f); + effect.brightestColor = Color.white; + effect.brightness = 0.2f; + effect.contrast = 0.1f; + effect.saturation = -0.05f; + effect.interferenceWidth = 25.0f; + effect.interferenceSpeed = 3.0f; + effect.interferenceStrength = 0.0f; + effect.interferenceSplit = 0.25f; + effect.maskMode = MaskMode.Dense; + effect.maskStrength = 0.35f; // 0.0 - 1.0 + effect.curvatureX = 0.6f; // uniform float crtBend; + effect.curvatureY = 0.6f; // uniform float crtBend; + effect.overscan = 0.0f; // uniform float crtOverscan; // 0.0 - 1.0 + effect.vignetteSize = 0.35f; + effect.vignetteStrength = 0.1f; + effect.textureScaling = TextureScalingMode.AdjustForHeight; + effect.scalingPolicy = TextureScalingPolicy.DownscaleOnly; + effect.textureSize = 768; + } + + public static void SetupKitchenTVPreset(UltimateCRT effect) + { + effect.blurSize = 0.7f; + effect.blurStrength = 0.6f; + effect.bleedingSize = 0.75f; + effect.bleedingStrength = 0.5f; + effect.chromaticAberrationOffset = 1.25f; + effect.RGBMaskIntensivity = 0.4f; + effect.RGBMaskStrength = 0.4f; + effect.RGBMaskBleeding = 0.1f; + effect.colorNoiseMode = NoiseMode.Add; + effect.colorNoiseStrength = 0.15f; + effect.whiteNoiseMode = NoiseMode.Lighten; + effect.whiteNoiseStrength = 0.15f; + effect.darkestLevel = Color.black; + effect.brightestLevel = Color.Lerp(Color.black, Color.white, 235.0f / 255.0f); + effect.darkestColor = Color.Lerp(Color.black, Color.white, 25.0f / 255.0f); + effect.brightestColor = Color.white; + effect.brightness = 0.1f; + effect.contrast = 0.1f; + effect.saturation = -0.05f; + effect.interferenceWidth = 25.0f; + effect.interferenceSpeed = 3.0f; + effect.interferenceStrength = 0.0f; + effect.interferenceSplit = 0.25f; + effect.maskMode = MaskMode.Dense; + effect.maskStrength = 0.25f; + effect.curvatureX = 0.3f; + effect.curvatureY = 0.3f; + effect.overscan = 0.0f; + effect.vignetteSize = 0.35f; + effect.vignetteStrength = 0.1f; + effect.textureScaling = TextureScalingMode.AdjustForHeight; + effect.scalingPolicy = TextureScalingPolicy.DownscaleOnly; + effect.textureSize = 768; + } + + public static void SetupMiniCRTPreset(UltimateCRT effect) + { + effect.blurSize = 0.8f; + effect.blurStrength = 0.8f; + effect.bleedingSize = 0.5f; + effect.bleedingStrength = 1.0f; + effect.chromaticAberrationOffset = 2.5f; + effect.RGBMaskIntensivity = 0.8f; + effect.RGBMaskStrength = 0.8f; + effect.RGBMaskBleeding = 0.3f; + effect.colorNoiseMode = NoiseMode.Add; + effect.colorNoiseStrength = 0.25f; + effect.whiteNoiseMode = NoiseMode.Lighten; + effect.whiteNoiseStrength = 0.25f; + effect.darkestLevel = Color.black; + effect.brightestLevel = Color.Lerp(Color.black, Color.white, 225.0f / 255.0f); + effect.darkestColor = Color.Lerp(Color.black, Color.white, 35.0f / 255.0f); + effect.brightestColor = Color.white; + effect.brightness = 0.3f; + effect.contrast = 0.3f; + effect.saturation = -0.1f; + effect.interferenceWidth = 25.0f; + effect.interferenceSpeed = 3.0f; + effect.interferenceStrength = 0.0f; + effect.interferenceSplit = 0.25f; + effect.maskMode = MaskMode.Denser; + effect.maskStrength = 1.0f; + effect.curvatureX = 0.7f; + effect.curvatureY = 0.7f; + effect.overscan = 0.0f; + effect.vignetteSize = 0.5f; + effect.vignetteStrength = 0.425f; + effect.textureScaling = TextureScalingMode.AdjustForHeight; + effect.scalingPolicy = TextureScalingPolicy.DownscaleOnly; + effect.textureSize = 768; + } + + public static void SetupColorTVPreset(UltimateCRT effect) + { + effect.blurSize = 0.9f; + effect.blurStrength = 0.6f; + effect.bleedingSize = 0.85f; + effect.bleedingStrength = 0.75f; + effect.chromaticAberrationOffset = 1.75f; + effect.RGBMaskIntensivity = 0.4f; + effect.RGBMaskStrength = 0.4f; + effect.RGBMaskBleeding = 0.1f; + effect.colorNoiseMode = NoiseMode.Add; + effect.colorNoiseStrength = 0.3f; + effect.whiteNoiseMode = NoiseMode.Lighten; + effect.whiteNoiseStrength = 0.2f; + effect.darkestLevel = Color.black; + effect.brightestLevel = Color.Lerp(Color.black, Color.white, 235.0f / 255.0f); + effect.darkestColor = Color.Lerp(Color.black, Color.white, 35.0f / 255.0f); + effect.brightestColor = new Color(245.0f / 255.0f, 1.0f, 1.0f); + effect.brightness = 0.0f; + effect.contrast = 0.2f; + effect.saturation = 0.1f; + effect.interferenceWidth = 25.0f; + effect.interferenceSpeed = 3.0f; + effect.interferenceStrength = 0.0f; + effect.interferenceSplit = 0.25f; + effect.maskMode = MaskMode.Denser; + effect.maskStrength = 0.2f; + effect.curvatureX = 0.5f; + effect.curvatureY = 0.5f; + effect.overscan = 0.1f; + effect.vignetteSize = 0.4f; + effect.vignetteStrength = 0.5f; + effect.textureScaling = TextureScalingMode.AdjustForHeight; + effect.scalingPolicy = TextureScalingPolicy.DownscaleOnly; + effect.textureSize = 768; + } + + public static void SetupOldTVPreset(UltimateCRT effect) + { + effect.blurSize = 0.9f; + effect.blurStrength = 0.8f; + effect.bleedingSize = 0.95f; + effect.bleedingStrength = 0.95f; + effect.chromaticAberrationOffset = 1.9f; + effect.RGBMaskIntensivity = 0.7f; + effect.RGBMaskStrength = 0.7f; + effect.RGBMaskBleeding = 0.3f; + effect.colorNoiseMode = NoiseMode.Add; + effect.colorNoiseStrength = 0.5f; + effect.whiteNoiseMode = NoiseMode.Darken; + effect.whiteNoiseStrength = 0.55f; + effect.darkestLevel = Color.black; + effect.brightestLevel = Color.Lerp(Color.black, Color.white, 235.0f / 255.0f); + effect.darkestColor = Color.Lerp(Color.black, Color.white, 35.0f / 255.0f); + effect.brightestColor = new Color(245.0f / 255.0f, 1.0f, 1.0f); + effect.brightness = 0.0f; + effect.contrast = -0.1f; + effect.saturation = -0.05f; + effect.interferenceWidth = 35.0f; + effect.interferenceSpeed = 2.0f; + effect.interferenceStrength = 0.075f; + effect.interferenceSplit = 0.25f; + effect.maskMode = MaskMode.Thin; + effect.maskStrength = 0.75f; + effect.curvatureX = 0.625f; + effect.curvatureY = 0.625f; + effect.overscan = 0.1f; + effect.vignetteSize = 0.4f; + effect.vignetteStrength = 0.5f; + effect.textureScaling = TextureScalingMode.AdjustForHeight; + effect.scalingPolicy = TextureScalingPolicy.DownscaleOnly; + effect.textureSize = 768; + } + + public static void SetupHighEndMonitorPreset(UltimateCRT effect) + { + effect.blurSize = 0.35f; + effect.blurStrength = 0.5f; + effect.bleedingSize = 0.5f; + effect.bleedingStrength = 0.8f; + effect.chromaticAberrationOffset = 0.5f; + effect.RGBMaskIntensivity = 0.4f; + effect.RGBMaskStrength = 0.4f; + effect.RGBMaskBleeding = 0.1f; + effect.colorNoiseMode = NoiseMode.Lighten; + effect.colorNoiseStrength = 0.15f; + effect.whiteNoiseMode = NoiseMode.Lighten; + effect.whiteNoiseStrength = 0.1f; + effect.darkestLevel = Color.black; + effect.brightestLevel = Color.white; + effect.darkestColor = Color.black; + effect.brightestColor = Color.white; + effect.brightness = 0.1f; + effect.contrast = 0.0f; + effect.saturation = 0.05f; + effect.interferenceWidth = 25.0f; + effect.interferenceSpeed = 3.0f; + effect.interferenceStrength = 0.0f; + effect.interferenceSplit = 0.25f; + effect.maskMode = MaskMode.Thin; + effect.maskStrength = 0.3f; + effect.curvatureX = 0.0f; + effect.curvatureY = 0.0f; + effect.overscan = 0.0f; + effect.vignetteSize = 0.0f; + effect.vignetteStrength = 0.0f; + effect.textureScaling = TextureScalingMode.AdjustForHeight; + effect.scalingPolicy = TextureScalingPolicy.DownscaleOnly; + effect.textureSize = 768; + } + + public static void SetupArcadeDisplayPreset(UltimateCRT effect) + { + effect.blurSize = 0.5f; + effect.blurStrength = 0.7f; + effect.bleedingSize = 0.65f; + effect.bleedingStrength = 0.8f; + effect.chromaticAberrationOffset = 0.9f; + effect.RGBMaskIntensivity = 0.4f; + effect.RGBMaskStrength = 0.4f; + effect.RGBMaskBleeding = 0.2f; + effect.colorNoiseMode = NoiseMode.Lighten; + effect.colorNoiseStrength = 0.15f; + effect.whiteNoiseMode = NoiseMode.Lighten; + effect.whiteNoiseStrength = 0.1f; + effect.darkestLevel = Color.black; + effect.brightestLevel = Color.white; + effect.darkestColor = Color.black; + effect.brightestColor = Color.white; + effect.brightness = 0.1f; + effect.contrast = 0.1f; + effect.saturation = 0.1f; + effect.interferenceWidth = 25.0f; + effect.interferenceSpeed = 3.0f; + effect.interferenceStrength = 0.0f; + effect.interferenceSplit = 0.25f; + effect.maskMode = MaskMode.Scanline; + effect.maskStrength = 0.75f; + effect.curvatureX = 0.0f; + effect.curvatureY = 0.0f; + effect.overscan = 0.0f; + effect.vignetteSize = 0.3f; + effect.vignetteStrength = 0.2f; + effect.textureScaling = TextureScalingMode.AdjustForHeight; + effect.scalingPolicy = TextureScalingPolicy.DownscaleOnly; + effect.textureSize = 768; + } + + public static void SetupBrokenBlackAndWhitePreset(UltimateCRT effect) + { + effect.blurSize = 0.9f; + effect.blurStrength = 1.0f; + effect.bleedingSize = 0.75f; + effect.bleedingStrength = 0.9f; + effect.chromaticAberrationOffset = 2.5f; + effect.RGBMaskIntensivity = 0.6f; + effect.RGBMaskStrength = 0.6f; + effect.RGBMaskBleeding = 0.1f; + effect.colorNoiseMode = NoiseMode.Add; + effect.colorNoiseStrength = 0.75f; + effect.whiteNoiseMode = NoiseMode.Lighten; + effect.whiteNoiseStrength = 0.5f; + effect.darkestLevel = Color.Lerp(Color.black, Color.white, 15.0f / 255.0f); + effect.brightestLevel = Color.Lerp(Color.black, Color.white, 225.0f / 255.0f); + effect.darkestColor = Color.Lerp(Color.black, Color.white, 60.0f / 255.0f); + effect.brightestColor = Color.white; + effect.brightness = 0.0f; + effect.contrast = -0.2f; + effect.saturation = -1.0f; + effect.interferenceWidth = 85.0f; + effect.interferenceSpeed = 2.5f; + effect.interferenceStrength = 0.05f; + effect.interferenceSplit = 0.0f; + effect.maskMode = MaskMode.Denser; + effect.maskStrength = 0.15f; + effect.curvatureX = 0.6f; + effect.curvatureY = 0.6f; + effect.overscan = 0.4f; + effect.vignetteSize = 0.75f; + effect.vignetteStrength = 0.5f; + effect.textureScaling = TextureScalingMode.AdjustForHeight; + effect.scalingPolicy = TextureScalingPolicy.DownscaleOnly; + effect.textureSize = 768; + } + + public static void SetupGreenTerminalPreset(UltimateCRT effect) + { + effect.blurSize = 0.9f; + effect.blurStrength = 1.0f; + effect.bleedingSize = 0.8f; + effect.bleedingStrength = 0.65f; + effect.chromaticAberrationOffset = 0.0f; + effect.RGBMaskIntensivity = 0.7f; + effect.RGBMaskStrength = 0.7f; + effect.RGBMaskBleeding = 0.2f; + effect.colorNoiseMode = NoiseMode.Add; + effect.colorNoiseStrength = 0.0f; + effect.whiteNoiseMode = NoiseMode.Lighten; + effect.whiteNoiseStrength = 0.0f; + effect.darkestLevel = Color.Lerp(Color.black, Color.white, 10.0f / 255.0f); + effect.brightestLevel = Color.Lerp(Color.black, Color.white, 205.0f / 255.0f); + effect.darkestColor = new Color(0.0f, 30.0f / 255.0f, 0.0f); + effect.brightestColor = new Color(25.0f / 255.0f, 1.0f, 25.0f / 255.0f); + effect.brightness = 0.4f; + effect.contrast = -0.1f; + effect.saturation = -0.8f; + effect.interferenceWidth = 300.0f; + effect.interferenceSpeed = 25.0f; + effect.interferenceStrength = 0.0035f; + effect.interferenceSplit = 0.0f; + effect.maskMode = MaskMode.DenseScanline; + effect.maskStrength = 0.25f; + effect.curvatureX = 0.55f; + effect.curvatureY = 0.55f; + effect.overscan = 0.0f; + effect.vignetteSize = 0.35f; + effect.vignetteStrength = 0.35f; + effect.textureScaling = TextureScalingMode.AdjustForHeight; + effect.scalingPolicy = TextureScalingPolicy.DownscaleOnly; + effect.textureSize = 768; + } + + public static void SetupYellowMonitorPreset(UltimateCRT effect) + { + effect.blurSize = 0.9f; + effect.blurStrength = 0.6f; + effect.bleedingSize = 0.85f; + effect.bleedingStrength = 0.75f; + effect.chromaticAberrationOffset = 1.75f; + effect.RGBMaskIntensivity = 0.4f; + effect.RGBMaskStrength = 0.4f; + effect.RGBMaskBleeding = 0.1f; + effect.colorNoiseMode = NoiseMode.Multiply; + effect.colorNoiseStrength = 0.4f; + effect.whiteNoiseMode = NoiseMode.Darken; + effect.whiteNoiseStrength = 0.2f; + effect.darkestLevel = Color.Lerp(Color.black, Color.white, 10.0f / 255.0f); + effect.brightestLevel = Color.Lerp(Color.black, Color.white, 205.0f / 255.0f); + effect.darkestColor = new Color(30.0f / 255.0f, 30.0f / 255.0f, 0.0f); + effect.brightestColor = new Color(1.0f, 1.0f, 25.0f / 255.0f); + effect.brightness = 0.5f; + effect.contrast = -0.1f; + effect.saturation = -1.0f; + effect.interferenceWidth = 300.0f; + effect.interferenceSpeed = 25.0f; + effect.interferenceStrength = 0.0035f; + effect.interferenceSplit = 0.0f; + effect.maskMode = MaskMode.DenseScanline; + effect.maskStrength = 0.25f; + effect.curvatureX = 0.4f; + effect.curvatureY = 0.4f; + effect.overscan = 0.0f; + effect.vignetteSize = 0.35f; + effect.vignetteStrength = 0.35f; + effect.textureScaling = TextureScalingMode.AdjustForHeight; + effect.scalingPolicy = TextureScalingPolicy.DownscaleOnly; + effect.textureSize = 768; + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/UltimateCRT.cs.meta b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/UltimateCRT.cs.meta new file mode 100644 index 00000000..513b99c8 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/AppSettings/Filter/UltimateCRT/UltimateCRT.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 6b6d0f839b5b6d44ca00392889d6e894 \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI_ValueEditItem_FloatEdit.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI_ValueEditItem_FloatEdit.cs index a7fbb3ba..193c4f1b 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI_ValueEditItem_FloatEdit.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI_ValueEditItem_FloatEdit.cs @@ -33,7 +33,7 @@ namespace AxibugEmuOnline.Client slider.minValue = (float)valueMenu.Min; slider.maxValue = (float)valueMenu.Max; slider.value = (float)valueMenu.ValueRaw; - m_step = (slider.maxValue - slider.minValue) * 0.05f; + m_step = (slider.maxValue - slider.minValue) * 0.01f; m_dataSetting = false; } From 1090fb4da76910df6282d4dcecbc4c0583e45bde Mon Sep 17 00:00:00 2001 From: "ALIENJACK\\alien" Date: Sun, 26 Jan 2025 10:51:06 +0800 Subject: [PATCH 4/4] =?UTF-8?q?IEmuCore=20=E6=8E=A8=E5=B8=A7,=E8=B7=B3?= =?UTF-8?q?=E5=B8=A7=E6=8A=BD=E8=B1=A1,=E4=B8=8D=E5=86=8D=E9=9C=80?= =?UTF-8?q?=E8=A6=81IEmuCore=E4=BE=9D=E8=B5=96monobehaviour=E7=9A=84update?= =?UTF-8?q?=E6=8E=A8=E5=B8=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AppMain/Emulator/MameEmulator/UMAME.cs | 86 ++++++++----------- .../UniInterface/UniVideoPlayer.cs | 11 ++- .../Emulator/NesEmulator/NesEmulator.cs | 49 ++++------- .../Emulator/NesEmulator/VideoProvider.cs | 3 + .../Assets/Script/AppMain/IEmuCore.cs | 7 ++ .../Assets/Script/AppMain/MonoCom/TickLoop.cs | 2 +- .../Assets/Script/AppMain/Network/NetMsg.cs | 2 +- .../Script/AppMain/UI/InGameUI/InGameUI.cs | 31 +++++++ 8 files changed, 101 insertions(+), 90 deletions(-) diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UMAME.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UMAME.cs index 480a383f..a1932fbd 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UMAME.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UMAME.cs @@ -1,3 +1,7 @@ +using AxibugEmuOnline.Client; +using AxibugEmuOnline.Client.ClientCore; +using AxibugEmuOnline.Client.Network; +using AxibugProtobuf; using AxiReplay; using MAME.Core; using System; @@ -6,13 +10,6 @@ using System.IO; using System.Text; using UnityEngine; using UnityEngine.UI; -using AxibugEmuOnline.Client; -using AxibugEmuOnline.Client.ClientCore; -using AxibugProtobuf; -using static AxibugEmuOnline.Client.NesControllerMapper; -using VirtualNes.Core; -using System.Linq; -using AxibugEmuOnline.Client.Event; public class UMAME : MonoBehaviour, IEmuCore { @@ -49,9 +46,9 @@ public class UMAME : MonoBehaviour, IEmuCore { - //Ϊ60֡ - Application.targetFrameRate = 60; - // ǿƺ + //设为60帧 + Application.targetFrameRate = 120; + // 强制横屏 Screen.orientation = ScreenOrientation.LandscapeLeft; instance = this; mFPS = GameObject.Find("FPS").GetComponent(); @@ -75,7 +72,7 @@ public class UMAME : MonoBehaviour, IEmuCore { StopGame(); } - #region ʵֽӿ + #region 实现接口 public object GetState() { return SaveState(); @@ -107,7 +104,7 @@ public class UMAME : MonoBehaviour, IEmuCore if (LoadGame(romFile.FileName, false)) return true; else - return "Romʧ"; + return "Rom加载失败"; } public void Dispose() { @@ -130,9 +127,9 @@ public class UMAME : MonoBehaviour, IEmuCore mReplayWriter = new ReplayWriter(mChangeRomName, "fuck", ReplayData.ReplayFormat.FM32IP64, Encoding.UTF8); mChangeRomName = loadRom; StopGame(); - //ȡROM + //读取ROM emu.LoadRom(mChangeRomName); - //ȡɹ + //读取成功 if (emu.bRom) { if (bReplay) @@ -142,14 +139,14 @@ public class UMAME : MonoBehaviour, IEmuCore mUniKeyboard.SetRePlay(true); } - //ȡROM֮ÿ߳ʼ + //读取ROM之后获得宽高初始化画面 int _width; int _height; IntPtr _framePtr; emu.GetGameScreenSize(out _width, out _height, out _framePtr); App.log.Debug($"_width->{_width}, _height->{_height}, _framePtr->{_framePtr}"); mUniVideoPlayer.Initialize(_width, _height, _framePtr); - //ʼƵ + //初始化音频 mUniSoundPlayer.Initialize(); - //ʼϷ + //开始游戏 emu.StartGame(); bInGame = true; bLogicUpdatePause = true; @@ -157,48 +154,29 @@ public class UMAME : MonoBehaviour, IEmuCore } else { - App.log.Debug($"ROMʧ"); + App.log.Debug($"ROM加载失败"); return false; } } - void Update() - { - if (!bInGame) - return; - if (bLogicUpdatePause) - { - PushEmulatorFrame(); - if (InGameUI.Instance.IsNetPlay) - FixEmulatorFrame(); - } - mUniVideoPlayer.ApplyFilterEffect(); - mUniVideoPlayer.ApplyScreenScaler(); - - mFPS.text = ($"fpsv {mUniVideoPlayer.videoFPS.ToString("F2")} fpsa {mUniSoundPlayer.audioFPS.ToString("F2")} ,Idx:{App.roomMgr.netReplay?.mCurrClientFrameIdx},RIdx:{App.roomMgr.netReplay?.mRemoteFrameIdx},RForward:{App.roomMgr.netReplay?.mRemoteForwardCount} ,RD:{App.roomMgr.netReplay?.mRemoteForwardCount} ,D:{App.roomMgr.netReplay?.mDiffFrameCount} ,Q:{App.roomMgr.netReplay?.mNetReplayQueue.Count}"); - } - - //Ƿ֡Ч - void FixEmulatorFrame() - { - var skipFrameCount = App.roomMgr.netReplay.GetSkipFrameCount(); - if (skipFrameCount > 0) App.log.Debug($"SKIP FRAME : {skipFrameCount} ,CF:{App.roomMgr.netReplay.mCurrClientFrameIdx},RFIdx:{App.roomMgr.netReplay.mRemoteFrameIdx},RForward:{App.roomMgr.netReplay.mRemoteForwardCount} ,queue:{App.roomMgr.netReplay.mNetReplayQueue.Count}"); - for (var i = 0; i < skipFrameCount; i++) - if (!PushEmulatorFrame()) - break; - } - - bool PushEmulatorFrame() - { - //ɼ֡Input + public bool PushEmulatorFrame() + { + if (!bInGame) return false; + if (!bLogicUpdatePause) return false; + + //采集本帧Input bool bhadNext = mUniKeyboard.SampleInput(); - //δյInput,֡ƽ + //如果未收到Input数据,核心帧不推进 if (!bhadNext) return false; - //һ֡ + //放行下一帧 //emu.UnlockNextFreme(); - //֡ + //推帧 emu.UpdateFrame(); return true; + } + public void AfterPushFrame() + { + mFPS.text = ($"fpsv {mUniVideoPlayer.videoFPS.ToString("F2")} fpsa {mUniSoundPlayer.audioFPS.ToString("F2")} ,Idx:{App.roomMgr.netReplay?.mCurrClientFrameIdx},RIdx:{App.roomMgr.netReplay?.mRemoteFrameIdx},RForward:{App.roomMgr.netReplay?.mRemoteForwardCount} ,RD:{App.roomMgr.netReplay?.mRemoteForwardCount} ,D:{App.roomMgr.netReplay?.mDiffFrameCount} ,Q:{App.roomMgr.netReplay?.mNetReplayQueue.Count}"); } public void SaveReplay() { @@ -245,5 +223,11 @@ public class UMAME : MonoBehaviour, IEmuCore emu.LoadState(br); br.Close(); fs.Close(); - } + } + + public Texture OutputPixel => mUniVideoPlayer.rawBufferWarper; + + public RawImage DrawCanvas => mUniVideoPlayer.DrawCanvas; + + } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UniInterface/UniVideoPlayer.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UniInterface/UniVideoPlayer.cs index e099b012..bdcec8b3 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UniInterface/UniVideoPlayer.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/MameEmulator/UniInterface/UniVideoPlayer.cs @@ -1,4 +1,4 @@ -using AxibugEmuOnline.Client.ClientCore; +using AxibugEmuOnline.Client.ClientCore; using AxibugProtobuf; using MAME.Core; using System; @@ -24,6 +24,9 @@ public class UniVideoPlayer : MonoBehaviour, IVideoPlayer public ulong mFrame { get; private set; } bool bInit = false; + public Texture2D rawBufferWarper => m_rawBufferWarper; + public RawImage DrawCanvas => m_drawCanvas; + private void Awake() { mFrame = 0; @@ -31,7 +34,7 @@ public class UniVideoPlayer : MonoBehaviour, IVideoPlayer m_drawCanvasrect = m_drawCanvas.GetComponent(); } - public void Initialize(int width, int height,IntPtr framePtr) + public void Initialize(int width, int height, IntPtr framePtr) { m_drawCanvas.color = Color.white; @@ -40,7 +43,7 @@ public class UniVideoPlayer : MonoBehaviour, IVideoPlayer mScreenSize = new Vector2Int(width, height); mDataLenght = width * height * 4; //mFrameData = new int[mWidth * mHeight]; - //MAMEBGRA32úú BGRA->RGBA + //MAME来的是BGRA32,好好好 BGRA->RGBA m_rawBufferWarper = new Texture2D(mScreenSize.x, mScreenSize.y, TextureFormat.RGBA32, false); m_rawBufferWarper.filterMode = FilterMode.Point; } @@ -56,7 +59,7 @@ public class UniVideoPlayer : MonoBehaviour, IVideoPlayer public void StopVideo() { bInit = false; - m_drawCanvas.color = new Color(0,0,0,0); + m_drawCanvas.color = new Color(0, 0, 0, 0); } //void Update() diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/NesEmulator.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/NesEmulator.cs index b70030d8..9589f350 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/NesEmulator.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/NesEmulator.cs @@ -6,6 +6,7 @@ using System.Globalization; using System.IO; using System.Xml.Linq; using UnityEngine; +using UnityEngine.UI; using VirtualNes.Core; using VirtualNes.Core.Debug; @@ -38,25 +39,6 @@ namespace AxibugEmuOnline.Client AudioProvider.NesEmu = this; } - /// - /// Unity的逐帧驱动 - /// - private unsafe void Update() - { - if (NesCore != null && !IsPause) - { - PushEmulatorFrame(); - if (InGameUI.Instance.IsNetPlay) - FixEmulatorFrame(); - - var screenBuffer = NesCore.ppu.GetScreenPtr(); - VideoProvider.SetDrawData(screenBuffer); - } - - VideoProvider.ApplyScreenScaler(); - VideoProvider.ApplyFilterEffect(); - } - public RomPlatformType Platform => RomPlatformType.Nes; private CoreSupporter m_coreSupporter; /// @@ -148,20 +130,11 @@ namespace AxibugEmuOnline.Client #if UNITY_EDITOR private ControllerState m_lastState; #endif - //是否跳帧,单机无效 - private void FixEmulatorFrame() - { - var skipFrameCount = App.roomMgr.netReplay.GetSkipFrameCount(); - - if (skipFrameCount > 0) App.log.Debug($"SKIP FRAME : {skipFrameCount}"); - for (var i = 0; i < skipFrameCount; i++) - if (!PushEmulatorFrame()) - break; - } - //推进帧 - private bool PushEmulatorFrame() + public bool PushEmulatorFrame() { + if (NesCore == null || IsPause) return false; + m_coreSupporter.SampleInput(NesCore.FrameCount); var controlState = m_coreSupporter.GetControllerState(); @@ -178,9 +151,15 @@ namespace AxibugEmuOnline.Client return true; + } + + + public unsafe void AfterPushFrame() + { + var screenBuffer = NesCore.ppu.GetScreenPtr(); + VideoProvider.SetDrawData(screenBuffer); } - public IControllerSetuper GetControllerSetuper() { return ControllerMapper; @@ -219,7 +198,11 @@ namespace AxibugEmuOnline.Client UnityEditor.EditorUtility.SetDirty(db); UnityEditor.AssetDatabase.SaveAssets(); - } + } + + public Texture OutputPixel => VideoProvider.OutputPixel; + public RawImage DrawCanvas => VideoProvider.Drawer; + #endif } } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/VideoProvider.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/VideoProvider.cs index e6603d77..63d568ff 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/VideoProvider.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Emulator/NesEmulator/VideoProvider.cs @@ -10,6 +10,9 @@ namespace AxibugEmuOnline.Client { public class VideoProvider : MonoBehaviour { + public RenderTexture OutputPixel => rt_gpu; + public RawImage Drawer => Image; + #region UI_REF public NesEmulator NesEmu; public Canvas DrawCanvas; diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/IEmuCore.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/IEmuCore.cs index a47e7e20..0762293f 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/IEmuCore.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/IEmuCore.cs @@ -1,5 +1,6 @@ using AxibugProtobuf; using UnityEngine; +using UnityEngine.UI; namespace AxibugEmuOnline.Client { @@ -34,6 +35,12 @@ namespace AxibugEmuOnline.Client RomPlatformType Platform { get; } /// 获取当前模拟器帧序号,在加载快照和Reset后,应当重置为0 uint Frame { get; } + /// 模拟器核心推帧 + bool PushEmulatorFrame(); + /// 模拟器核心推帧结束 + void AfterPushFrame(); + Texture OutputPixel { get; } + RawImage DrawCanvas { get; } } public static class IEnumCoreTool diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs index 32952556..e1869a61 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs @@ -1,4 +1,4 @@ -using AxibugEmuOnline.Client.ClientCore; +using AxibugEmuOnline.Client.ClientCore; using AxibugEmuOnline.Client.Common; using AxibugEmuOnline.Client.Network; using AxibugProtobuf; diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Network/NetMsg.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Network/NetMsg.cs index ddad8ec7..307561e1 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Network/NetMsg.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Network/NetMsg.cs @@ -2,6 +2,7 @@ using AxibugProtobuf; using System; using System.Collections.Generic; +using UnityEngine; namespace AxibugEmuOnline.Client.Network { @@ -76,7 +77,6 @@ namespace AxibugEmuOnline.Client.Network { while (queueNetMsg.Count > 0) { - var msgData = queueNetMsg.Dequeue(); PostNetMsgEvent(msgData.Item1, msgData.Item2, msgData.Item3); } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI.cs index e650c4e8..08e9b095 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI.cs @@ -1,5 +1,6 @@ using AxibugEmuOnline.Client.ClientCore; using AxibugEmuOnline.Client.Event; +using AxibugEmuOnline.Client.Network; using AxibugProtobuf; using System; using System.Collections.Generic; @@ -51,6 +52,36 @@ namespace AxibugEmuOnline.Client base.Awake(); } + protected override void Update() + { + base.Update(); + + PushCoreFrame(); + + App.settings.Filter.ExecuteFilterRender(Core.OutputPixel, Core.DrawCanvas); + App.settings.ScreenScaler.CalcScale(Core.DrawCanvas, Core.Platform); + } + + void PushCoreFrame() + { + if (Core.IsNull()) return; + //fluash netMsg + NetMsg.Instance.DequeueNesMsg(); + + if (!Core.PushEmulatorFrame()) return; + + if (IsNetPlay) //skip frame handle + { + var skipFrameCount = App.roomMgr.netReplay.GetSkipFrameCount(); + if (skipFrameCount > 0) App.log.Debug($"SKIP FRAME : {skipFrameCount} ,CF:{App.roomMgr.netReplay.mCurrClientFrameIdx},RFIdx:{App.roomMgr.netReplay.mRemoteFrameIdx},RForward:{App.roomMgr.netReplay.mRemoteForwardCount} ,queue:{App.roomMgr.netReplay.mNetReplayQueue.Count}"); + for (var i = 0; i < skipFrameCount; i++) + if (!Core.PushEmulatorFrame()) + break; + } + + Core.AfterPushFrame(); + } + protected override void OnDestroy() { Instance = null;