Loading mesh(OBJ+MTL+JPG) with react-three-fiber, Texture is not working

Viewed 4071

In my react app, I am trying to make a view page which shows 3d-mesh exported from pix4d. This mesh consists of three types of files, (.obj, .mtl, .jpg) pix4d.com.

I am new, with react-three-fiber, which I suppose is best way to achieve my solution to my problem.

Below is whole code of react component used to load and render 3D-Model.

code

Thanks in Advance!

I want to understand how to attach texture & material to my obj rendered model.

2 Answers

I was looking for this answer for a couple of weeks, finally I've found a way to make it work.

Material loader is not resolving by itself the import of remote files (it does on web, not in mobile, maybe in the future it will). So, I'm creating material and assigning it images by hand.

Something like this:

import { TextureLoader } from 'expo-three';
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
// useThree is used to get scene reference
import { useThree } from 'react-three-fiber';

const textureLoader = new TextureLoader();
const mapImage = textureLoader.load(require('path/to/image1.png'))
const normalMapImage = textureLoader.load(require('path/to/image2.png'))

Note that TextureLoader from expo-three can handle the file resource returned from require()

const loaderObj = new OBJLoader();
const loaderMtl = new MTLLoader();

export default props => {
  const { scene } = useThree();

  loaderMtl.load(
    'https://url_to/material.mtl',
    mtl => {
      mtl.preload();

      loaderObj.setMaterials(mtl);
      loaderObj.load(
        'https://url_to/model.obj',
        obj => {
          // simple logic for an obj with single child
          obj.children[0].material.map = mapImage;
          obj.children[0].material.normalMap = normalMapImage;

          scene.add(obj)
        }
      )
    }
  )

  return null;
}

This is my first successful attempt to render an obj with mtl including a map and a normal map, so since it works, we can keep updating the code for improvements.

Another way to load model with texture is by specifying the path where your texture has been stored. In one case, mtl + obj + texture files are stored in your react project's directory 'public/models/'. So you can specify the path by calling setPath() function prior loading your material or object file and it should load your texture on the material. You may also want to make sure that in ./mtl file the texture name is correct. It should be called following by map_Kd in .mtl file.

const Model = () => {
  const materialLoader = new MTLLoader().setPath('./model/').load(MaterialFile);
  const objLoader = new OBJLoader().setMaterials(materialLoader).load(OojectFile);
  return <primitive object={objLoader} />;
};
Related