Three.js: How to flip normals after negative scale

前端 未结 5 1332
臣服心动
臣服心动 2020-12-06 13:50

I have cloned and than flipped an object using negative scale, which causes my single sided faces to inverse. My question is, how can i flip the normals too?

I don\'

5条回答
  •  眼角桃花
    2020-12-06 14:26

    Just dumping this here. I found somewhere flipNormals and translated it for BufferGeometry

    Flip normals, flip UVs, Inverse Face winding

    Version for BufferGeometry

    export function flipBufferGeometryNormals(geometry) {
      const tempXYZ = [0, 0, 0];
    
      // flip normals
      for (let i = 0; i < geometry.attributes.normal.array.length / 9; i++) {
        // cache a coordinates
        tempXYZ[0] = geometry.attributes.normal.array[i * 9];
        tempXYZ[1] = geometry.attributes.normal.array[i * 9 + 1];
        tempXYZ[2] = geometry.attributes.normal.array[i * 9 + 2];
    
        // overwrite a with c
        geometry.attributes.normal.array[i * 9] =
          geometry.attributes.normal.array[i * 9 + 6];
        geometry.attributes.normal.array[i * 9 + 1] =
          geometry.attributes.normal.array[i * 9 + 7];
        geometry.attributes.normal.array[i * 9 + 2] =
          geometry.attributes.normal.array[i * 9 + 8];
    
        // overwrite c with stored a values
        geometry.attributes.normal.array[i * 9 + 6] = tempXYZ[0];
        geometry.attributes.normal.array[i * 9 + 7] = tempXYZ[1];
        geometry.attributes.normal.array[i * 9 + 8] = tempXYZ[2];
      }
    
      // change face winding order
      for (let i = 0; i < geometry.attributes.position.array.length / 9; i++) {
        // cache a coordinates
        tempXYZ[0] = geometry.attributes.position.array[i * 9];
        tempXYZ[1] = geometry.attributes.position.array[i * 9 + 1];
        tempXYZ[2] = geometry.attributes.position.array[i * 9 + 2];
    
        // overwrite a with c
        geometry.attributes.position.array[i * 9] =
          geometry.attributes.position.array[i * 9 + 6];
        geometry.attributes.position.array[i * 9 + 1] =
          geometry.attributes.position.array[i * 9 + 7];
        geometry.attributes.position.array[i * 9 + 2] =
          geometry.attributes.position.array[i * 9 + 8];
    
        // overwrite c with stored a values
        geometry.attributes.position.array[i * 9 + 6] = tempXYZ[0];
        geometry.attributes.position.array[i * 9 + 7] = tempXYZ[1];
        geometry.attributes.position.array[i * 9 + 8] = tempXYZ[2];
      }
    
      // flip UV coordinates
      for (let i = 0; i < geometry.attributes.uv.array.length / 6; i++) {
        // cache a coordinates
        tempXYZ[0] = geometry.attributes.uv.array[i * 6];
        tempXYZ[1] = geometry.attributes.uv.array[i * 6 + 1];
    
        // overwrite a with c
        geometry.attributes.uv.array[i * 6] =
          geometry.attributes.uv.array[i * 6 + 4];
        geometry.attributes.uv.array[i * 6 + 1] =
          geometry.attributes.uv.array[i * 6 + 5];
    
        // overwrite c with stored a values
        geometry.attributes.uv.array[i * 6 + 4] = tempXYZ[0];
        geometry.attributes.uv.array[i * 6 + 5] = tempXYZ[1];
      }
    
      geometry.attributes.normal.needsUpdate = true;
      geometry.attributes.position.needsUpdate = true;
      geometry.attributes.uv.needsUpdate = true;
    }
    

    For old style Geometry

    export function flipNormals (geometry) {
      let temp = 0;
      let face;
    
      // flip every vertex normal in geometry by multiplying normal by -1
      for (let i = 0; i < geometry.faces.length; i++) {
        face = geometry.faces[i];
        face.normal.x = -1 * face.normal.x;
        face.normal.y = -1 * face.normal.y;
        face.normal.z = -1 * face.normal.z;
      }
    
      // change face winding order
      for (let i = 0; i < geometry.faces.length; i++) {
        const face = geometry.faces[i];
        temp = face.a;
        face.a = face.c;
        face.c = temp;
      }
    
      // flip UV coordinates
      const faceVertexUvs = geometry.faceVertexUvs[0];
      for (let i = 0; i < faceVertexUvs.length; i++) {
        temp = faceVertexUvs[i][0];
        faceVertexUvs[i][0] = faceVertexUvs[i][2];
        faceVertexUvs[i][2] = temp;
      }
    
      geometry.verticesNeedUpdate = true;
      geometry.normalsNeedUpdate = true;
    
      geometry.computeFaceNormals();
      geometry.computeVertexNormals();
      geometry.computeBoundingSphere();
    }
    

提交回复
热议问题