.obj and .fbx 3d looks black when use RGBELoader

I am trying to render obj and fbx model just like, gltf is getting rendered using RGBELoader.
GLTF models are rendering fine.
But obj/fbx model are rendering black and if we provide any external light settings, then the 3d object shows its textures, otherwise it renders black.
I am using venice_sunset_1k.hdr and code is similar to https://github.com/mrdoob/three.js/blob/cf836bbb074da979bc5eb8f131440bb4341350c1/examples/webgl_loader_gltf.html just replaced the loader part, for obj/fbx.

Scene.environment is only applied to PBR materials. Since FBX and OBJ loaders do not return PBR materials, the parsed 3D objects are not affected by Scene.environment.

You can easily fix this by applying the environment map to the envMap property of your materials. However, the environment map produces by PMREM does only properly work with PBR materials. So you might want to consider to replace all materials from the OBJ and FBX asset with MeshStandardMaterial.

ok thanks for the reply. But after adding envmap to material, 3d model is not rendering and canvas is white. What change should I do???
this is my code

new RGBELoader()
    .setDataType( THREE.UnsignedByteType )
    .setPath( './' )
    .load( 'venice_sunset_1k.hdr', ( texture )=> {
      this.envMap = pmremGenerator.fromCubemap( texture ).texture;
     this.scene.background = this.envMap;
      this.scene.environment = this.envMap;
      texture.dispose();
      pmremGenerator.dispose();
      this.animate();

      // model
           var mtl = new MTLLoader();
           var objl = new OBJLoader();
          mtl.setPath("./sketchfab obj/")  
          .load("3Dobj.mtl ", materials => { 
          materials.preload();    
          objl.setMaterials(materials).setPath("./sketchfab obj/") 
            .load("3Dobj.obj",object => {
           object.traverse( function ( obj ) {
               if ( obj.isMesh ) {
                     obj.castShadow = true;
                     obj.receiveShadow = true;
                    obj.material.envMap = this.envMap;
                }
            });});});
       this.animate();
      });


    this.renderer = new THREE.WebGLRenderer({
      antialias: true
    });
    this.renderer.setSize(this.width, this.height);
    this.renderer.outputEncoding = THREE.sRGBEncoding;
    this.renderer.shadowMap.enabled = true;
    this.renderer.shadowMapSoft = true;
    this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    var pmremGenerator = new THREE.PMREMGenerator( this.renderer );
        pmremGenerator.compileCubemapShader();

As I said above, the environment map produced by PMREMGenerator can only be used with PBR materials. MTLLoader does not produce PBR materials.

sorry but I am trying to understand what you said

So you might want to consider to replace all materials from the OBJ and FBX asset with MeshStandardMaterial .

you are suggesting , traversing to obj/fbx model and replacing it with MeshStandardMaterial.??

object.traverse( function ( obj ) {
      if ( obj.isMesh ) {
        if ( obj.material ) 
        {
          const meshMat = new THREE.MeshStandardMaterial().clone(obj);
         meshMat.envMap = this.envMap;
          obj.material = meshMat;
          
        }
        obj.castShadow = true;
       obj.receiveShadow = true;
    }
} );

getting warning
THREE.FBXLoader: AmbientColor map is not supported in three.js, skipping texture.
so textures are not rendering on the model.

This statement looks not correct. Why do you create a new material and then clone it? Also passing the 3D object to the clone method does not make sense.

It’s maybe best if you completely avoid OBJ and FBX and focus on the more modern glTF instead.

1 Like

yes but we had a requirement to use obj-mtl and fbx model and need to use Image based lighting on that.

Try to create the PBR material just like so:

const meshMat = new THREE.MeshStandardMaterial();

It’s not possible top copy between different material types. So if you want to copy over existing material properties (like textures), you have to to it manually.

This warning can be ignored. It is not responsible for your rendering issues.

1 Like

Well, it’s just code like:

meshMat.color.copy( obj.material.color );
meshMat.map = obj.material.map;

You do this for all relevant material properties.

obj-mtl/fbx loader uses MeshPhongMaterial which does not support IBL. If we had to change material, we have to do it at the loading time of the 3D object.

mtl loader line 490
this.materials[ materialName ] = new MeshPhongMaterial( params );

obj loader line 810
material = new MeshPhongMaterial();

So why cant in the library, other materials are not provided??
Can we do that, by changing material in library??

Answered you at stackoverflow:

1 Like

so can we achieve IBL(using .hdr) without using pmremgenerator for obj-mtl/fbx??

You can already do this. Here is an example with an HDR equirect env map: https://jsfiddle.net/a471r0e8/

1 Like

so extra light setting are required, other wise it will look dark.? :thinking:
I assumed in IBL, we dont provide or there is no need, of any extra lights to the 3d model.

Unfortunately, the way shaders are implemented for MeshPhongMaterial, a light is required. It’s not a PBR material.