Skip to content

vec3 damp and dampVectors#22720

Closed
RenaudRohlinger wants to merge 1 commit into
mrdoob:devfrom
utsuboco:vec3-damping
Closed

vec3 damp and dampVectors#22720
RenaudRohlinger wants to merge 1 commit into
mrdoob:devfrom
utsuboco:vec3-damping

Conversation

@RenaudRohlinger

@RenaudRohlinger RenaudRohlinger commented Oct 22, 2021

Copy link
Copy Markdown
Collaborator

Description

Hello!
WebGL and XR performances can be pretty limited by the browser. When it comes to animations, that fps variation can generate unintentional behaviors. (Let's say you want to smooth a position from point A to point B in X ms if the fps drops the lerp function would increase the animation duration to that point).

Obviously damp is not always what you would need for your animations (let's say you don't care about the time spent to travel A -> B, and just want something very smooth).

By using damp to animate elements, we get rid of the delay generated from the frame rate fluctuation. For the time being, we added this feature only as Vector3.damp and Vector3.dampVectors. Next, we could add a smoothdamp-like slerp function to the quaternion too.

Also added a small demo webgl_instancing_damping.html as a proposal.

ScreenFlow.mp4

TODO: Update docs.

This contribution is funded by Utsubo.

@bhouston

Copy link
Copy Markdown
Contributor

Interesting approach.

When I saw your example on twitter I did wonder to myself why you just didn't create an animation clip which would play back exactly the same no matter what the framerate is. But I guess this is a different application.

An alternative to the damp would be this:
lerp( startValue, endValue, clamp( currentElapsed / timeFrame, 0, 1 ) )

This would then be exact and equivalent to the animation clip example.

I believe this damp is for a different application.... maybe it is best to explain why the two above approaches I suggest are not the best solution?

@mrdoob

mrdoob commented Nov 15, 2021

Copy link
Copy Markdown
Owner

@looeee

looeee commented Nov 18, 2021

Copy link
Copy Markdown
Contributor

So damp is an easing function?

const easeDamp = (lambda, t) => 1 - Math.exp(- lambda * t);

It's quite similar to easeOutExpo:

const easeOutExpo = (t) => -Math.pow(2, -10 * t) + 1;

If you add the lambda smoothing param and raise to the power of Math.E instead of 2 it becomes:

(lambda, d) =>  -Math.pow(Math.E, -lambda * t) + 1;

Which can be written as:

(lambda, t) => 1 - Math.exp(-lambda * t);

@looeee

looeee commented Jan 7, 2022

Copy link
Copy Markdown
Contributor

Looking into this a bit more, it seems like there are two ways lerp is being used. To lerp/damp between a and b, you can either:

  1. pass in a time parameter t in range [0,1]. With t=0 lerp will return a, with t=1, lerp will return b, but neither a nor b get modified.
  2. Pass in a delta time parameter dt. In this case, in each step you need to set a = a + x where x is calculated by lerp with the given easing function (the current Vector3.lerp method works this way).

The second case will work well with the damp easing function 1 - Math.exp(-lambda * dt), because in that case you can put in any dt > 0 and you will never get a value greater than b. I guess that is the magic of damp and it's pretty cool actually. However, I am not fully convinced there's any reason to add new methods everywhere to achieve this - lerp with damp/exp easing will work fine since the term lerp is commonly used for both of these cases. See the main answer in this SO post - at least in Unity, what we are calling damp they seem to simply call lerp.

On the other hand, if many people do think it's worth adding VectorX.damp methods (and maybe `Quaternion.sdamp and others?) then I don't have any particular objection.

Note that the requirement to modify a when using dt is assumed in the definitions here:

https://github.com/mrdoob/three.js/blob/master/src/math/MathUtils.js#L68-L80

It should probably be spelled out somewhere. There's no reason why you can't use dt in lerp and t in damp but you do need to know about this requirement.

@mrdoob

mrdoob commented Jan 12, 2022

Copy link
Copy Markdown
Owner

Yeah... I don't think lerp() was/is supposed to be used to animate.

For these kind of use cases I'd rather rely on tween.js. Although I just noticed very few examples use it these days... The CanvasRenderer examples used it more.

@looeee

looeee commented Jan 13, 2022

Copy link
Copy Markdown
Contributor

Yeah... I don't think lerp() was/is supposed to be used to animate.

Interesting. There exist so many good JS animation libraries that adding this in three.js does seem a bit like reinventing the wheel. So we could remove all the damp stuff and recommend people to use another library for animation? Pretty much all JS animation libraries support custom easing functions so you can pass in damp easing to get this result with Tween.js or another library.

@RenaudRohlinger what do you think about opening PRs to add damp easing to Tween.js/Popmotion/React-Spring etc. instead of three.js?

@RenaudRohlinger

Copy link
Copy Markdown
Collaborator Author

I totally understand and agree @looeee. I will close this PR here and try to come back with this kind of feature somewhere else 👍 (most probably in the react sphere 😬 )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants