Search code examples
typescriptnext.jsthree.jsreact-three-fiberreact-three-drei

How to set side={THREE.BackSide} with external .glb file?


I'm new with Threejs. I want to use side="THREE.BackSide" with external model file room.glb file. I'm using nextjs 13 (typescript and app directory enabled) with @react-three/fiber and react-three/drei.

It works like this

<Canvas>
    
  <OrbitControls enableZoom dampingFactor={0.01}/>
  <mesh scale={[1,5,9]}>
  <boxGeometry  />
  <meshStandardMaterial color="grey" side={THREE.BackSide} />
  </mesh> 
  <ambientLight intensity={1}/>
  <pointLight intensity={5} position={[10,90,0]}/>
  </Canvas>

but when I try to do this by loading some external file like:

<Canvas>
      <OrbitControls enableZoom dampingFactor={0.009} enableRotate maxAzimuthAngle={0} maxPolarAngle={1.5} minPolarAngle={1} maxDistance={10} minAzimuthAngle={0.5}/>
    <mesh  scale={[depth/18,height/18,width/18]}>
      <primitive object={gltf.scene} ref={meshRef}/>
      <meshStandardMaterial color={"red"} side={THREE.BackSide}/>
    <ambientLight intensity={1}/>
    <pointLight intensity={5} position={[10,90,0]}/>
    </Canvas>

it simply doesn't work.

I tried using gltfjsx cli to convert my .glb file into jsx but it doesn't work. I dont know how can I loop through all nodes and set their side prop to BackSide.

gltfjsx file:

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

type GLTFResult = GLTF & {
  nodes: {
    Cube: THREE.Mesh
  }
  materials: {
    ['Material.001']: THREE.MeshStandardMaterial
  }
}

export function Model(props: JSX.IntrinsicElements['group']) {
  const { nodes, materials } = useGLTF('/labRoom.glb') as GLTFResult
  return (
    <group {...props} dispose={null}>
      <mesh geometry={nodes.Cube.geometry} material={materials['Material.001']} scale={[2.52, 2.64, 2.49]}/>
    </group>
  )
}

useGLTF.preload('/labRoom.glb')```

Solution

  • Updating your gltfjsx output to do something like this ought to be enough:

    <group {...props} dispose={null}>
      <mesh geometry={nodes.Cube.geometry} 
        material={materials['Material.001']}
        material-side={THREE.BackSide}
        scale={[2.52, 2.64, 2.49]}/>
    </group>
    

    Alternatively, the materials object is just a plain javascript object, you can loop over it too:

    for (let key in materials) {
      materials[key].side = THREE.BackSide;
    }