0

I wanted to load a 3d object to three.js, so since I'm quite new to that, I started from the very first basic example in the documentation and everything seemed to be ok to me. But then when simply added the import line, following the documentation I couldn't see anymore the scene and I got this error from the console:

(index):1 Uncaught TypeError: Failed to resolve module specifier "three/examples/jsm/loaders/GLTFLoader.js". Relative references must start with either "/", "./", or "../"

I've just copied this line from three.js documentation so I'm not really sure about what is wrong in referencing the loader.

import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

Can you help me understand what's the issue? I'm working on macOS using atom live server for the previw Thank you!

3
  • When installing from npm you always need a bundler to create one single js file. I suggest parceljs.org/getting_started.html Commented Nov 28, 2020 at 16:54
  • Nvm I guess you are hosting file statically with atom live server. I will post an example with <script type="module"> Commented Nov 28, 2020 at 17:08
  • Same topic: stackoverflow.com/questions/64409605/… Commented Nov 28, 2020 at 17:22

1 Answer 1

2

I don't know how your project is organized so you will have to replace {path} or even the file name with the actual static path of the file.

<script type="module">
 import * as THREE from '{path}/three.module.js'
 import { GLTFLoader } from '{path}/GLTFLoader.js'
</script>

If you don't host threejs file just use a CDN

import { GLTFLoader } from 'https://cdn.jsdelivr.net/npm/three/examples/jsm/loaders/GLTFLoader.js'

EDIT

NPM and serving files with any kind of server extension is something you need to understand clearly and is not something that works out of the box. I suggest that you create a single index.html file and run it directly on the browser.

As an example I've replaced every file access with a CDN link. First run is slow after that the model is in cache.

    <!DOCTYPE html>
<html lang="en">
    <head>
        <title>three.js webgl - glTF loader</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <link type="text/css" rel="stylesheet" href="https://ghcdn.rawgit.org/mrdoob/three.js/dev/examples/main.css">
    </head>

    <body>
        <div id="info">
            <a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - GLTFLoader<br />
            Battle Damaged Sci-fi Helmet by
            <a href="https://sketchfab.com/theblueturtle_" target="_blank" rel="noopener">theblueturtle_</a><br />
            <a href="https://hdrihaven.com/hdri/?h=royal_esplanade" target="_blank" rel="noopener">Royal Esplanade</a> by <a href="https://hdrihaven.com/" target="_blank" rel="noopener">HDRI Haven</a>
        </div>

        <script type="module">

            import * as THREE from 'https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js';

            import { OrbitControls } from 'https://cdn.jsdelivr.net/npm/three/examples/jsm/controls/OrbitControls.js';
            import { GLTFLoader } from 'https://cdn.jsdelivr.net/npm/three/examples/jsm/loaders/GLTFLoader.js';
            import { RGBELoader } from 'https://cdn.jsdelivr.net/npm/three/examples/jsm/loaders/RGBELoader.js';
            import { RoughnessMipmapper } from 'https://cdn.jsdelivr.net/npm/three/examples/jsm/utils/RoughnessMipmapper.js';

            let camera, scene, renderer;

            init();
            render();

            function init() {

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

                camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 20 );
                camera.position.set( - 1.8, 0.6, 2.7 );

                scene = new THREE.Scene();

                new RGBELoader()
                    .setDataType( THREE.UnsignedByteType )
                    .setPath( 'https://ghcdn.rawgit.org/mrdoob/three.js/dev/examples/textures/equirectangular/' )
                    .load( 'royal_esplanade_1k.hdr', function ( texture ) {

                        const envMap = pmremGenerator.fromEquirectangular( texture ).texture;

                        scene.background = envMap;
                        scene.environment = envMap;

                        texture.dispose();
                        pmremGenerator.dispose();

                        render();

                        // model

                        // use of RoughnessMipmapper is optional
                        const roughnessMipmapper = new RoughnessMipmapper( renderer );

                        const loader = new GLTFLoader().setPath( 'https://ghcdn.rawgit.org/mrdoob/three.js/dev/examples/models/gltf/DamagedHelmet/glTF/' );
                        loader.load( 'DamagedHelmet.gltf', function ( gltf ) {

                            gltf.scene.traverse( function ( child ) {

                                if ( child.isMesh ) {

                                    // TOFIX RoughnessMipmapper seems to be broken with WebGL 2.0
                                    // roughnessMipmapper.generateMipmaps( child.material );

                                }

                            } );

                            scene.add( gltf.scene );

                            roughnessMipmapper.dispose();

                            render();

                        } );

                    } );

                renderer = new THREE.WebGLRenderer( { antialias: true } );
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                renderer.toneMapping = THREE.ACESFilmicToneMapping;
                renderer.toneMappingExposure = 1;
                renderer.outputEncoding = THREE.sRGBEncoding;
                container.appendChild( renderer.domElement );

                const pmremGenerator = new THREE.PMREMGenerator( renderer );
                pmremGenerator.compileEquirectangularShader();

                const controls = new OrbitControls( camera, renderer.domElement );
                controls.addEventListener( 'change', render ); // use if there is no animation loop
                controls.minDistance = 2;
                controls.maxDistance = 10;
                controls.target.set( 0, 0, - 0.2 );
                controls.update();

                window.addEventListener( 'resize', onWindowResize, false );

            }

            function onWindowResize() {

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

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

                render();

            }

            //

            function render() {

                renderer.render( scene, camera );

            }

        </script>

    </body>
</html>
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer, for the three.js file, I put it directly in my file folder, and I installed three.js using npm in the folder project. I don't know if the right way to do it but to be honest, I've been having some hard time figuring out how to import/reference things in three.js rather than understanding how it actually works

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.