Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions BopVisualEffects/Core/EffectEnvelope.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using UnityEngine;

namespace BopVisualEffects.Core;

/// <summary>
/// Shared envelope math for effects whose strength fades at event boundaries.
/// </summary>
internal static class EffectEnvelope
{
/// <summary>
/// Evaluates a fade envelope while allowing either boundary fade to be disabled.
/// </summary>
/// <param name="progress">Normalized event progress in the range 0..1.</param>
/// <param name="easeIn">Whether to fade in from zero at the start.</param>
/// <param name="easeOut">Whether to fade out to zero at the end.</param>
/// <param name="fadeInEnd">End of the fade-in segment.</param>
/// <param name="fadeOutStart">Start of the fade-out segment.</param>
public static float Evaluate(float progress, bool easeIn, bool easeOut, float fadeInEnd = 0.2f, float fadeOutStart = 0.8f)
{
progress = Mathf.Clamp01(progress);

if (easeIn && progress < fadeInEnd)
return Mathf.InverseLerp(0f, fadeInEnd, progress);

if (easeOut && progress > fadeOutStart)
return 1f - Mathf.InverseLerp(fadeOutStart, 1f, progress);

return 1f;
}
}
22 changes: 12 additions & 10 deletions BopVisualEffects/Effects/ColorTint/ColorTintEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public MixtapeEventTemplate CreateTemplate(string pluginGuid)
resizable = true,
properties = new Dictionary<string, object>
{
["color"] = new MixtapeEventTemplates.ColorField(new Color(1.0f, 0.0f, 0.0f, 0.25f))
["color"] = new MixtapeEventTemplates.ColorField(new Color(1.0f, 0.0f, 0.0f, 0.25f)),
["ease_in"] = true,
["ease_out"] = true
}
};
}
Expand All @@ -43,6 +45,8 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
var log = ClassLogger.GetForClass<ColorTintEffect>();
var durationBeats = Mathf.Max(0.01f, entity.length);
var color = entity.GetColor("color");
var easeIn = entity.GetBool("ease_in", true);
var easeOut = entity.GetBool("ease_out", true);
var startBeat = entity.beat;
var endBeat = startBeat + durationBeats;

Expand All @@ -53,7 +57,7 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
void SpawnAction()
{
EffectRuntimeController.Instance.SpawnRunner<ColorTintRunner>(runner =>
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, color));
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, color, easeIn, easeOut));
}
}

Expand All @@ -66,17 +70,21 @@ private sealed class ColorTintRunner : MonoBehaviour
private MixtapeLoaderCustom? _loader;
private JukeboxScript? _jukebox;
private ColorTintOverlay? _overlay;
private bool _easeIn;
private bool _easeOut;

/// <summary>
/// Initializes this runner with effect parameters.
/// </summary>
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, Color color)
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, Color color, bool easeIn, bool easeOut)
{
_loader = loader;
_jukebox = jukebox;
_startBeat = startBeat;
_endBeat = endBeat;
_color = new Color(Mathf.Clamp01(color.r), Mathf.Clamp01(color.g), Mathf.Clamp01(color.b), Mathf.Clamp01(color.a));
_easeIn = easeIn;
_easeOut = easeOut;
InitializeOverlay();
}

Expand Down Expand Up @@ -113,13 +121,7 @@ private void LateUpdate()

// Fade in over first 20%, hold, fade out over last 20%.
var progress = Mathf.InverseLerp(_startBeat, _endBeat, currentBeat);
float envelope;
if (progress < 0.2f)
envelope = Mathf.InverseLerp(0f, 0.2f, progress);
else if (progress > 0.8f)
envelope = 1f - Mathf.InverseLerp(0.8f, 1f, progress);
else
envelope = 1f;
var envelope = EffectEnvelope.Evaluate(progress, _easeIn, _easeOut);

if (_overlay != null)
_overlay.SetColor(new Color(_color.r, _color.g, _color.b, _color.a * envelope));
Expand Down
22 changes: 12 additions & 10 deletions BopVisualEffects/Effects/Fog/FogEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ public MixtapeEventTemplate CreateTemplate(string pluginGuid)
properties = new Dictionary<string, object>
{
["color"] = new MixtapeEventTemplates.ColorField(new Color(0.8f, 0.8f, 0.9f, 0.6f)),
["height"] = 0.5f
["height"] = 0.5f,
["ease_in"] = true,
["ease_out"] = true
}
};
}
Expand All @@ -45,6 +47,8 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
var durationBeats = Mathf.Max(0.01f, entity.length);
var color = entity.GetColor("color");
var height = entity.GetFloat("height");
var easeIn = entity.GetBool("ease_in", true);
var easeOut = entity.GetBool("ease_out", true);
var startBeat = entity.beat;
var endBeat = startBeat + durationBeats;

Expand All @@ -55,7 +59,7 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
void SpawnAction()
{
EffectRuntimeController.Instance.SpawnRunner<FogRunner>(runner =>
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, color, height));
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, color, height, easeIn, easeOut));
}
}

