diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FilterEffect.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FilterEffect.cs index 4d4c3ea..f79752e 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FilterEffect.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FilterEffect.cs @@ -9,17 +9,23 @@ namespace AxibugEmuOnline.Client { public abstract class FilterEffect { - public BoolParameter Enable = new BoolParameter(false); + public bool Enable { get; set; } + + [Range(0.1f, 4f)] + public FloatParameter RenderScale; + public abstract string Name { get; } public IReadOnlyCollection EditableParam => m_editableParamList.AsReadOnly(); List m_editableParamList; Material m_material; - + protected virtual float m_defaultRenderScale { get => 1f; } protected abstract string ShaderName { get; } + private static int m_iResolutionID = Shader.PropertyToID("_iResolution"); public FilterEffect() { + RenderScale = new FloatParameter(m_defaultRenderScale); GetEditableFilterParamters(); m_material = new Material(Shader.Find(ShaderName)); OnInit(m_material); @@ -31,7 +37,6 @@ namespace AxibugEmuOnline.Client { var parameters = (from t in GetType().GetFields(BindingFlags.Instance | BindingFlags.Public) where t.FieldType.IsSubclassOf(typeof(FilterParameter)) - where t.DeclaringType.IsSubclassOf(typeof(FilterEffect)) orderby t.MetadataToken select t); @@ -54,7 +59,7 @@ namespace AxibugEmuOnline.Client public void Render(Texture src, RenderTexture result) { - m_material.SetTexture("_MainTex", src); + m_material.SetVector(m_iResolutionID, new Vector4(result.width, result.height)); OnRenderer(m_material, src, result); } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FilterManager.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FilterManager.cs index 4964462..af69fd1 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FilterManager.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FilterManager.cs @@ -4,7 +4,9 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; using UnityEngine; +using UnityEngine.UI; using static AxibugEmuOnline.Client.FilterEffect; +using static AxibugEmuOnline.Client.FilterManager; namespace AxibugEmuOnline.Client { @@ -48,41 +50,63 @@ namespace AxibugEmuOnline.Client } private RenderTexture result = null; - public Texture ExecuteFilterRender(Texture src) + public void ExecuteFilterRender(Texture src, RawImage renderGraphic) { - -#if UNITY_PSP2 - if (result == null) - { - result = RenderTexture.GetTemporary(Screen.width / 2, Screen.height / 2); - } -#else - if (result == null) - { - result = RenderTexture.GetTemporary(Screen.width, Screen.height); - } - else if (result.width != Screen.width || result.height != Screen.height) - { - RenderTexture.ReleaseTemporary(result); - result = RenderTexture.GetTemporary(Screen.width, Screen.height); - } -#endif - - - bool anyFilterEnable = false; + //获得激活的滤镜 + Filter activeFilter = null; foreach (var filter in Filters) { - if (!filter.m_setting.Enable.GetValue()) continue; - filter.m_setting.Render(src, result); - anyFilterEnable = true; + if (!filter.m_setting.Enable) continue; + activeFilter = filter; + break; } - if (anyFilterEnable) - return result; - else - return src; + if (activeFilter == null) + { + renderGraphic.texture = src; + return; + } + + var resolution = GetRawImageScreenResolution(renderGraphic); + int resWidth = (int)(resolution.x * activeFilter.m_setting.RenderScale.GetValue()); + int resHeight = (int)(resolution.y * activeFilter.m_setting.RenderScale.GetValue()); + + if (result == null) + { + result = RenderTexture.GetTemporary(resWidth, resHeight); + } + else if (result.width != resWidth || result.height != resHeight) + { + RenderTexture.ReleaseTemporary(result); + result = RenderTexture.GetTemporary(resWidth, resHeight); + } + + activeFilter.m_setting.Render(src, result); + + renderGraphic.texture = result; } + Vector2 GetRawImageScreenResolution(RawImage rawImage) + { + // 获取 RawImage 的 RectTransform + RectTransform rectTransform = rawImage.rectTransform; + + // 获取 RawImage 在屏幕上的四个顶点的世界坐标 + Vector3[] corners = new Vector3[4]; + rectTransform.GetWorldCorners(corners); + + // 左下角和右上角的屏幕坐标 + Vector2 bottomLeft = RectTransformUtility.WorldToScreenPoint(rawImage.canvas.worldCamera, corners[0]); + Vector2 topRight = RectTransformUtility.WorldToScreenPoint(rawImage.canvas.worldCamera, corners[2]); + + // 计算宽度和高度 + float width = topRight.x - bottomLeft.x; + float height = topRight.y - bottomLeft.y; + + return new Vector2(width, height); + } + + /// 关闭滤镜预览 public void ShutDownFilterPreview() { @@ -103,8 +127,8 @@ namespace AxibugEmuOnline.Client { foreach (var selfFiler in Filters) { - if (selfFiler != filter) selfFiler.m_setting.Enable.Override(false); - else selfFiler.m_setting.Enable.Override(true); + if (selfFiler != filter) selfFiler.m_setting.Enable = false; + else selfFiler.m_setting.Enable = true; } } @@ -115,7 +139,7 @@ namespace AxibugEmuOnline.Client { //关闭所有后处理效果 foreach (var filter in Filters) - filter.m_setting.Enable.Override(false); + filter.m_setting.Enable = false; } /// diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FixingPixelArtGrille/FixingPixelArtGrille.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FixingPixelArtGrille/FixingPixelArtGrille.cs index bdd2e99..63840bd 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FixingPixelArtGrille/FixingPixelArtGrille.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/FixingPixelArtGrille/FixingPixelArtGrille.cs @@ -37,7 +37,6 @@ public sealed class FixingPixelArtGrille : FilterEffect protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) { - renderMat.SetVector("_iResolution", new Vector4(result.width, result.height, 0, 0)); renderMat.SetVector("_res", new Vector4(DrawResolution.GetValue().x, DrawResolution.GetValue().y, 0, 0)); renderMat.SetFloat("_hardScan", HardScan.GetValue()); renderMat.SetFloat("_hardPix", HardPix.GetValue()); diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/LCDPostEffect/LCDPostEffect.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/LCDPostEffect/LCDPostEffect.cs index fe91ac5..13aaee9 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/LCDPostEffect/LCDPostEffect.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/LCDPostEffect/LCDPostEffect.cs @@ -9,7 +9,6 @@ public sealed class LCDPostEffect : FilterEffect protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) { - renderMat.SetVector("_iResolution", new Vector4(result.width, result.height, 0, 0)); Graphics.Blit(src, result, renderMat); } } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/MattiasCRT/MattiasCRT.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/MattiasCRT/MattiasCRT.cs index 746acef..3e4a30e 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/MattiasCRT/MattiasCRT.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/MattiasCRT/MattiasCRT.cs @@ -13,11 +13,9 @@ public sealed class MattiasCRT : FilterEffect private LocalKeyword _kw_qualityLow; private LocalKeyword _kw_qualityMid; private LocalKeyword _kw_qualityHigh; - private int _pid_iResolution; protected override void OnInit(Material renderMat) { - _pid_iResolution = Shader.PropertyToID("_iResolution"); _kw_qualityLow = new LocalKeyword(renderMat.shader, "_QUALITY_LOW"); _kw_qualityMid = new LocalKeyword(renderMat.shader, "_QUALITY_MID"); _kw_qualityHigh = new LocalKeyword(renderMat.shader, "_QUALITY_HIGH"); @@ -25,7 +23,6 @@ public sealed class MattiasCRT : FilterEffect protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result) { - renderMat.SetVector(_pid_iResolution, new Vector4(result.width, result.height, 0, 0)); renderMat.DisableKeyword(_kw_qualityLow); renderMat.DisableKeyword(_kw_qualityMid); renderMat.DisableKeyword(_kw_qualityHigh); diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/RetroArch_Glow/RetroArchMattiasCRTGlow.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/RetroArch_Glow/RetroArchMattiasCRTGlow.cs index 80e2750..23282ff 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/RetroArch_Glow/RetroArchMattiasCRTGlow.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/RetroArch_Glow/RetroArchMattiasCRTGlow.cs @@ -1,4 +1,4 @@ -using Assets.Script.AppMain.Filter; +using Assets.Script.AppMain.Filter; using AxibugEmuOnline.Client; using UnityEngine; using UnityEngine.Rendering; @@ -47,7 +47,6 @@ public class RetroArchMattiasCRTGlow : FilterEffect m_multipPassCmd.Clear(); m_multipPassCmd.GetTemporaryRT(m_wrapRT, result.width, result.height); - renderMat.SetVector("_iResolution", new Vector2(result.width, result.height)); renderMat.SetFloat(m_gamma_ID, InputGamma.GetValue()); renderMat.SetFloat(m_horiz_gauss_width_ID, GaussianWidth.GetValue()); diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/UIFilterPreviewer.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/UIFilterPreviewer.cs index 8ba8837..7855a2e 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/UIFilterPreviewer.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Filter/UIFilterPreviewer.cs @@ -16,6 +16,6 @@ public class UIFilterPreviewer : MonoBehaviour private void Update() { - m_rawImg.texture = App.filter.ExecuteFilterRender(m_src); + App.filter.ExecuteFilterRender(m_src, m_rawImg); } } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/NesEmulator/VideoProvider.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/NesEmulator/VideoProvider.cs index 680a3d1..48f9299 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/NesEmulator/VideoProvider.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/NesEmulator/VideoProvider.cs @@ -79,7 +79,7 @@ namespace AxibugEmuOnline.Client public void ApplyFilterEffect() { - Image.texture = App.filter.ExecuteFilterRender(rt_gpu); + App.filter.ExecuteFilterRender(rt_gpu, Image); } private unsafe void PrepareUI(uint* screenData)