New to ThreeJS - Can't load Obj file

I’m using the following code to try and load an MTL and obj file - the index.html code is attached below. I made the file on blender. I also tried loading simpler files onto threejs and I still didn’t see anything on my browser. Not sure what I’m doing wrong.

three.js webgl - OBJLoader + MTLLoader
<body>
	<div id="info">
	<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - OBJLoader + MTLLoader
	</div>

	<!-- Import maps polyfill -->
	<!-- Remove this when import maps will be widely supported -->
	<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

	<script type="importmap">
		{
			"imports": {
				"three": "../build/three.module.js",
				"three/addons/": "./jsm/"
			}
		}
	</script>

	<script type="module">

		import * as THREE from 'three';

		import { MTLLoader } from 'three/addons/loaders/MTLLoader.js';
		import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
		import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

		let camera, scene, renderer;

		init();
		animate();


		function init() {

			camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 20 );
			camera.position.z = 2.5;

			// scene

			scene = new THREE.Scene();

			const ambientLight = new THREE.AmbientLight( 0xffffff );
			scene.add( ambientLight );

			const pointLight = new THREE.PointLight( 0xffffff, 15 );
			camera.add( pointLight );
			scene.add( camera );

			// model

			const onProgress = function ( xhr ) {

				if ( xhr.lengthComputable ) {

					const percentComplete = xhr.loaded / xhr.total * 100;
					console.log( Math.round( percentComplete, 2 ) + '% downloaded' );

				}

			};

			new MTLLoader()
				.setPath( '/room' )
				.load( 'roomnight.mtl', function ( materials ) {

					materials.preload();

					new OBJLoader()
						.setMaterials( materials )
						.setPath( '/room' )
						.load( 'roomnight.obj', function ( object ) {

							object.position.y = - 0.95;
							object.scale.setScalar( 0.01 );
							scene.add( object );

						}, onProgress );

				} );

			//

			renderer = new THREE.WebGLRenderer( { antialias: true } );
			renderer.setPixelRatio( window.devicePixelRatio );
			renderer.setSize( window.innerWidth, window.innerHeight );
			document.body.appendChild( renderer.domElement );

			//

			const controls = new  OrbitControls( camera, renderer.domElement );
			controls.minDistance = 2;
			controls.maxDistance = 5;

			//

			window.addEventListener( 'resize', onWindowResize );

		}

		function onWindowResize() {

			camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();

			renderer.setSize( window.innerWidth, window.innerHeight );

		}

		//

		function animate() {

			requestAnimationFrame( animate );
			renderer.render( scene, camera );
		
		}


	</script>

</body>

Is there any error message in the JS console?

I keep getting this message but nothing loads on my window:
“GET /” “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36”

Would it be possible to share the OBJ and the MTL file? I’m just curious whether if I load them locally the model will show up.

PS. Sometimes models are not visible if they are too small, or too big, or too near, or too far, or behind the camera, or have the same color as the background, or the material/light conditions are not good, etc

Sure! I tried using these test files for MTL and OBJ first to see if it would even render on my computer and it didn’t.
RobotoMono-Regular.woff2 (10.4 KB)
male02.mtl (1.1 KB)
male02.obj (453.7 KB)
favicon
index.html (3.1 KB)
main.css (11.2 KB)

So, here is the result (see comments below):

Comments:

  • Lines 21-24: The import maps were incorrect. I replaced them with these:
"imports": {
	"three": "https://unpkg.com/three@0.155.0/build/three.module.js",
	"three/addons/": "https://unpkg.com/three@0.155.0/examples/jsm/"
}

  • Lines 72 and 79: Changed both setPaths from '/male' to 'male/' (I think your MTL+OBJ files are in folder 'male', right?):
.setPath( 'male/' )
:
.setPath( 'male/' )
  • Line 54: Increased the light intensity from 15 to 1500:
const pointLight = new THREE.PointLight( 0xffffff, 1500 );

Additional comments:

  • You did not send me the textures, that’s why the image here is black-and-white
  • After loading the model reduce the metalness of all meshes (this will make the colors more natural, not so shiny and metalic)

Thank you so much!! I made those changes in my code. The only thing is I get this screen when I try to load it. Could you maybe let me know how you load it locally - I’m not sure if that’s where I’m messing up.

I don’t know your folder structure.

The browser’s JS console may contain some error messages. What does it say?

This is the folder structure and the error messages
structure
errors

Most likely the import map is missing braces. Here is the full section:

<script type="importmap">
{
	"imports": {
		"three": "https://unpkg.com/three@0.155.0/build/three.module.js",
		"three/addons/": "https://unpkg.com/three@0.155.0/examples/jsm/"
	}
}
</script>
1 Like

It worked!!! Thank you so so much!!!

1 Like

Not work

three.js webgl - OBJLoader + MTLLoader
	<meta name="viewport" content="width=device-width, initial-scale=1">

	<link type="text/css" rel="stylesheet" href="main.css">
</head>

