0

I am working on a project in react and I'm trying to change the texture of a mesh I'm working with but I am having trouble accessing the material property. Whenever I log the object to console I can see the material property but I cannot access it by 'mesh.material'. Anyone familiar with this issue?

import React, { useMemo } from 'react';
import { useGLTF, useTexture } from 'drei';
import modelConfig from '../../config/model.config';
    const gltfModel = useGLTF(modelConfig.path.meshes, true);
    gltfModel.scene.castShadow = true;
    gltfModel.scene.receiveShadow = true;
    const mesh = gltfModel.scene.getObjectByName("Floor")
    console.log(mesh);
Son Of Earth
  • 13
  • 1
  • 1
  • 5
  • i suggest you try https://github.com/pmndrs/gltfjsx this will also teach you how to properly change props. it creates a virtual jsx scene graph which you can now alter without have to query. btw scenes do not have castshadow/receiveshadow - only meshes have that. – hpalu Mar 10 '21 at 16:29

2 Answers2

0

useGLTF is async so you will have to access it in a react state callback such as useEffect

try adding

useEffect(() =>{
 gltfModel.scene.castShadow = true;
 gltfModel.scene.receiveShadow = true;
 const mesh = gltfModel.scene.getObjectByName("Floor")
});

while the useGLTF is still outside before the useEffect

Epiczzor
  • 377
  • 2
  • 13
  • this is not accurate. useGLTF is synchronous, next line after useGLTF can access all meshes, materials and so on. that's because it uses react.suspense which literally halts the component execution until the async op is completed. – hpalu Mar 10 '21 at 16:31
0

In most examples on the internet I found people were using mesh.material to access the material property. For some reason this was not an option for me so this is the way I did it:

import { useGLTF, useTexture } from 'drei';
import * as THREE from "three";


const gltfModel = useGLTF(modelConfig.path.meshes, true);
const mesh = gltfModel.scene.getObjectByName("Floor")
const texture = new THREE.TextureLoader().load(img);
const material = new THREE.MeshBasicMaterial({ 
            map: texture, 
        });
mesh['material'] = material;
mesh['material'].needsUpdate = true;
Son Of Earth
  • 13
  • 1
  • 1
  • 5