Camera filters (#242)

* Spaceball cleanup and small bug fix

* Replace old hit sound in spaceball

* Camera filters

* added 9 new filters, including 3 types of sepia

* oops

* remark

* normalization of fade out and fade in on filters are by 100

* GenerateFilterTypeEnum comments
This commit is contained in:
Braedon Lewis
2023-01-26 22:42:16 -05:00
committed by GitHub
parent e822a22f54
commit bdfb27b225
230 changed files with 13676 additions and 39 deletions

View File

@ -26,6 +26,7 @@ namespace HeavenStudio
public CircleCursor CircleCursor;
[HideInInspector] public GameObject GamesHolder;
public Games.Global.Flash fade;
public Games.Global.Filter filter;
public GameObject textbox;
[Header("Games")]
@ -109,8 +110,10 @@ namespace HeavenStudio
sp.sortingOrder = 30000;
gameObject.layer = LayerMask.NameToLayer("Flash");
GameObject fade = new GameObject();
GameObject fade = new GameObject("flash");
this.fade = fade.AddComponent<Games.Global.Flash>();
GameObject filter = new GameObject("filter");
this.filter = filter.AddComponent<Games.Global.Filter>();
GlobalGameManager.Init();

View File

@ -0,0 +1,187 @@
using System;
using System.Collections.Generic;
using System.IO;
using Starpelly;
using UnityEngine;
namespace HeavenStudio.Games.Global
{
public class Filter : MonoBehaviour
{
private List<DynamicBeatmap.DynamicEntity> allFilterEvents = new List<DynamicBeatmap.DynamicEntity>();
private int lastFilterIndexesCount = 0; // Optimization
private List<AmplifyColorEffect> amplifies = new List<AmplifyColorEffect>(); // keeps memory of all the filters on the main camera
private List<Texture2D> amplifyTextures = new List<Texture2D>(); // All available camera filters in texture format
// Because of how HS serializes enums, we have to number these manually to make sure a level doesn't break if we add more.
// Backwards compatibility is preserved as long as new elements are appended to the end of this enum. (!DO NOT TRY TO SORT THESE!)
public enum FilterType
{
accent = 0,
air = 1,
atri = 2,
bleach = 3,
bleak = 4,
blockbuster = 5,
cinecold = 6,
cinewarm = 7,
colorshift = 8,
dawn = 9,
deepfry = 10,
deuteranopia = 11,
exposed = 12,
friend = 13,
friend_diffusion = 14,
gamebob = 15,
gamebob_2 = 16,
gameboy = 17,
gameboy_color = 18,
glare = 19,
grayscale = 20,
grayscale_invert = 21,
invert = 22,
iso_blue = 23,
iso_cyan = 24,
iso_green = 25,
iso_highlights = 26,
iso_magenta = 27,
iso_mid = 28,
iso_red = 29,
iso_shadows = 30,
iso_yellow = 31,
maritime = 32,
moonlight = 33,
nightfall = 34,
polar = 35,
poster = 36,
protanopia = 37,
redder = 38,
sanic = 39,
sepia = 40,
sepier = 41,
sepiest = 42,
shareware = 43,
shift_behind = 44,
shift_left = 45,
shift_right = 46,
tina = 47,
tiny_palette = 48,
toxic = 49,
tritanopia = 50,
vibrance = 51,
winter = 52,
}
#region MonoBehaviour
private void Start()
{
foreach (var filt in Enum.GetNames(typeof(FilterType)))
amplifyTextures.Add(Resources.Load<Texture2D>(Path.Combine("Filters/", filt)));
GameManager.instance.onBeatChanged += OnBeatChanged;
// Don't use this because of serialization, add to the "FilterType" enum above manually.
// GenerateFilterTypeEnum();
}
#endregion
#region Filter
private void OnBeatChanged(float beat)
{
allFilterEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "filter" });
}
private void Update()
{
var songPosBeat = Conductor.instance.songPositionInBeats;
var filterIndexes = new List<int>();
for (int i = 0; i < allFilterEvents.Count; i++)
{
var filter = allFilterEvents[i];
if (filter.beat > songPosBeat)
break;
if (filter.beat + filter.length < songPosBeat)
continue;
filterIndexes.Add(i);
}
bool indexCountChanged = filterIndexes.Count != lastFilterIndexesCount;
if (indexCountChanged)
{
for (int i = 0; i < amplifies.Count; i++)
{
Destroy(amplifies[i]);
}
amplifies.Clear();
}
for (int i = 0; i < filterIndexes.Count; i++)
{
var filter = allFilterEvents[filterIndexes[i]];
if (filter.beat <= songPosBeat && filter.beat + filter.length >= songPosBeat)
{
var fadeInTime = filter["fadein"] * 0.01f;
var fadeOutTime = filter["fadeout"] * 0.01f;
var intensity = filter["inten"];
intensity = Mathf.Lerp(1, 0, Mathp.Normalize(intensity, 0, 100));
var blendAmount = intensity;
var endFadeInTime = Mathf.Lerp(filter.beat, filter.beat + filter.length, fadeInTime);
var startFadeOutTime = filter.beat + (Mathf.Lerp(0, filter.length, Mathf.Lerp(1, 0, fadeOutTime)));
if (songPosBeat < endFadeInTime)
{
var normalizedFadeIn = Mathp.Normalize(songPosBeat, filter.beat, endFadeInTime);
blendAmount = Mathf.Lerp(1f, intensity, normalizedFadeIn);
}
else if (songPosBeat >= startFadeOutTime)
{
var normalizedFadeOut = Mathf.Clamp01(Mathp.Normalize(songPosBeat, startFadeOutTime, filter.beat + filter.length));
blendAmount = Mathf.Lerp(intensity, 1f, normalizedFadeOut);
}
var newAmplify =
(indexCountChanged) ?
GameManager.instance.GameCamera.gameObject.AddComponent<AmplifyColorEffect>() :
(AmplifyColorEffect)GameManager.instance.GameCamera.GetComponents(typeof(AmplifyColorEffect))[i];
var texIndex = (int)filter["filter"];
newAmplify.LutTexture = amplifyTextures[texIndex];
newAmplify.BlendAmount = blendAmount;
amplifies.Add(newAmplify);
}
}
lastFilterIndexesCount = filterIndexes.Count;
}
/// <summary>
/// Logs C# code of the "FilterType" enum.
/// </summary>
private void GenerateFilterTypeEnum()
{
var allFilterTypes = Resources.LoadAll("Filters");
var filterEnum = string.Empty;
filterEnum += "public enum FilterType\n{\n";
for (int i = 0; i < allFilterTypes.Length; i += 2)
{
filterEnum += $" {allFilterTypes[i].name} = {i / 2},\n";
}
filterEnum += "}";
Debug.Log(filterEnum);
}
#endregion
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae4410fc1adf0c3449bcdd0b493aacd5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -43,10 +43,6 @@ namespace HeavenStudio.Games.Global
public void OnBeatChanged(float beat)
{
// I really need to create a class for objects that are constant like the Spaceball Camera
// startColor = new Color(1, 1, 1, 0);
// endColor = new Color(1, 1, 1, 0);
allFadeEvents = EventCaller.GetAllInGameManagerList("vfx", new string[] { "flash" });
Test(beat);

View File

@ -378,6 +378,15 @@ namespace HeavenStudio
new Param("ease", EasingFunction.Ease.Linear, "Ease")
}
),
new GameAction("filter", "Filter", 1f, true,
new List<Param>()
{
new Param("filter", Games.Global.Filter.FilterType.grayscale, "Filter"),
new Param("inten", new EntityTypes.Float(0, 100, 100), "Intensity"),
new Param("fadein", new EntityTypes.Float(0, 100, 0), "Fade In"),
new Param("fadeout", new EntityTypes.Float(0, 100, 0), "Fade Out")
}
),
new GameAction("move camera", "Move Camera", 1f, true, new List<Param>()
{
new Param("valA", new EntityTypes.Float(-50, 50, 0), "Right / Left"),