Moon
Moon

Reputation: 313

GLTF objects doesn`t load into my react three fiber Canvas element

I downloaded a gltf model from sketchfab to put in my website. This one, https://sketchfab.com/3d-models/space-exploration-wlp-series-8-91964c1ce1a34c3985b6257441efa500.

But everytime I try to load it into my project, everything from my screen just disappears. I thought that I set up the Canvas element somewhat wrong, so I tested it by putting some Stars object from three/drei.

import { Canvas } from "@react-three/fiber";
import { Suspense } from "react";

import { Stars } from '@react-three/drei';

function App() {
  return (
    <div className="App">
      <Canvas style={{ height: '100vh', width: '100vw' }}>
        <Suspense>
          <pointLight color="#f6f3ea" position={[10, 5, 10]} intensity={2} />
          <Stars />
        </Suspense>
      </Canvas>
    </div>
  )
}

and sure enough, it works.enter image description here

I converted the gltf object I donwloaded into a jsx component using npx gltfjsx, resulting in the Scene component

import React, { useRef } from 'react'
import { useGLTF } from '@react-three/drei'

export function Scene(props) {
  const { nodes, materials } = useGLTF('/scene.gltf')
  return (
    <group {...props} dispose={null}>
      <group rotation={[-Math.PI / 2, 0, 0]}>
        <group position={[0, 0.02, -6.33]} rotation={[0.24, -0.55, 0.56]} scale={7}>
          <mesh geometry={nodes.planet001_1.geometry} material={materials.scene} />
          <mesh geometry={nodes.planet001_2.geometry} material={materials.scene} />
        </group>
      </group>
    </group>
  )
}

useGLTF.preload('/scene.gltf')

but when I tried to load the component into my Canvas element

  <Canvas style={{ height: '100vh', width: '100vw' }}>
    <Suspense>
      <pointLight color="#f6f3ea" position={[10, 5, 10]} intensity={2} />
      <Stars />
      <Scene />
    </Suspense>
  </Canvas>

my screen just turns up blank, it shows nothing on the screen. I thought that the z position of -6.33 on the group element in the Scene component was pushing it "behind" the screen (if that makes sense), so I changed it to 2 or 5 or 10, but the result was the same. I also thought that the rotation might be a problem, so I took it out to see what would happen, but same result. Why is that when I try to load this gltf into my scene, not only I can't see it but my entire background with the stars also vanished?

Upvotes: 1

Views: 2523

Answers (4)

Theshirya
Theshirya

Reputation: 31

My Solution and Explanation

Dependencies
Next.js: 14.2.23
React: 18.3.1
@react-three/fiber: 8.17.12
@react-three/drei: 9.121.2

Place all your 3D models inside the /public folder. This is because Next.js automatically serves files in /public as "publicly available" resources.

If you put models in other folders (like /components or anywhere else), they won't be accessible.

I initially thought useGLTF uses relative paths (based on the current file's location), but this is wrong. Instead, the path you provide to useGLTF must be a global path, starting from the root of the next.js app

My folder structure

/public  
  /models  
    /Cube  
      Cube.jsx  
      license.txt  
      scene.bin  
      scene.glft

Even though my Cube.jsx file is inside /public/models/Cube, I still have to provide a global path when using useGLTF

useGLTF('/models/Cube/scene.gltf')

I didn't include /public in the path. Next.js automatically assumes the /public folder as the base path for serving static files.

Upvotes: 0

Kostas Minaidis
Kostas Minaidis

Reputation: 5516

Make sure to download all the resources from Sketchfab:

  • textures/scene_baseColor.png
  • textures/scene_emissive.png
  • scene.bin
  • scene.gltf

Then, use the following setup:

import { Canvas } from '@react-three/fiber'
import { Suspense } from 'react'
import { Stars } from '@react-three/drei'
import { useLoader } from '@react-three/fiber'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'

export default function App() {
  const gltf = useLoader(GLTFLoader, 'scene.gltf')

  return (
    <div className="App">
      <Canvas style={{ height: '100vh', width: '100vw' }}>
        <Suspense>
          <pointLight color="#f6f3ea" position={[10, 5, 10]} intensity={2} />
          <Stars />
          <primitive scale={[0.25, 0.25, 0.25]} object={gltf.scene} />
        </Suspense>
      </Canvas>
    </div>
  )
}

Upvotes: 1

ASG
ASG

Reputation: 29

You mentioned on your comment you put your 3D object files in a folder inside the public folder. You could still have them inside this folder, but you have to specify that when you refer to the glb or gltf file:

const { nodes, materials } = useGLTF('/<path inside public folder>/scene.gltf')

Upvotes: 0

Dilruk R
Dilruk R

Reputation: 11

Please check your console

enter image description here

and if indicates an error of the above type

you need to change in your Scene Component

export function Scene(props){}

to

export default function Scene(props){}

because You need to export it as a default function. your problem is a usual problem for starters that use gltfjsx. I think that answer will help you

Upvotes: 0

Related Questions