javascriptthree.js

How to get correct values for normals in threejs?


I don’t understand how normals are computed in threejs.

Here is my problem :

I create a simple plane

var plane = new THREE.PlaneGeometry(10, 100, 10, 10);
var material = new THREE.MeshBasicMaterial();
material.setValues({side: THREE.DoubleSide, color: 0xaabbcc});
var mesh = new THREE.Mesh(plane, material);
mesh.rotateY(Math.PI / 2);
scene.add(mesh);

When I read the normal of this plane, I get (0, 0, 1). But the plane is parallel to the z axis so the value is wrong.

I tried adding

mesh.geometry.computeFaceNormals();
mesh.geometry.computeVertexNormals();

but I still get the same result.

Did I miss anything ?

How can I get correct values for normals from threejs ?

Thanks.


Solution

  • Geometry normals are in object space, in your case you want to transform them to world space.

    // 1. First, make sure the object matrix is updated. 
    // The renderer does this for you in each render loop, so you may be able to skip this step.
    object.updateMatrixWorld();
    
    // 2. Then, compute the normal matrix
    const normalMatrix = new THREE.Matrix3().getNormalMatrix( object.matrixWorld );
    
    // 3. Finally, transform the normal to world space
    const newNormal = normal.clone().applyMatrix3( normalMatrix ).normalize();
    

    three.js r.66