Material mapping not showing up correctly in my exported GLB

Hi,

I’ve been trying to apply a three JS mesh standardMaterial with a colormap and depthmap to a GLB I exported myself using some custom code to convert a Revit file. The issue I had before was that there were no normals defined, causing the material to become black upon alteration.

This time, it seems like there was a bit of progress, however as you can see in the screenshot the materials aren’t stretching the correct way over the whole surface. I’ve tried repeatWrapping but it does not seem to change anything. Any idea what’s wrong?

I’ve placed a box mesh in front of the element as reference which uses the same texture / materials.

export default function ModelLoader(props: { fileUrl: string }) {
  const url = props.fileUrl;
  const {nodes, scene, materials} = useGLTF(url, true)

  const paths = [
    'PavingStones092_1K_Color.jpg',
    'PavingStones092_1K_Displacement.jpg',
    'PavingStones092_1K_NormalDX.jpg',
    'PavingStones092_1K_Roughness.jpg',
    'PavingStones092_1K_AmbientOcclusion.jpg',
  ].map(p => '/assets/textures/pave/' + p)

  const [colorMap, displacementMap, normalMap, roughnessMap, aoMap] = useTexture(paths, (texture) => {
    if (texture instanceof Texture) {
      texture.repeat.set(1, 1)
      texture.wrapS = RepeatWrapping
      texture.wrapT = RepeatWrapping
      texture.flipY = true
    }
  })
  //
  colorMap.encoding = sRGBEncoding
  displacementMap.encoding = LinearEncoding
  normalMap.encoding = LinearEncoding
  roughnessMap.encoding = LinearEncoding

  const concrete = new MeshStandardMaterial({
    color: "grey",
    normalMap: normalMap,
    map: colorMap,
    flatShading: true,
    roughness: 1,
    roughnessMap: roughnessMap,
    aoMap: aoMap,
    metalness: 0.5,
    side: DoubleSide,
  })

  const glass = new MeshBasicMaterial({
    color: "darkgrey",
    transparent: true,
    opacity: 0.4,
    side: DoubleSide,
  })

  const dirt = new MeshBasicMaterial({
    color: "#BD9A7A",
    side: DoubleSide,
  })

  const grass = new MeshBasicMaterial({
    color: "#348C31",
    side: DoubleSide,
  })

  const roof = new MeshStandardMaterial(
    {
      color: "grey",
      map: colorMap,
      normalMap: normalMap,
      // flatShading: true,
      roughness: 1,
      roughnessMap: roughnessMap,
      aoMap: aoMap,
      metalness: 0.5,
      side: DoubleSide,
    }
  )

  const bricks = new MeshStandardMaterial({
    map: colorMap,
    normalMap: normalMap,
    roughnessMap: roughnessMap,
    aoMap: aoMap,

    // roughness: 1,

    // metalness: 0.5,
    // side: DoubleSide,
  })


  // map materials
  scene.traverse(o => {
    if (o.type !== 'Mesh') return

    // @ts-ignore
    switch (o.material.name) {
      case "NLRS_g2_dakpan_donkergrijs":
        // @ts-ignore
        o.material = roof;
        break;
      case "NLRS_o1_glas_helder":
        // @ts-ignore
        o.material = glass;
        break;
      case "NLRS_f2_zandcement":
        // @ts-ignore
        o.material = concrete;
        break;
      case "NLRS_g2_baksteen":
        // @ts-ignore
        o.material = bricks;
        break;
      case "NLRS_p1_grond":
        // @ts-ignore
        o.material = dirt;
        break;
      case "NLRS_a_terreinbeplanting_gras":
        // @ts-ignore
        o.material = grass;
        break;
      default:
    }
  })

  return <>

    <primitive castShadow object={scene} scale={1}/>
    {/*<primitive castShadow receiveShadow object={scene} rotation={[-1 / 2 * Math.PI, 0, 0]} scale={0.0001}/>*/}

    <mesh position={[1, 1, 1]} material={bricks}>
      <boxGeometry args={[1, 1, 1]} />

    </mesh>
  </>
}

The geometry must have UVs (or “texture coordinates”) for textures to map onto it. I’m not sure if Revit includes those, and you’d need to do a UV unwrapping in software like Blender if not. You’ll also want to set texture.flipY = false for textures added to glTF files.