I wanted to play around with a simple VR app with fun affects around the hand detections from the Quest 3 headset.
I had plans for all kinds of effects I wanted to do, and I started with this simple sphere following my finger. But it didn’t look nice enough at first!
So I became interested in deriving a smoothstep function by myself.
Detour - deriving smoothstep ourselves
Idea - smoothness at the edges, constant speed inbetween. Because what if we want to travel large distances
Constraints:
- Where
- Given , , and as input constraints, we then have 1 less degree of freedom for whatever parameters define
- Controlling for a, we get a set of curves, which all satisfy our needs
- Another thing: , so that we don’t get this
Using a cubic function:
The function is nice!
But then I’ve got a problem - this function is complicated to compute the inverse of, which I’ll need later. There are formulas for computing the inverse for the cubic from above, and Inigo Quilez even did a post about it. But I don’t want to integrate it because it’s not something I want to derive right now
So I tried a couple more families of functions:
This is all fun & stuff, but the section is called a detour because this function specification isn’t very useful. The speed of the middle section is derived, not an input parameter. and the “warmup distance” isn’t an input parameter.
Deriving a “warmup/warmdown” function
The purpose is to get a function with specific warmup / warmdown properties. I.e.:
- The warmup/warmdown must take time
- During the warmup/warmdown, distance should be traveled
- By the end of warmup we should have speed
Or:
Didn’t manage to derive this for a cubic or a trigonometrical
But it was very doable for !
Assume current position is , target position is , and current speed is
– the distance to target
-
If :
-
if , then we’re up to speed and don’t need to do anything, just update position
-
i.e. we’re not close enough to do “warmdown” yet, we should do “warmup”:
-
-
Otherwise we need to do “warmdown”, strictly according to the function:
Voila! It works