Expand All @@ -69,18 +73,22 @@ private sealed class FogRunner : MonoBehaviour
private MixtapeLoaderCustom? _loader;
private JukeboxScript? _jukebox;
private FogOverlay? _overlay;
private bool _easeIn;
private bool _easeOut;

/// <summary>
/// Initializes this runner with effect parameters.
/// </summary>
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, Color color, float height)
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, Color color, float height, bool easeIn, bool easeOut)
{
_loader = loader;
_jukebox = jukebox;
_startBeat = startBeat;
_endBeat = endBeat;
_color = new Color(Mathf.Clamp01(color.r), Mathf.Clamp01(color.g), Mathf.Clamp01(color.b), Mathf.Clamp01(color.a));
_height = Mathf.Clamp01(height);
_easeIn = easeIn;
_easeOut = easeOut;
InitializeOverlay();
}

Expand Down Expand Up @@ -117,13 +125,7 @@ private void LateUpdate()

// Fade in over first 20%, hold, fade out over last 20%.
var progress = Mathf.InverseLerp(_startBeat, _endBeat, currentBeat);
float envelope;
if (progress < 0.2f)
envelope = Mathf.InverseLerp(0f, 0.2f, progress);
else if (progress > 0.8f)
envelope = 1f - Mathf.InverseLerp(0.8f, 1f, progress);
else
envelope = 1f;
var envelope = EffectEnvelope.Evaluate(progress, _easeIn, _easeOut);

if (_overlay != null)
_overlay.SetParams(new Color(_color.r, _color.g, _color.b, _color.a * envelope), _height);
Expand Down
23 changes: 12 additions & 11 deletions BopVisualEffects/Effects/Hsl/HslEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ public MixtapeEventTemplate CreateTemplate(string pluginGuid)
["hue_shift"] = 0.0f,
["saturation"] = 1.0f,
["lightness"] = 0.0f,
["intensity"] = 1.0f
["intensity"] = 1.0f,
["ease_in"] = true,
["ease_out"] = true
}
};
}
Expand All @@ -51,6 +53,8 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
var saturation = entity.GetFloat("saturation");
var lightness = entity.GetFloat("lightness");
var intensity = entity.GetFloat("intensity");
var easeIn = entity.GetBool("ease_in", true);
var easeOut = entity.GetBool("ease_out", true);
var startBeat = entity.beat;
var endBeat = startBeat + durationBeats;

Expand All @@ -61,7 +65,7 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
void SpawnAction()
{
EffectRuntimeController.Instance.SpawnRunner<HslRunner>(runner =>
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, hueShift, saturation, lightness, intensity));
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, hueShift, saturation, lightness, intensity, easeIn, easeOut));
}
}

Expand All @@ -78,12 +82,14 @@ private sealed class HslRunner : MonoBehaviour
private JukeboxScript? _jukebox;
private Camera? _camera;
private HslRequest? _request;
private bool _easeIn;
private bool _easeOut;

/// <summary>
/// Initializes this runner with effect parameters.
/// </summary>
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat,
float hueShift, float saturation, float lightness, float intensity)
float hueShift, float saturation, float lightness, float intensity, bool easeIn, bool easeOut)
{
_loader = loader;
_jukebox = jukebox;
Expand All @@ -93,6 +99,8 @@ public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float
_saturation = Mathf.Max(0f, saturation);
_lightness = Mathf.Clamp(lightness, -0.5f, 0.5f);
_maxIntensity = Mathf.Clamp01(intensity);
_easeIn = easeIn;
_easeOut = easeOut;
InitializeRequest();
}

Expand Down Expand Up @@ -129,13 +137,7 @@ private void LateUpdate()

// Fade in over first 20%, hold, fade out over last 20%.
var progress = Mathf.InverseLerp(_startBeat, _endBeat, currentBeat);
float envelope;
if (progress < 0.2f)
envelope = Mathf.InverseLerp(0f, 0.2f, progress);
else if (progress > 0.8f)
envelope = 1f - Mathf.InverseLerp(0.8f, 1f, progress);
else
envelope = 1f;
var envelope = EffectEnvelope.Evaluate(progress, _easeIn, _easeOut);

if (_request != null)
{
Expand Down Expand Up @@ -178,4 +180,3 @@ private void RemoveRequest()
}
}
}

22 changes: 12 additions & 10 deletions BopVisualEffects/Effects/Letterbox/LetterboxEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ public MixtapeEventTemplate CreateTemplate(string pluginGuid)
resizable = true,
properties = new Dictionary<string, object>
{
["size"] = 0.1f
["size"] = 0.1f,
["ease_in"] = true,
["ease_out"] = true
}
};
}
Expand All @@ -43,6 +45,8 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
var log = ClassLogger.GetForClass<LetterboxEffect>();
var durationBeats = Mathf.Max(0.01f, entity.length);
var size = entity.GetFloat("size");
var easeIn = entity.GetBool("ease_in", true);
var easeOut = entity.GetBool("ease_out", true);
var startBeat = entity.beat;
var endBeat = startBeat + durationBeats;

