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!

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
baband
  • 123
  • 12

1 Answers1

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/three@0.123.0/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>
user2258152
  • 635
  • 5
  • 13
  • 1
    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 – baband Nov 28 '20 at 17:37