## Easings Library

monolifed
Party member
Posts: 189
Joined: Sat Feb 06, 2016 9:42 pm

### Easings Library

I am writing yet another easings library

smoothstep 1 to 6
polynomial 2 to 6
circle, sine, expo
back, elastic, bounce

https://github.com/monolifed/lua-modules -> easings
Last edited by monolifed on Sat Sep 18, 2021 9:51 am, edited 5 times in total.
pgimeno
Party member
Posts: 2775
Joined: Sun Oct 18, 2015 2:58 pm

### Re: Easings Preview

Nice! But I miss the smoothstep function, 3x² - 2x³.

I'm not a big fan of piecewise defined functions for easing, because their lack of smoothness is sometimes perceptible.

monolifed
Party member
Posts: 189
Joined: Sat Feb 06, 2016 9:42 pm

### Re: Easings Preview

Which ones are not smooth?
bounce is clearly not
elasticOutIn, expoOutIn also not
Anything else?

I think its out version can be

Code: Select all

f(x) = sqrt(x * (x - 1) / 3) for x < 0.5
1 - f(x - 2) for x >= 0.5

Thinking again, smoothstep is more like an InOut function
pgimeno
Party member
Posts: 2775
Joined: Sun Oct 18, 2015 2:58 pm

### Re: Easings Preview

I mean smooth as in infinitely derivable. Any polynomial function, like smoothstep, has this property. Note however that just having the first derivative continuous makes the function have no angles, but that's not what I meant. Many if not all of the first derivatives of your piecewise InOut and OutIn functions have angles, and that may cause visible effects.

Consider for example the quadInOut function. It's equivalent to the following scenario: imagine you're in a car; starting from 0 speed, you accelerate with constant acceleration for the first 50 m and then brake for another 50 m with constant deceleration until you're stopped again. In the car, it means you go from having your back against the back of the seat, to suddenly having your chest against the seatbelt, rather than having a smooth transition between these two cases. The abrupt change from accelerating to decelerating means the second derivative is not continuous, and it's noticeable for someone observing the car's movement.

It's even worse in the case of cubicInOut, for example, because it means that the acceleration grows constantly for the first half of the trajectory and suddenly changes its sign during the second half.
monolifed
Party member
Posts: 189
Joined: Sat Feb 06, 2016 9:42 pm

### Re: Easings Preview

Yes they (InOut ones) don't seem to have continuous second derivatives.
Interestingly leap from acceleration to deceleration doesn't seem to affect smoothness of the transition noticeably
Last edited by monolifed on Tue Sep 14, 2021 5:12 pm, edited 1 time in total.
milon
Party member
Posts: 182
Joined: Thu Jan 18, 2018 9:14 pm

### Re: Easings Preview

As pgimeno as pointed out in both posts, it can/will affect the smoothness of transitions. Whether or not it's noticed will depend on the hardware, framerate, user, etc. If you want to guarantee a smooth transition then the second derivative function must be continuous.
monolifed
Party member
Posts: 189
Joined: Sat Feb 06, 2016 9:42 pm

### Re: Easings Preview

I understand that they are not mathematically smooth but I am yet to see visual artifacts caused by it, Feel free to provide an example

That said I am not inventing new functions here. They are some standard functions and some other functions from easings.net
If they are not smooth there is nothing I can do.

Also you can provide functions if you want, I will add them

pgimeno
Party member
Posts: 2775
Joined: Sun Oct 18, 2015 2:58 pm

### Re: Easings Preview

Here's an example.

Code: Select all

local smooth = 0

love.graphics.setNewFont(30)

local function lerp(a, b, t)
return t < 0.5 and a + (b - a) * t or b + (a - b) * (1.0 - t)
end

local function smootherstep(t)
return t*t*t*(t*(6*t-15)+10)
end

return t < 0.5 and 2*t*t or 1-2*(1-t)^2
end

local T = 0
function love.update(dt)
T = (T + dt) % 2
end

function love.draw()
local w, h = love.graphics.getDimensions()
local t = T < 1 and T or 2 - T
if smooth == 0 or smooth == 2 then
love.graphics.print("quadInOut", 0, h * 0.4 - love.graphics.getFont():getHeight() - 8)
love.graphics.circle("fill", lerp(w * 0.2, w * 0.8, quadInOut(t)), h*(smooth == 2 and 0.4 or 0.5), 4)
end
if smooth == 1 or smooth == 2 then
love.graphics.print("Smooth", 0, h * 0.6 + 8)
love.graphics.circle("fill", lerp(w * 0.2, w * 0.8, smootherstep(t)), h*(smooth == 2 and 0.6 or 0.5), 4)
end
end

function love.keypressed(k)
if k == "escape" then return love.event.quit() end
if k == "space" then smooth = (smooth + 1) % 3 end
end

I see a visible jerk in the middle of the quadInOut function compared to the approximately equivalent smootherstep function. The jerk is best observed in isolation, and the approximate equivalence can be observed side by side. The jerk is more obvious the steeper the slope in the middle point is; with circInOut it's maximum because the slope is infinite.

I didn't include your code because I've realized that you haven't included a license, so the default copyright applies, which doesn't give me any rights to reproduce it.

BTW, there's a typo in the latest version (missing a separating comma; easily fixable).
monolifed
Party member
Posts: 189
Joined: Sat Feb 06, 2016 9:42 pm

### Re: Easings Preview

Thanks
Yes very slight but there and compared to smootherstep it becomes very noticeable.
polynomial outin functions seem to be smooth but all inout ones have that problem
One solution is adding a higher degree polynomial that resembles the piecewise inout function
(Like the smootherstep you provided)