Error when using OBJLoader to load OBJ Model

I am trying to load a OBJ model to display in browser but I keep getting this error:
“Three.js:24086 Uncaught TypeError: Cannot read property ‘getUniforms’ of undefined”.

Code:

<!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta http-equiv="X-UA-Compatible" content="IE=edge">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Document</title>

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

</head>

<body>

    <h1>cool beans</h1>

    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/102/three.js"></script> -->

    <script src="Three.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.2/TweenMax.min.js"></script>

    <script type = "module">

        import {OBJLoader} from '/OBJLoader.js';

        import { MTLLoader } from '/MTLLoader.js';

        var scene = new THREE.Scene();

        var meshX;

        var camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000);

        camera.position.z = 10;

/*         camera.up = new THREE.Vector3(0,0,1);

        camera.lookAt(10,10,10); */

        var renderer = new THREE.WebGLRenderer({antialias: true});

        renderer.setClearColor("#e5e5e5");

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

        document.body.appendChild(renderer.domElement);

        // make renderer size and aspect ratio of camera responsive to browser size

        window.addEventListener('resize', () => {

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

            camera.aspect = window.innerWidth / window.innerHeight;

            camera.updateProjectionMatrix();

        })

        // instantiate a loader

        const loader = new OBJLoader();

        // load a resource

        loader.load(

            // resource URL

            'Solid1.obj',

            // called when resource is loaded

            function ( object ) {

                scene.add( object );

            },

            // called when loading is in progresses

            function ( xhr ) {

                console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );

            },

            // called when loading has errors

            function ( error ) {

                console.log( 'An error happened' );

            }

        );

        var raycaster = new THREE.Raycaster();

        var mouse = new THREE.Vector2();

        var geometry = new THREE.BoxGeometry(1, 1, 1); // x, y, z scale

        var material = new THREE.MeshLambertMaterial({color: 0xF7F7F7});

        /* var mesh = new THREE.Mesh(geometry, material); */

        /* mesh.position.set(2,2,-2); // x y z 

        mesh.rotation.set(45,0,0);

        mesh.scale.set(1,2,1); */

        

        /* scene.add(mesh); */

        meshX = -10;

        for(var i = 0; i < 15; i++){

            var mesh = new THREE.Mesh(geometry, material);

            mesh.position.x = (Math.random() - 0.5) * 10;

            mesh.position.y = (Math.random() - 0.5) * 10;

            mesh.position.z = (Math.random() - 0.5) * 10;

            scene.add(mesh);

            meshX += 1;

        }

        var light = new THREE.PointLight(0xFFFFFF, 1, 1000); //color , intensity, distance

        light.position.set(0,0,0); // x , y , z

        scene.add(light);

        var light = new THREE.PointLight(0xFFFFFF, 2, 1000);

        light.position.set(0,0,25); // x , y , z

        scene.add(light);

        var render = function(){

            requestAnimationFrame(render); //to fix the scaling of object so that it doesnt become smaller on resize

            renderer.render(scene,camera);

        }

        // when hovered/click over object (depends on event you are listening to)

        function onMouseMove(event){

            event.preventDefault();

            mouse.x = (event.clientX / window.innerWidth ) * 2 - 1;

            mouse.y = - (event.clientY / window.innerHeight) * 2 + 1;

            raycaster.setFromCamera(mouse, camera);

            var intersects = raycaster.intersectObjects(scene.children, true);

            for (var i = 0; i < intersects.length; i++){

                this.tl = new TimelineMax();

                this.tl.to(intersects[i].object.scale, 1, {x: 2, ease: Expo.easeOut}); // (reference mesh and scale, duration, scale on x axis and set ease)

                this.tl.to(intersects[i].object.scale, 0.5, {x: 0.5, ease: Expo.easeOut});

                this.tl.to(intersects[i].object.position, 0.5, {x: 2, ease: Expo.easeOut});

                this.tl.to(intersects[i].object.rotation, 0.5, {y: Math.PI*0.5, ease: Expo.easeOut}, "=-1.5"); // happens 1.5 seconds before it normally would

                /* intersects[i].object.material.color.set(0xff0000); */

            }

        }

        render();

        // this part is using the twinmax imported stuff (we imported it below the three.js part)

               

        window.addEventListener('mousemove',onMouseMove);

        /* document.body.addEventListener('click', () => {

            this.tl.play();

        }) */

    </script>

</body>

</html>

Do you mind sharing the OBJ Solid1.obj in this thread?

Here you go

Solid1.obj (43.5 KB)
Solid1.mtl (1.4 KB)

I have replaced the OBJ/MTL asset in three.js webgl - OBJLoader + MTLLoader and the model loads and renders without a runtime error.

Full code:

import * as THREE from '../build/three.module.js';

import { MTLLoader } from './jsm/loaders/MTLLoader.js';
import { OBJLoader } from './jsm/loaders/OBJLoader.js';

let camera, scene, renderer;

init();
animate();


function init() {

	const container = document.createElement( 'div' );
	document.body.appendChild( container );

	camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 20 );
	camera.position.set( 2, 0, 2 );

	// scene

	scene = new THREE.Scene();
	camera.lookAt( scene.position );

	const ambientLight = new THREE.AmbientLight( 0xcccccc, 0.4 );
	scene.add( ambientLight );

	const pointLight = new THREE.PointLight( 0xffffff, 0.8 );
	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' );

		}

	};

	const onError = function () { };

	new MTLLoader()
		.setPath( 'models/obj/' )
		.load( 'Solid1.mtl', function ( materials ) {

			materials.preload();

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

					scene.add( object );

				}, onProgress, onError );

		} );

	//

	renderer = new THREE.WebGLRenderer();
	renderer.setPixelRatio( window.devicePixelRatio );
	renderer.setSize( window.innerWidth, window.innerHeight );
	container.appendChild( renderer.domElement );

	//

	window.addEventListener( 'resize', onWindowResize );

}

function onWindowResize() {

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

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

}

//

function animate() {

	requestAnimationFrame( animate );
	render();

}

function render() {

	renderer.render( scene, camera );

}

When I try to view in browser, I receive this error:

index.html:64 Uncaught ReferenceError: manager is not defined
at init (index.html:64)
at index.html:25

It is referring to this part

new MTLLoader( manager )

    .setPath( 'models/obj/' )

    .load( 'Solid1.mtl', function ( materials ) {

        materials.preload();

        new OBJLoader( manager )

            .setMaterials( materials )

            .setPath( 'models/obj/' )

            .load( 'Solid1.obj', function ( object ) {

                scene.add( object );

            }, onProgress, onError );

    } );

Please try it again with the updated code. There was a copy/paste error.

Ah it works fine now. thanks!

1 Like