Exponential Easing Function Does Not Approach 1

I’ve recently discovered that the function TweenService uses for Enum.EasingStyle.Exponential does not approach 1, which results in rough jumps at the end of tweens, particularly when tweening the camera large distances.

It approaches 0.9990234375, which you can easily see just by running the following command in the console:

print(game.TweenService:GetValue(0.9999999, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out))

As a workaround, I made the following function for Exponential which roughly approximates the curve but approaches 1 exactly:

function fixedExponential(t, dir)
	t = math.clamp(t, 0, 1)
	if dir == Enum.EasingDirection.In then
		return math.pow(2, math.pow(t, 4.985)) - 1
	elseif dir == Enum.EasingDirection.Out then
		return 2 - math.pow(2, math.pow(1 - t, 4.985))
	elseif t < 0.5 then
		t *= 2
		return (math.pow(2, math.pow(t, 4.985)) - 1) * 0.5
	else
		t = (t - 0.5) * 2
		return (2 - math.pow(2, math.pow(1 - t, 4.985)) * 0.5) + 0.5
	end
end

While the above workaround works in scenarios where I just need an interpolation value, the Tweens from TweenService:Create() still use the incorrect function, which means they have a slight (but very visible) jump/stutter at the end.

Expected behavior

I’m expecting all functions from TweenService to approach exactly 1 in order to be smooth in all scenarios. If you run the above command with the other EasingStyles, they all return 1 (or very close to it); Exponential is the only style which approaches a different value.

6 Likes

This is very apparent when tweening the camera’s CFrame with the Exponential easing style. It’s been happening for years!

2 Likes

I had to look into this because I was confused how it could be wrong. I thought that the equation for expo was something simple like
y = x^2
but apparently the common expression for this easing style is
y = 2^(x*10 - 10)

This equation fundamentally has a gap, making it non-continuous from 0-1 for easing.
image

I personally would love to have the equation changed to something that is easy to replicate with code and does map continuously between 0 and 1. Maybe one of these?
y = x ^ 5
y = x ^ 5.6
image

2 Likes

Actually, this orange equation is a near perfect fit for the original equation but does continuously map between 0 and 1 as expected.
y = (2^(x*10)-1)/1023
image

2 Likes

Thanks for the report! We’ll follow up when we have an update for you.

3 Likes