Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle the smoothstep degenerate case of empty range #93149

Merged
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
12 changes: 10 additions & 2 deletions core/math/math_funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -447,14 +447,22 @@ class Math {

static _ALWAYS_INLINE_ double smoothstep(double p_from, double p_to, double p_s) {
if (is_equal_approx(p_from, p_to)) {
return p_from;
if (likely(p_from <= p_to)) {
return p_s <= p_from ? 0.0 : 1.0;
} else {
return p_s <= p_to ? 1.0 : 0.0;
}
}
double s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0, 1.0);
return s * s * (3.0 - 2.0 * s);
}
static _ALWAYS_INLINE_ float smoothstep(float p_from, float p_to, float p_s) {
if (is_equal_approx(p_from, p_to)) {
return p_from;
if (likely(p_from <= p_to)) {
return p_s <= p_from ? 0.0f : 1.0f;
} else {
return p_s <= p_to ? 1.0f : 0.0f;
}
}
float s = CLAMP((p_s - p_from) / (p_to - p_from), 0.0f, 1.0f);
return s * s * (3.0f - 2.0f * s);
Expand Down
6 changes: 4 additions & 2 deletions doc/classes/@GlobalScope.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1248,8 +1248,9 @@
<param index="1" name="to" type="float" />
<param index="2" name="x" type="float" />
<description>
Returns the result of smoothly interpolating the value of [param x] between [code]0[/code] and [code]1[/code], based on the where [param x] lies with respect to the edges [param from] and [param to].
The return value is [code]0[/code] if [code]x &lt;= from[/code], and [code]1[/code] if [code]x &gt;= to[/code]. If [param x] lies between [param from] and [param to], the returned value follows an S-shaped curve that maps [param x] between [code]0[/code] and [code]1[/code].
Returns a smooth cubic Hermite interpolation between [code]0[/code] and [code]1[/code].
For positive ranges (when [code]from &lt;= to[/code]) the return value is [code]0[/code] when [code]x &lt;= from[/code], and [code]1[/code] when [code]x &gt;= to[/code]. If [param x] lies between [param from] and [param to], the return value follows an S-shaped curve that smoothly transitions from [code]0[/code] to [code]1[/code].
For negative ranges (when [code]from &gt; to[/code]) the function is mirrored and returns [code]1[/code] when [code]x &lt;= to[/code] and [code]0[/code] when [code]x &gt;= from[/code].
This S-shaped curve is the cubic Hermite interpolator, given by [code]f(y) = 3*y^2 - 2*y^3[/code] where [code]y = (x-from) / (to-from)[/code].
[codeblock]
smoothstep(0, 2, -5.0) # Returns 0.0
Expand All @@ -1259,6 +1260,7 @@
[/codeblock]
Compared to [method ease] with a curve value of [code]-1.6521[/code], [method smoothstep] returns the smoothest possible curve with no sudden changes in the derivative. If you need to perform more advanced transitions, use [Tween] or [AnimationPlayer].
[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/smoothstep_ease_comparison.png]Comparison between smoothstep() and ease(x, -1.6521) return values[/url]
[url=https://raw.githubusercontent.com/godotengine/godot-docs/master/img/smoothstep_range.webp]Smoothstep() return values with positive, zero, and negative ranges[/url]
</description>
</method>
<method name="snapped">
Expand Down
Loading