Updating plane vertices in animation loop

He guys, new to ThreeJS and I totally love it. I made a simple animated flag, but now I want to be able (when I scroll my website) to change the amount of vertices that are moved i.e. the intensity.

My code here:

const animate = function () {
		const time = clock.getElapsedTime();

		plane.geometry.vertices.map(vertices => {
			vertices.z = 0.42 * Math.sin(vertices.x * 2 + time);

		plane.geometry.verticesNeedUpdate = true;

		renderer.render(scene, camera);


I am unable to figure out how I can do this. I mean for example:

setTimeout(() => {
		plane.geometry.vertices.map(vertices => {
			vertices.z = 3.42 * Math.sin(vertices.x * 2 + clock.getElapsedTime());

		plane.geometry.verticesNeedUpdate = true;
    }, 5000)

does nothing. So basically what I want to do is increase the amount in:

vertices.z = 3.42 * Math.sin(vertices.x * 2 + clock.getElapsedTime());

and after increasing it, decrease it again back to normal, depending on where the user is scrolling the website.

If I update the rotation for example it does work, but changing the above vertices code does nothing :frowning:

  1. It’s best to avoid using Geometry - wherever possible, use BufferGeometry instead.
  2. Can you please share a runnable code (or jsfiddle or codepen) that shows the issue? It’s a bit easier to find the issue this way.
1 Like

Yes I have put the code in codepen.

I will look into the “buffer geometry” but I dont understand a thing about it haha, thank you very much for your reply mjurczyk!

Are you looking for this? https://jsfiddle.net/4tre32qz/

Math.sin() returns values in the range [-1,1]. If you want to increase the range, you have to multiply them with a value > 1.

1 Like

Hey Mugen, yeah thats what I want sort off. But as you can see in my code when I change the values, nothing is updated visually.

As an example:

setTimeout(() => {
  plane.geometry.vertices.map(vertices => {
    vertices.z = 2.42 * Math.sin(vertices.x * 6 + clock.getElapsedTime());

This does nothing. But when I do (for example):

plane.rotation.set(10, 10, 5);

then the plane does actually rotate. So yeah, increasing the plane.geometry.vertices values does nothing, while other stuff like “rotation” does work.

I took a look at BufferGeometry but I really dont understand it. I got a “plane” but after that I have no clue on how to animate it like I did in my current example. It goes above my head lol, if possible i’d rather stick to simple geometry for now :slight_smile:

Why are you doing this in setTimeout()?

Just for testing purposes :wink:

I would normally do it when triggering a scroll event which watches when certain elements come into the user his screen. When one does, I need to increase the values for i.e. 2 seconds, then decrease them again.

If you are new, the examples from the collection ( Collection of examples from discourse.threejs.org ) may help you.

Based on the example from 2019 ColorStripeChanging I have animated a wave.

See ColorWave

Some things have changed since 2019. Instead of .addAttribute now .setAttribute .

Also the notation for dynamic has changed.
Now .setUsage( THREE.DynamicDrawUsage )

Hope I could help. :slightly_smiling_face:

Yeah thats exactly what I want to do, but AFTER the animation has started. So basically what I want is:

  1. Start the animation with: vertices.z = 0.42 * Math.sin(vertices.x * 2 + time);
  2. After a timeout of 5 seconds use: vertices.z = 1.42 * Math.sin(vertices.x * 2 + time);
  3. After another 5 seconds go back to: vertices.z = 0.42 * Math.sin(vertices.x * 2 + time);

That is what I would like to archieve, but as said… when I change the values, nothing happens :slight_smile:

You don’t see any effect since the vertex displacement in setTimeout() is overwritten in animate().


Well, do not perform the vertex displacement twice. Change the existing one in animate().

Yeah but how… I mean the animate() is an infinite loop. I cannot do that kind of stuff in there or can i?
If i set a timeout for example, it will be automatically executed an infinite times?

Or when I scroll on my website and get to a certain point. How would I change values inside the animate() loop… that is impossible is it not?

Ill give it a try and let you guys know the outcome. Thanks for your reply!