Expand All @@ -53,7 +57,7 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
void SpawnAction()
{
EffectRuntimeController.Instance.SpawnRunner<LetterboxRunner>(runner =>
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, size));
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, size, easeIn, easeOut));
}
}

Expand All @@ -66,17 +70,21 @@ private sealed class LetterboxRunner : MonoBehaviour
private MixtapeLoaderCustom? _loader;
private JukeboxScript? _jukebox;
private LetterboxOverlay? _overlay;
private bool _easeIn;
private bool _easeOut;

/// <summary>
/// Initializes this runner with effect parameters.
/// </summary>
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float size)
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float size, bool easeIn, bool easeOut)
{
_loader = loader;
_jukebox = jukebox;
_startBeat = startBeat;
_endBeat = endBeat;
_size = Mathf.Clamp(size, 0f, 0.49f);
_easeIn = easeIn;
_easeOut = easeOut;
InitializeOverlay();
}

Expand Down Expand Up @@ -113,13 +121,7 @@ private void LateUpdate()

// Slide bars in over first 15%, hold, slide out over last 15%.
var progress = Mathf.InverseLerp(_startBeat, _endBeat, currentBeat);
float envelope;
if (progress < 0.15f)
envelope = Mathf.InverseLerp(0f, 0.15f, progress);
else if (progress > 0.85f)
envelope = 1f - Mathf.InverseLerp(0.85f, 1f, progress);
else
envelope = 1f;
var envelope = EffectEnvelope.Evaluate(progress, _easeIn, _easeOut, 0.15f, 0.85f);

if (_overlay != null)
_overlay.SetParams(_size * envelope);
Expand Down
22 changes: 12 additions & 10 deletions BopVisualEffects/Effects/PixelGrid/PixelGridEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ public MixtapeEventTemplate CreateTemplate(string pluginGuid)
resizable = true,
properties = new Dictionary<string, object>
{
["pixel_size"] = 4.0f
["pixel_size"] = 4.0f,
["ease_in"] = true,
["ease_out"] = true
}
};
}
Expand All @@ -44,6 +46,8 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
var log = ClassLogger.GetForClass<PixelGridEffect>();
var durationBeats = Mathf.Max(0.01f, entity.length);
var pixelSize = entity.GetFloat("pixel_size");
var easeIn = entity.GetBool("ease_in", true);
var easeOut = entity.GetBool("ease_out", true);
var startBeat = entity.beat;
var endBeat = startBeat + durationBeats;

Expand All @@ -54,7 +58,7 @@ public bool TrySchedule(Entity entity, MixtapeLoaderCustom loader)
void SpawnAction()
{
EffectRuntimeController.Instance.SpawnRunner<PixelGridRunner>(runner =>
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, pixelSize));
runner.Initialize(loader, loader.jukebox, startBeat, endBeat, pixelSize, easeIn, easeOut));
}
}

Expand All @@ -67,17 +71,21 @@ private sealed class PixelGridRunner : MonoBehaviour
private MixtapeLoaderCustom? _loader;
private JukeboxScript? _jukebox;
private PixelGridOverlay? _overlay;
private bool _easeIn;
private bool _easeOut;

/// <summary>
/// Initializes this runner with effect parameters.
/// </summary>
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float pixelSize)
public void Initialize(MixtapeLoaderCustom loader, JukeboxScript? jukebox, float startBeat, float endBeat, float pixelSize, bool easeIn, bool easeOut)
{
_loader = loader;
_jukebox = jukebox;
_startBeat = startBeat;
_endBeat = endBeat;
_pixelSize = Mathf.Clamp(Mathf.RoundToInt(pixelSize), 2, 64);
_easeIn = easeIn;
_easeOut = easeOut;
InitializeOverlay();
}

Expand Down Expand Up @@ -115,13 +123,7 @@ private void LateUpdate()
// Ramp block size up over first 15%, hold, ramp down over last 15%.
// block_size=1 means no pixelation; ramping from 1 → _pixelSize gives a "zooming into pixels" look.
var progress = Mathf.InverseLerp(_startBeat, _endBeat, currentBeat);
float envelope;
if (progress < 0.15f)
envelope = Mathf.InverseLerp(0f, 0.15f, progress);
else if (progress > 0.85f)
envelope = 1f - Mathf.InverseLerp(0.85f, 1f, progress);
else
envelope = 1f;
var envelope = EffectEnvelope.Evaluate(progress, _easeIn, _easeOut, 0.15f, 0.85f);

var currentBlockSize = Mathf.Max(1, Mathf.RoundToInt(Mathf.Lerp(1f, _pixelSize, envelope)));
if (_overlay != null)
Expand Down
Loading
Loading