[math] Add SmoothStep and SmootherStep easing functions#16957
Merged
mockersf merged 1 commit intobevyengine:mainfrom Dec 24, 2024
Merged
[math] Add SmoothStep and SmootherStep easing functions#16957mockersf merged 1 commit intobevyengine:mainfrom
SmoothStep and SmootherStep easing functions#16957mockersf merged 1 commit intobevyengine:mainfrom
Conversation
1811201 to
b137b15
Compare
scottmcm
commented
Dec 24, 2024
| /// Curve functions over the [unit interval], commonly used for easing transitions. | ||
| /// | ||
| /// [unit interval]: `Interval::UNIT` | ||
| #[non_exhaustive] |
Contributor
Author
There was a problem hiding this comment.
Given that adding something to an enum is technically a breaking change, I figured I'd do the broader breaking change of marking this #[non_exhaustive] so that any future additions to the enum will be non-breaking.
BenjaminBrienen
approved these changes
Dec 24, 2024
mockersf
approved these changes
Dec 24, 2024
pcwalton
pushed a commit
to pcwalton/bevy
that referenced
this pull request
Dec 25, 2024
…ne#16957) # Objective Almost all of the `*InOut` easing functions are not actually smooth (`SineInOut` is the one exception). Because they're defined piecewise, they jump from accelerating upwards to accelerating downwards, causing infinite jerk at t=½. ## Solution This PR adds the well-known [smoothstep](https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml), as well as its higher-degree version [smootherstep](https://en.wikipedia.org/wiki/Smoothstep#Variations), as easing functions. Mathematically, these are the classic [Hermite interpolation](https://en.wikipedia.org/wiki/Hermite_interpolation) results: - for smoothstep, the cubic with velocity zero at both ends - for smootherstep, the quintic with velocity zero *and acceleration zero* at both ends And because they're simple polynomials, there's no branching and thus they don't have the acceleration jump in the middle. I also added some more information and cross-linking to the documentation for these and some of the other easing functions, to help clarify why one might want to use these over other existing ones. In particular, I suspect that if people are willing to pay for a quintic they might prefer `SmootherStep` to `QuinticInOut`. For consistency with how everything else has triples, I added `Smooth(er)Step{In,Out}` as well, in case people want to run the `In` and `Out` versions separately for some reason. Qualitatively they're not hugely different from `Quadratic{In,Out}` or `Cubic{In,Out}`, though, so could be removed if you'd rather. They're low cost to keep, though, and convenient for testing. ## Testing These are simple polynomials, so their coefficients can be read directly from the Horner's method implementation and compared to the reference materials. The tests from bevyengine#16910 were updated to also test these 6 new easing functions, ensuring basic behaviour, plus one was updated to better check that the InOut versions of things match their rescaled In and Out versions. Even small changes like ```diff - (((2.5 + (-1.875 + 0.375*t) * t) * t) * t) * t + (((2.5 + (-1.85 + 0.375*t) * t) * t) * t) * t ``` are caught by multiple tests this way. If you want to confirm them visually, here are the 6 new ones graphed: <https://www.desmos.com/calculator/2d3ofujhry>  --- ## Migration Guide This version of bevy marks `EaseFunction` as `#[non_exhaustive]` to that future changes to add more easing functions will be non-breaking. If you were exhaustively matching that enum -- which you probably weren't -- you'll need to add a catch-all (`_ =>`) arm to cover unknown easing functions.
ecoskey
pushed a commit
to ecoskey/bevy
that referenced
this pull request
Jan 6, 2025
…ne#16957) # Objective Almost all of the `*InOut` easing functions are not actually smooth (`SineInOut` is the one exception). Because they're defined piecewise, they jump from accelerating upwards to accelerating downwards, causing infinite jerk at t=½. ## Solution This PR adds the well-known [smoothstep](https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml), as well as its higher-degree version [smootherstep](https://en.wikipedia.org/wiki/Smoothstep#Variations), as easing functions. Mathematically, these are the classic [Hermite interpolation](https://en.wikipedia.org/wiki/Hermite_interpolation) results: - for smoothstep, the cubic with velocity zero at both ends - for smootherstep, the quintic with velocity zero *and acceleration zero* at both ends And because they're simple polynomials, there's no branching and thus they don't have the acceleration jump in the middle. I also added some more information and cross-linking to the documentation for these and some of the other easing functions, to help clarify why one might want to use these over other existing ones. In particular, I suspect that if people are willing to pay for a quintic they might prefer `SmootherStep` to `QuinticInOut`. For consistency with how everything else has triples, I added `Smooth(er)Step{In,Out}` as well, in case people want to run the `In` and `Out` versions separately for some reason. Qualitatively they're not hugely different from `Quadratic{In,Out}` or `Cubic{In,Out}`, though, so could be removed if you'd rather. They're low cost to keep, though, and convenient for testing. ## Testing These are simple polynomials, so their coefficients can be read directly from the Horner's method implementation and compared to the reference materials. The tests from bevyengine#16910 were updated to also test these 6 new easing functions, ensuring basic behaviour, plus one was updated to better check that the InOut versions of things match their rescaled In and Out versions. Even small changes like ```diff - (((2.5 + (-1.875 + 0.375*t) * t) * t) * t) * t + (((2.5 + (-1.85 + 0.375*t) * t) * t) * t) * t ``` are caught by multiple tests this way. If you want to confirm them visually, here are the 6 new ones graphed: <https://www.desmos.com/calculator/2d3ofujhry>  --- ## Migration Guide This version of bevy marks `EaseFunction` as `#[non_exhaustive]` to that future changes to add more easing functions will be non-breaking. If you were exhaustively matching that enum -- which you probably weren't -- you'll need to add a catch-all (`_ =>`) arm to cover unknown easing functions.
mrchantey
pushed a commit
to mrchantey/bevy
that referenced
this pull request
Feb 4, 2025
…ne#16957) # Objective Almost all of the `*InOut` easing functions are not actually smooth (`SineInOut` is the one exception). Because they're defined piecewise, they jump from accelerating upwards to accelerating downwards, causing infinite jerk at t=½. ## Solution This PR adds the well-known [smoothstep](https://registry.khronos.org/OpenGL-Refpages/gl4/html/smoothstep.xhtml), as well as its higher-degree version [smootherstep](https://en.wikipedia.org/wiki/Smoothstep#Variations), as easing functions. Mathematically, these are the classic [Hermite interpolation](https://en.wikipedia.org/wiki/Hermite_interpolation) results: - for smoothstep, the cubic with velocity zero at both ends - for smootherstep, the quintic with velocity zero *and acceleration zero* at both ends And because they're simple polynomials, there's no branching and thus they don't have the acceleration jump in the middle. I also added some more information and cross-linking to the documentation for these and some of the other easing functions, to help clarify why one might want to use these over other existing ones. In particular, I suspect that if people are willing to pay for a quintic they might prefer `SmootherStep` to `QuinticInOut`. For consistency with how everything else has triples, I added `Smooth(er)Step{In,Out}` as well, in case people want to run the `In` and `Out` versions separately for some reason. Qualitatively they're not hugely different from `Quadratic{In,Out}` or `Cubic{In,Out}`, though, so could be removed if you'd rather. They're low cost to keep, though, and convenient for testing. ## Testing These are simple polynomials, so their coefficients can be read directly from the Horner's method implementation and compared to the reference materials. The tests from bevyengine#16910 were updated to also test these 6 new easing functions, ensuring basic behaviour, plus one was updated to better check that the InOut versions of things match their rescaled In and Out versions. Even small changes like ```diff - (((2.5 + (-1.875 + 0.375*t) * t) * t) * t) * t + (((2.5 + (-1.85 + 0.375*t) * t) * t) * t) * t ``` are caught by multiple tests this way. If you want to confirm them visually, here are the 6 new ones graphed: <https://www.desmos.com/calculator/2d3ofujhry>  --- ## Migration Guide This version of bevy marks `EaseFunction` as `#[non_exhaustive]` to that future changes to add more easing functions will be non-breaking. If you were exhaustively matching that enum -- which you probably weren't -- you'll need to add a catch-all (`_ =>`) arm to cover unknown easing functions.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Objective
Almost all of the
*InOuteasing functions are not actually smooth (SineInOutis the one exception).Because they're defined piecewise, they jump from accelerating upwards to accelerating downwards, causing infinite jerk at t=½.
Solution
This PR adds the well-known smoothstep, as well as its higher-degree version smootherstep, as easing functions.
Mathematically, these are the classic Hermite interpolation results:
And because they're simple polynomials, there's no branching and thus they don't have the acceleration jump in the middle.
I also added some more information and cross-linking to the documentation for these and some of the other easing functions, to help clarify why one might want to use these over other existing ones. In particular, I suspect that if people are willing to pay for a quintic they might prefer
SmootherSteptoQuinticInOut.For consistency with how everything else has triples, I added
Smooth(er)Step{In,Out}as well, in case people want to run theInandOutversions separately for some reason. Qualitatively they're not hugely different fromQuadratic{In,Out}orCubic{In,Out}, though, so could be removed if you'd rather. They're low cost to keep, though, and convenient for testing.Testing
These are simple polynomials, so their coefficients can be read directly from the Horner's method implementation and compared to the reference materials. The tests from #16910 were updated to also test these 6 new easing functions, ensuring basic behaviour, plus one was updated to better check that the InOut versions of things match their rescaled In and Out versions.
Even small changes like
are caught by multiple tests this way.
If you want to confirm them visually, here are the 6 new ones graphed: https://www.desmos.com/calculator/2d3ofujhry

Migration Guide
This version of bevy marks
EaseFunctionas#[non_exhaustive]to that future changes to add more easing functions will be non-breaking. If you were exhaustively matching that enum -- which you probably weren't -- you'll need to add a catch-all (_ =>) arm to cover unknown easing functions.