How do I load a gltf file that has multiple bin and texture files

This code loads a standalone gltf file, but I have a file that contains multiple bin and texture files

    import React from "react";
    import { useLoader } from "react-three-fiber";

    let GLTFLoader;
    /**
     * @name Scene
     * @param {*} url received
     * @returns {html} primitive
     */
    function Scene({ url }) {
      GLTFLoader = require('three/examples/jsm/loaders/GLTFLoader').GLTFLoader;
      const gltf = useLoader(GLTFLoader, url);
      const { nodes } = gltf;
      
      return (
        <group>
          <mesh visible >
            <bufferGeometry attach="geometry" {...nodes.mesh_0_18.geometry} />
            <meshStandardMaterial
              attach="material"
              color="white"
              roughness={0.3}
              metalness={0.3}
            />
          </mesh>
        </group>
      );
    }

    export default Scene;

I’m displaying this file here:

     <Canvas style={{height:"400px",width:"100%", background: "#ccc"}}>
                      <directionalLight intensity={0.5} />
                      <Suspense fallback={ <Loading /> }>
                        <Scene url="/static/avatars/polka-dot-slip-dress/polka-dot-slip-dress_Colorway-1.gltf"/>
                      </Suspense>
                    </Canvas>

I believe the problem with this code is

<bufferGeometry attach="geometry" {...nodes.mesh_0_18.geometry} />

, there are 20 mesh files. How do I get this to load as I think it might be a geometry issue?

GLTFLoader will automatically download any .bin or texture files that it requires. There is no need to do anything special with that.

As for the rest of the code here, I’m not familiar with using any of this in React, and can’t tell you whether the code is correct for the specific model that you have. It does worry me a little that it references an index _0_18, if that’s an auto-generated name based on the node index, it would not be as stable a way to reference part of the model as if that part of the model had a unique name in the original file.

using just
<bufferGeometry attach="geometry" />
renders a blank screen, but adding the nodes.mesh (auto-generated name) index work for gltf files that have a single nodes.mesh

If the model appears correctly in https://gltf-viewer.donmccurdy.com/ (which also renders with three.js) then I have to assume this is a problem with how react or react-three-fiber is being configured, relative to what the model itself contains. You may have better luck finding a user who knows about that on https://github.com/pmndrs/react-three-fiber/discussions.

1 Like

A quick primer on how you could do it.

Using the whole scene

Either take the output that GLTFLoader gives you (a scene) and throw it on your screen. In r3f you put existing models into your scene via primitive.

:white_check_mark:simplest
:x:it sucks if you want to change model contents, add shadows, events, make stuff conditional

function Model({ url }) {
  const { scene } = useLoader(GLTFLoader, url)
  return <primitive object={scene} />
}

Picking model-parts

R3f gives you two extra collections in the gltf output, nodes and materials. You can use these to pick out stuff by name. As don said, these names represent threes unique names, they can differ from the ones in blender.

:white_check_mark:still easy
:white_check_mark:you can alter things
:x:model data can be nested into groups that transform, scale and rotate the meshes, you’d loose that

function Model({ url }) {
  const { nodes, materials } = useLoader(GLTFLoader, url)
  return <mesh geometry={nodes.robot.geometry} materials={materials.metal} />
}

Using gltfjsx

This is pretty much your best option. Gltfjsx creates a virtual model graph. I don’t think this approach has any downsides.

:white_check_mark:easy since the tool creates your component
:white_check_mark:you can change whatever you want
:white_check_mark:it contains all groups, transforms, meshes

2 Likes

I tried solution 1 and it worked.
Solution 2 is what I have been struggling with. My nodes index has multiple sub-indexes (Scene, mesh_0 …, mesh_0_20) so which of these sub-indexes do I reference as you did here
geometry={nodes.robot.geometry}

I’m currently checking out solution 3

it’s up to you. if you know your gltf contains three objects and you want the one in the middle, then pick it. but i always go for gltfjsx. it plots the entire graph and then it’s easy to rip stuff out. like in this video: https://twitter.com/0xca0a/status/1224335000755146753 after the jsx has been created i drop it into my project and rip the trees out, you can now play with your model in realtime through hot reload.

1 Like