mattdesl / workshop-webgl-glsl

A workshop on WebGL and GLSL
https://frontendmasters.com/courses/webgl-shaders/
1.03k stars 143 forks source link

some changes in ThreeJS which break compatibility #10

Open gregja opened 3 years ago

gregja commented 3 years ago

Hi Matt, I'm studying now your great course on frontendmasters, and it helps me a lot to better understand how the shaders work.

I've noticed two changes on ThreeJS, which break the compatiliby with the previous versions, and break two of your examples.

First, the "Geometry" constructor disapeared, so it breaks one of your examples, but it's not too difficult to fix it, by using the BufferGeometry constructor (like you show on another example). To complete the topic, I found that article which is interesting : https://sbcode.net/threejs/geometry-to-buffergeometry/

Second impact is on the example which uses the vertices of an icosahedron. The property "vertices" disappeared. So I wrote a little function to fix that in my code :

function getVertices(geom) {
    let positions = geom.attributes.position.array;
    let count = positions.length / 3;
    let datas = [];
    for (let i = 0; i < count; i++) {
        datas.push( new THREE.Vector3(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]) );
    }
    return datas;
}

I hope it will help other students. Take care, Greg

rhernandog commented 2 years ago

Thanks @gregja.

One thing to notice about this:

function getVertices(geom) {
    let positions = geom.attributes.position.array;
    let count = positions.length / 3;
    let datas = [];
    for (let i = 0; i < count; i++) {
        datas.push( new THREE.Vector3(positions[i * 3], positions[i * 3 + 1], positions[i * 3 + 2]) );
    }
    return datas;
}

The array in the position buffer attribute, contains all the points of all the triangles that compose the icosahedron geometry, so there are a lot of duplicated points. In order to get something similar to the old vertices I used lodash to remove the duplicated elements from the array:

// At the top of the file
const _ = require("lodash");

const points = getVertices(baseGeometry);
// Remove duplicates
const cleanPoints = _.uniqWith(points, _.isEqual);

const spaceOrigin = new THREE.Vector3();
const pointMaterial  = new THREE.MeshBasicMaterial({
  color: "#444",
  side: THREE.BackSide
});

cleanPoints.forEach(point => {
  const mesh = new THREE.Mesh(circleGeometry, pointMaterial);
  mesh.position.copy(point);
  mesh.scale.setScalar(0.075 * Math.random() + 0.075);
  mesh.lookAt(spaceOrigin);
  scene.add(mesh);
});

Best, Rodrigo.