像素化
This commit is contained in:
@@ -10,6 +10,19 @@ namespace Ichni
|
||||
/// </summary>
|
||||
public static class CustomCurvePresets
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 瞬间完成
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static AnimationCurve Instant()
|
||||
{
|
||||
Keyframe[] keys = new Keyframe[2];
|
||||
keys[0] = new Keyframe(0, 1, 0, 0);
|
||||
keys[1] = new Keyframe(1, 1, 0, 0);
|
||||
return new AnimationCurve(keys);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 抛物线曲线,在中间达到最大值,两端为起始值
|
||||
/// </summary>
|
||||
|
||||
@@ -138,6 +138,7 @@ namespace Ichni.RhythmGame
|
||||
{ "Vignette", new VignetteEffect(1, 1, 0.4f, Color.black, CustomCurvePresets.Parabolic(1, 0, 1)) },
|
||||
{ "SetInteger", new SetIntegerEffect("New Variable", 0, false, 0, 1) },
|
||||
{ "EnableControl", new EnableControlEffect(null, "New Variable", 0, false, "") },
|
||||
{"Pixelate", new PixelateEffect(1, 320, 180, CustomCurvePresets.Instant())},
|
||||
{ "LowPassFilter", new LowPassFilterEffect(1, 10, CustomCurvePresets.Parabolic(1, 0, 1)) },
|
||||
{ "HighPassFilter", new HighPassFilterEffect(1, 22000, CustomCurvePresets.Parabolic(1, 0, 1)) },
|
||||
{ "DTM_RippleEffect", new DTMRippleEffect(0.65f, Color.white, 0) }
|
||||
|
||||
@@ -78,7 +78,10 @@ namespace Ichni.RhythmGame
|
||||
|
||||
public override EffectBase ConvertToGameType(GameElement attachedGameElement)
|
||||
{
|
||||
return new BloomEffect(duration, peak, intensityCurve);
|
||||
return new BloomEffect(duration, peak, intensityCurve)
|
||||
{
|
||||
attachedGameElement = attachedGameElement
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Ichni.Editor;
|
||||
using Ichni.RhythmGame.Beatmap;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ichni.RhythmGame
|
||||
{
|
||||
public class PixelateEffect : EffectBase
|
||||
{
|
||||
public float duration;
|
||||
public float bottomX;
|
||||
public float bottomY;
|
||||
public AnimationCurve intensityCurve;
|
||||
|
||||
public PixelateEffect(float duration, float bottomX, float bottomY, AnimationCurve intensityCurve)
|
||||
{
|
||||
this.effectTime = duration;
|
||||
this.duration = duration;
|
||||
this.bottomX = bottomX;
|
||||
this.bottomY = bottomY;
|
||||
this.intensityCurve = intensityCurve;
|
||||
}
|
||||
|
||||
public override void Recover()
|
||||
{
|
||||
EditorManager.instance.postProcessingManager.SetPixelateStrength(Screen.width, Screen.height);
|
||||
EditorManager.instance.postProcessingManager.SetFeatureActive(false);
|
||||
}
|
||||
|
||||
public override void Disrupt()
|
||||
{
|
||||
EditorManager.instance.postProcessingManager.SetPixelateStrength(Screen.width, Screen.height);
|
||||
EditorManager.instance.postProcessingManager.SetFeatureActive(false);
|
||||
}
|
||||
|
||||
public override void PreExecute()
|
||||
{
|
||||
EditorManager.instance.postProcessingManager.SetFeatureActive(true);
|
||||
EditorManager.instance.postProcessingManager.SetPixelateStrength(Screen.width, Screen.height);
|
||||
}
|
||||
|
||||
public override void Execute()
|
||||
{
|
||||
float x = Mathf.Lerp(Screen.width, bottomX, intensityCurve.Evaluate(effectProgressPercent));
|
||||
float y = Mathf.Lerp(Screen.height, bottomY, intensityCurve.Evaluate(effectProgressPercent));
|
||||
Debug.Log(x + ", " + y);
|
||||
|
||||
EditorManager.instance.postProcessingManager.SetPixelateStrength(x,y);
|
||||
}
|
||||
|
||||
public override void Adjust()
|
||||
{
|
||||
EditorManager.instance.postProcessingManager.SetPixelateStrength(Screen.width, Screen.height);
|
||||
EditorManager.instance.postProcessingManager.SetFeatureActive(false);
|
||||
}
|
||||
|
||||
public override EffectBase_BM ConvertToBM()
|
||||
{
|
||||
return new PixelateEffect_BM(duration, bottomX, bottomY, intensityCurve);
|
||||
}
|
||||
|
||||
public override void SetUpInspector()
|
||||
{
|
||||
IHaveInspection inspector = EditorManager.instance.uiManager.inspector;
|
||||
var container = inspector.GenerateContainer("Pixelate Effect");
|
||||
var effectSettings = container.GenerateSubcontainer(3);
|
||||
var effectTimeField = inspector.GenerateInputField(this, effectSettings, "Effect Time", nameof(duration));
|
||||
var bottomXField = inspector.GenerateInputField(this, effectSettings, "Bottom X", nameof(bottomX));
|
||||
var bottomYField = inspector.GenerateInputField(this, effectSettings, "Bottom Y", nameof(bottomY));
|
||||
var intensityCurveButton = inspector.GenerateButton(this, effectSettings, "Intensity Curve", () =>
|
||||
{
|
||||
var intensityCurveWindow =
|
||||
inspector.GenerateCompositeParameterWindow(this, "Intensity Curve", nameof(intensityCurve)).SetAsCustomCurve();
|
||||
});
|
||||
|
||||
var clearButton = inspector.GenerateButton(this, effectSettings, "Clear Pixelate", () =>
|
||||
{
|
||||
EditorManager.instance.postProcessingManager.SetFeatureActive(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
namespace Beatmap
|
||||
{
|
||||
public class PixelateEffect_BM : EffectBase_BM
|
||||
{
|
||||
public float duration;
|
||||
public float bottomX;
|
||||
public float bottomY;
|
||||
public AnimationCurve intensityCurve;
|
||||
|
||||
public PixelateEffect_BM(float duration, float bottomX, float bottomY, AnimationCurve intensityCurve)
|
||||
{
|
||||
this.effectTime = duration;
|
||||
this.duration = duration;
|
||||
this.bottomX = bottomX;
|
||||
this.bottomY = bottomY;
|
||||
this.intensityCurve = intensityCurve;
|
||||
}
|
||||
|
||||
public override EffectBase ConvertToGameType(GameElement attachedGameElement)
|
||||
{
|
||||
return new PixelateEffect(duration, bottomX, bottomY, intensityCurve)
|
||||
{
|
||||
attachedGameElement = attachedGameElement
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1ecccb5fd84627489e74a02a44da11a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,12 +1,90 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Sirenix.OdinInspector;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
namespace Ichni.Editor
|
||||
{
|
||||
public class PostProcessingManager : MonoBehaviour
|
||||
{
|
||||
public Volume globalVolume;
|
||||
public PixelateFeature pixelateFeature;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
FindAndCacheFeatureWithReflection();
|
||||
}
|
||||
|
||||
private void FindAndCacheFeatureWithReflection()
|
||||
{
|
||||
var pipelineAsset = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
|
||||
if (pipelineAsset == null)
|
||||
{
|
||||
Debug.LogError("当前渲染管线不是 UniversalRenderPipelineAsset。");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 使用反射来获取内部的 m_RendererDataList 字段
|
||||
FieldInfo rendererDataListField = typeof(UniversalRenderPipelineAsset).GetField("m_RendererDataList", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (rendererDataListField == null)
|
||||
{
|
||||
Debug.LogError("在 UniversalRenderPipelineAsset 中无法通过反射找到 'm_RendererDataList' 字段。API可能已在你的URP版本中更改。");
|
||||
return;
|
||||
}
|
||||
|
||||
var rendererDataList = rendererDataListField.GetValue(pipelineAsset) as ScriptableRendererData[];
|
||||
if (rendererDataList == null)
|
||||
{
|
||||
Debug.LogError("获取渲染器数据列表失败。");
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 遍历获取到的列表来查找我们的Feature
|
||||
foreach (var rendererData in rendererDataList)
|
||||
{
|
||||
if (rendererData == null) continue;
|
||||
|
||||
var feature = rendererData.rendererFeatures.OfType<PixelateFeature>().FirstOrDefault();
|
||||
if (feature != null)
|
||||
{
|
||||
pixelateFeature = feature;
|
||||
Debug.Log("成功找到并缓存 pixelateFeature (通过反射)!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pixelateFeature == null)
|
||||
{
|
||||
Debug.LogError("在所有 RendererData 中都未找到 pixelateFeature。");
|
||||
}
|
||||
}
|
||||
|
||||
[Button]
|
||||
public void SetFeatureActive(bool enable)
|
||||
{
|
||||
if (pixelateFeature != null)
|
||||
{
|
||||
pixelateFeature.SetActive(enable);
|
||||
}
|
||||
}
|
||||
|
||||
[Button]
|
||||
public void SetPixelateStrength(float strengthX, float strengthY)
|
||||
{
|
||||
if (pixelateFeature != null)
|
||||
{
|
||||
pixelateFeature.settings.pixelateStrengthX = strengthX;
|
||||
pixelateFeature.settings.pixelateStrengthY = strengthY;
|
||||
pixelateFeature.pixelatePass.UpdateConfig(strengthX, strengthY);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("Pixelate feature is not initialized.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user