Skip to content

Instantly share code, notes, and snippets.

@a3geek
Last active January 5, 2023 04:14
Show Gist options
  • Save a3geek/8cb23cbafdc1eec0a6f975f8bb83ce90 to your computer and use it in GitHub Desktop.
Save a3geek/8cb23cbafdc1eec0a6f975f8bb83ce90 to your computer and use it in GitHub Desktop.
Knee Curve and Soft Knee Curve for Unity.
using System;
using UnityEngine;
namespace Gists
{
[Serializable]
public class KneeCurve
{
[SerializeField]
protected float threshold = 0f;
public KneeCurve(float threshold)
{
this.threshold = threshold;
}
public virtual float Evaluate(float source)
{
return Mathf.Max(source - this.threshold, 0f) / Mathf.Max(source, float.MinValue);
}
public virtual AnimationCurve ToAnimationCurve(float step = 0.01f, float min = 0f, float max = 1f)
{
var curve = new AnimationCurve();
for(var i = min; i <= max; i += step)
{
curve.AddKey(i, this.Evaluate(i));
}
return curve;
}
}
[Serializable]
public class SoftKneeCurve : KneeCurve
{
[SerializeField, Range(0f, 1f)]
protected float softThreshold = 0f;
public SoftKneeCurve(float threshold, float softThreshold) : base(threshold)
{
this.softThreshold = Mathf.Min(Mathf.Max(softThreshold, 0f), 1f);
}
public override float Evaluate(float source)
{
var knee = this.softThreshold * this.threshold;
var soft = Mathf.Pow(Mathf.Min(2f * knee, Mathf.Max(0f, source - threshold + knee)), 2f) / (4f * knee * float.MinValue);
return Mathf.Max(source - this.threshold, soft) / Mathf.Max(source, float.MinValue);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment