# How do i replicate this effect in React Three Fiber?

Hi. I’ve been using three.js fora while now and decided to move to react-three. for my first project I decided to replicate this effect I found on codepen: https://codepen.io/chriscourses/pen/aZRzOM since the code is not too complicated I just need to offset the vertices of a PlaneGeometry over time to resemble the waves of a lowpoly ocean.

The problem comes from the react three library using a PlaneBufferGeometry compared to the PlaneGeometry used by the original implementation in plain JS. meaning that i do not have access to vertices information. I’ve been able to work around this by updating the geometry.attributes.position.array

original:

geometry.vertices.forEach(function(vertice) {
vertice.x += (Math.random() - 0.5) * 4;
vertice.y += (Math.random() - 0.5) * 4;
vertice.z += (Math.random() - 0.5) * 4;
vertice.dx = Math.random() - 0.5;
vertice.dy = Math.random() - 0.5;
vertice.randomDelay = Math.random() * 5;
});

for ( var i = 0; i < geometry.faces.length; i ++ ) {
geometry.faces[ i ].color.setStyle( baseColor );
geometry.faces[ i ].baseColor =  baseColorRGB;
}

my implementation:

for (let i = 0; i <= mesh.geometry.attributes.position.array.length; i += 3){
mesh.geometry.attributes.position.array[i]     += (Math.random() - 0.5) * 4  // x
mesh.geometry.attributes.position.array[i + 1] += (Math.random() - 0.5) * 4  // y
mesh.geometry.attributes.position.array[i + 2] += (Math.random() - 0.5) * 4  // z
}
// can't access .dx, .dy, .randomDelay, and .faces

i’m struggling to find a way to update the geometry dx, dy, randomDelay, faces values since i cannot find them anyway in the PlaneBufferGeometry.

Here’s my question: how do i replicate the effect in react three? is there no way for me to use a plain PlaneGeometry?

i think there is a mix up. fiber doesn’t change anything regarding threejs, there are no new or altered objects etc, it merely reflects the threejs that you have installed as is.

a long while ago threejs deleted PlaneBufferGeometry (along with all other buffer geometries, as well as THREE.Face3) and now there is only PlaneGeometry, you do not have access to faces no more and dealing with attributes is a bit more complicated. what you’re looking for is essentially how to upgrade an old threejs example to modern threejs, i think if you re-word that you would get more attention.

ps, this thread describes the migration THREE.Geometry will be removed from core with r125

ok my version of three.js only uses buffered geometries since they are better for performance. is there no way in my current version to replicate the effect shown in the code pen? and if not would it be worth to downgrade my version of three.js so I can use the old geometries?

there is no way other than updating the code to attributes. i wouldn’t bother going back to old threejs, it would work, including fiber, but you would be stuck there.

The current version also uses buffer geometries. The old legacy geometry classes have been removed and stuff like BoxBufferGeometry have simply been renamed to BoxGeometry

so are we saying that the new version of three is more limited than the legacy version, that is no longer available? like there’s no way to replicate the effect without using custom shaders?

@drcmda what do you mean by updating the code to attributes?

We are not saying this. Here are more details. In the past, the structure of geometries was designed to be easier for humans, but this was too inconvenient for computers. Then a new structure was proposed, that was easier for the computers to use, and as a result – graphics were much faster. For some time both structures coexisted, but at some point the old one was abandoned. For good. The example that you want to recreate uses the old structure.

There is absolutely no need to use a custom shader in order to replicate this effect. It can be done completely with the current core functionality of Three.js. Here is a demo with low-poly beach. It uses a standard geometry with programatically modified vertices:

https://codepen.io/boytchev/full/xxaKXgK

My suggestion would be to recreate the original example with modern Three.js, and then to think about porting it to R3F.

5 Likes

Thank you so much that was honestly a great answer

1 Like