<body>
	<div id="info">
	<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - OBJLoader + MTLLoader
	</div>

	<!-- Import maps polyfill -->
	<!-- Remove this when import maps will be widely supported -->
	<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

	
		

	<script type="importmap">
		{
			"imports": {
				"three": "https://unpkg.com/three@0.155.0/build/three.module.js",
				"three/addons/": "https://unpkg.com/three@0.155.0/examples/jsm/"
			}
		}
		</script>

	<script type="module">

		import * as THREE from 'three';

		import { MTLLoader } from 'three/addons/loaders/MTLLoader.js';
		import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
		import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

		let camera, scene, renderer;

		init();
		animate();


		function init() {

			camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 20 );
			camera.position.z = 2.5;

			// scene

			scene = new THREE.Scene();

			const ambientLight = new THREE.AmbientLight( 0xffffff );
			scene.add( ambientLight );

			
			const pointLight = new THREE.PointLight( 0xffffff, 1500 );
			camera.add( pointLight );
			scene.add( camera );

			// model

			const onProgress = function ( xhr ) {

				if ( xhr.lengthComputable ) {

					const percentComplete = xhr.loaded / xhr.total * 100;
					console.log( Math.round( percentComplete, 2 ) + '% downloaded' );

				}

			};

			new MTLLoader()
				.setPath( 'male' )
				.load( 'male02.mtl', function ( materials ) {

					materials.preload();

					new OBJLoader()
						.setMaterials( materials )
						.setPath( 'male' )
						.load( 'male02.obj', function ( object ) {

							object.position.y = - 0.95;
							object.scale.setScalar( 0.01 );
							scene.add( object );

						}, onProgress );

				} );

			//

			renderer = new THREE.WebGLRenderer( { antialias: true } );
			renderer.setPixelRatio( window.devicePixelRatio );
			renderer.setSize( window.innerWidth, window.innerHeight );
			document.body.appendChild( renderer.domElement );

			//

			const controls = new OrbitControls( camera, renderer.domElement );
			controls.minDistance = 2;
			controls.maxDistance = 5;

			//

			window.addEventListener( 'resize', onWindowResize );

		}

		function onWindowResize() {

			camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();

			renderer.setSize( window.innerWidth, window.innerHeight );

		}

		//

		function animate() {

			requestAnimationFrame( animate );
			renderer.render( scene, camera );
		
		}


	</script>

</body>

The code you posted is missing the top part <!DOCTYPE html> and <head> and the path you used is slightly incorrect.

Here is the code that works:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link type="text/css" rel="stylesheet" href="main.css">
</head>

<body>
	<div id="info">
	<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - OBJLoader + MTLLoader
	</div>

	<!-- Import maps polyfill -->
	<!-- Remove this when import maps will be widely supported -->
	<script async src="https://unpkg.com/es-module-shims@1.6.3/dist/es-module-shims.js"></script>

	
		

	<script type="importmap">
		{
			"imports": {
				"three": "https://unpkg.com/three@0.155.0/build/three.module.js",
				"three/addons/": "https://unpkg.com/three@0.155.0/examples/jsm/"
			}
		}
		</script>

	<script type="module">

		import * as THREE from 'three';

		import { MTLLoader } from 'three/addons/loaders/MTLLoader.js';
		import { OBJLoader } from 'three/addons/loaders/OBJLoader.js';
		import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

		let camera, scene, renderer;

		init();
		animate();


		function init() {

			camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 20 );
			camera.position.z = 2.5;

			// scene

			scene = new THREE.Scene();

			const ambientLight = new THREE.AmbientLight( 0xffffff );
			scene.add( ambientLight );

			
			const pointLight = new THREE.PointLight( 0xffffff, 150 );
			camera.add( pointLight );
			scene.add( camera );

			// model

			const onProgress = function ( xhr ) {

				if ( xhr.lengthComputable ) {

					const percentComplete = xhr.loaded / xhr.total * 100;
					console.log( Math.round( percentComplete, 2 ) + '% downloaded' );

				}

			};

			new MTLLoader()
				.setPath( './male/' )
				.load( 'male02.mtl', function ( materials ) {

					materials.preload();

					new OBJLoader()
						.setMaterials( materials )
						.setPath( './male/' )
						.load( 'male02.obj', function ( object ) {

							object.position.y = - 0.95;
							object.scale.setScalar( 0.01 );
							scene.add( object );

						}, onProgress );

				} );

			//

			renderer = new THREE.WebGLRenderer( { antialias: true } );
			renderer.setPixelRatio( window.devicePixelRatio );
			renderer.setSize( window.innerWidth, window.innerHeight );
			document.body.appendChild( renderer.domElement );

			//

			const controls = new OrbitControls( camera, renderer.domElement );
			controls.minDistance = 2;
			controls.maxDistance = 5;

			//

			window.addEventListener( 'resize', onWindowResize );

		}

		function onWindowResize() {

			camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();

			renderer.setSize( window.innerWidth, window.innerHeight );

		}

		//

		function animate() {

			requestAnimationFrame( animate );
			renderer.render( scene, camera );
		
		}


	</script>

</body>
</html>

I did lower the point light intensity since it was too bright.

1 Like

Yes it should work. Did all set upp complet. What can possebly be wrong?

The page cannot be used alone, you have to use a server that can serve the files.

If you want a page that is standalone then your path should point to three.js repository, just like in the attached file.

OBJ+MTL Loading - Standalone.zip (1.4 KB)

1 Like

Thanx thats also what i did. And similar projects as well.
I realy like your model work on your sight.

1 Like

Don’t hesitate to star my repository if you can.

Remember that it is a digital star which costs nothing and is just a click away - it might just suggest to other people that there is something useful and FREE in my repository.

I don’t really aim for or expect to ever reach the number of stargazers that three.js repository has.

HI
Do you have some sample code to a model?