Page 1 of 1
Easings Library
Posted: Mon Sep 13, 2021 8:40 pm
by monolifed
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
Re: Easings Preview
Posted: Mon Sep 13, 2021 11:03 pm
by pgimeno
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.
See also
https://love2d.org/forums/viewtopic.php ... 29#p198129
Re: Easings Preview
Posted: Tue Sep 14, 2021 8:21 am
by monolifed
Which ones are not smooth?
bounce is clearly not
elasticOutIn, expoOutIn also not
Anything else?
I can add smoothstep
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
Re: Easings Preview
Posted: Tue Sep 14, 2021 1:30 pm
by pgimeno
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.
Re: Easings Preview
Posted: Tue Sep 14, 2021 3:09 pm
by monolifed
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
Re: Easings Preview
Posted: Tue Sep 14, 2021 4:23 pm
by milon
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.
Re: Easings Preview
Posted: Tue Sep 14, 2021 5:09 pm
by monolifed
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
Edit: Added smoothstep
Re: Easings Preview
Posted: Wed Sep 15, 2021 11:47 am
by pgimeno
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
local function quadInOut(t)
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).
Re: Easings Preview
Posted: Wed Sep 15, 2021 1:09 pm
by monolifed
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)
(added a license and fixed typo)
(added higher degree smoothstep functions)