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.
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.
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:
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/
so extra light setting are required, other wise it will look dark.?
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.