1

https://www.youtube.com/watch?v=1TeMXIWRrqE

<!DOCTYPE html>
<html>
<head>
 <title>Three.js</title>
 <style type="text/css">
  html, body {margin: 0; padding: 0; overflow: hidden}
 </style>
</head>
<body>
  <div id="webgl"></div>
 <script src="three.js"></script>
    <script src="GLTFLoader.js"></script>
 <script>
        
    let scene,camera,renderer;
    function init(){
    scene = new THREE.Scene();
    scene.background = new THREE.Color(0xdddddd);
    
    camera = new THREE.PerspectiveCamera(40,window.innerWidth/window.innerHeight,1,5000);
    
    hlight = new THREE.AmbientLight(0x404040,100);
    scene.add(hlight);
    
    renderer = new THREE.WebGLRenderer({antialias:true});
    renderer.setSize(window.innerWidth,window.innerHeight);
    document.getElementById('webgl').appendChild(renderer.domElement);
    
    let loader = new THREE.GLTFLoader();  //THE ERROR WITH THIS, I TRIED WITHOUT THREE. ONLY GLTLOADER() BUT DID NOT WORK 
    loader.load('scene.gltf', function(gltf){
        scene.add(gltf.scene);
        renderer.render(scene,camera);
    });
}
init();
    </script>
      
</body>
</html>
https://sketchfab.com/3d-models/1972-datsun-240k-gt-non-commercial-use-only-b2303a552b444e5b8637fdf5169b41cb //https://www.youtube.com/watch?v=1TeMXIWRrqE This is tutorial for GLTFLOADER , i imported same 3d file as well and written same code, but when i open the file on local server, i get 2 errors in console: 1) "GLTFLoader.js:9 Uncaught SyntaxError: Cannot use import statement outside a module" 2) "(index):29 Uncaught TypeError: THREE.GLTFLoader is not a constructor." Although in youtube video it opens with him immediatly!! :( I would be greatful if anybody can hep me out with this. THANK YOU SO MUCH

GLTFLoader.js:9 Uncaught SyntaxError GLTFLoader.js:9 Uncaught SyntaxError

(index):29 Uncaught TypeError (index):29 Uncaught TypeError

gman
  • 100,619
  • 31
  • 269
  • 393
mash
  • 23
  • 1
  • 1
  • 3

2 Answers2

5

Here's a newer tutorial. The bottom of this article explains what changed.

The short version is three.js changed to prefer using es6 modules so instead of

<script src="three.js"></script>
<script src="GLTFLoader.js"></script>
<script>

let scene,camera,renderer;
function init(){
  ...
  THREE.GLTFLoader.load(...

you'd do this

<script type="module">
import * as THREE from './build/three.module.js';
import {GLTFLoader} from './examples/jsm/loaders/GLTFLoader.js';

let scene,camera,renderer;
function init(){
  ...
  GLTFLoader.load(...

But to use it like that requires you copy the three.js files to the same folder structure.

someFolder
 |
 ├-build
 | |
 | +-three.module.js
 |
 +-examples
   |
   +-jsm
     |
     +-controls
     | |
     | +-OrbitControls.js
     | +-TrackballControls.js
     | +-...
     |
     +-loaders
     | |
     | +-GLTFLoader.js
     | +-...
     |
     ...

If you want to use the old method <script> tag style then you need to make sure you use the files from the js folder, not the jsm folder

Note: You must use this folder structure because the files in the examples/jsm folder like GLTFLoader.js refer to various other files like three.module.js via relative but hard coded paths. For example in GLTFLoader.js there is a line which is effectively

import {stuff} from "../../../build/three.module.js";

A couple of advantages to the new style are

  1. the various modules can pull in the other parts they need.

    In the past to use one extra part you might need to add 1 to 10 other <script> tags. Now you just need 1 import and that part can pull in the other 1 to 10 parts on it's own

  2. If you build your page with a web builder it can strip out the parts you are not using.

Rumor is there are plans to get rid of the <script> method completely at some point in the future.


Just to try to make it clear both why ES6 modules are better and why you need to keep the same structure.

In pre r105 to use the EffectComposer you'd do this

<script src="threejs/examples/js/postprocessing/EffectComposer.js"></script>

You run and you'd get an error

THREE.EffectComposer relies on THREE.CopyShader

So you'd dig around to find it, it's not in the same folder as EffectsComposer.js. When you finally find it you add it

<script src="threejs/examples/js/postprocessing/EffectComposer.js"></script>
<script src="threejs/examples/js/shaders/CopyShader.js"></script>

Run again and get another error THREE.EffectComposer relies on THREE.ShaderPass so again digging around you add that

<script src="threejs/examples/js/postprocessing/EffectComposer.js"></script>
<script src="threejs/examples/js/shaders/CopyShader.js"></script>
<script src="threejs/examples/js/postprocessing/ShaderPass.js"></script>

That sucked.

Now as of r105 using es6 modules you can just do

import {EffectComposer} from './threejs/examples/jsm/postprocessing/EffectComposer.js';

Which is arguably much nicer. You won't get the other errors because the ES6 module version EffectComposer.js can reference the files it needs, its dependencies, itself. At the top of EffectComposer.js are the references to its dependencies.

import {
    Clock,
    LinearFilter,
    Mesh,
    OrthographicCamera,
    PlaneBufferGeometry,
    RGBAFormat,
    Vector2,
    WebGLRenderTarget
} from "../../../build/three.module.js";
import { CopyShader } from "../shaders/CopyShader.js";
import { ShaderPass } from "../postprocessing/ShaderPass.js";
import { MaskPass } from "../postprocessing/MaskPass.js";
import { ClearMaskPass } from "../postprocessing/MaskPass.js";

But, as you can see above, EffectsComposer.js expects that three.module.js is in a folder called build 3 subfolders down from itself. It expects CopyShader.js is in a folder called shaders one folder down from itself. Etc...

In other words, it needs the same folder structure.

gman
  • 100,619
  • 31
  • 269
  • 393
  • You can also be sarcastic in hopes to diminish someone's valid and accurate point. However, as long as you understand what's happening under the hood. You'll always be able to reason and decide what is best and preferable for your use-case. – ScieCode May 11 '20 at 09:32
  • I haven't removed any comments and I have no ability to do so even if I wanted to which I don't. You're fully entitled to change three.js however you want. Rename `Mesh` to `Foobar`. Cut out the parts you don't want. Refactor it into something else. Most people choose to use it as and as is it requires a certain folder structure. I have no idea why that is such an issue for you but you're entitled to your opinion and to create more work for yourself. – gman May 11 '20 at 17:14
  • You keep deviating what I said, because you cannot accept a different perspective. I never said to change Three.js core, like `Mesh`, I never even said to change the example file implementation, although you can do that as well. All I said is that anyone can and should change module import paths to what fits with their liking. Three.js collaborators always stated that example files are but that, example files. Users don't need to use them as they are, they are meant to be reference, they are meant to be adapted. Changing the module import path is nothing but what is expected. – ScieCode May 11 '20 at 17:23
0

I faced a similar issue, this is how I solved it.

In your HTML, the order matters when adding other scripts as it needs certain things from Three.js.

It should be

   <script src="../build/three.min.js"></script>
   <script src="three.js-master/examples/js/controls/OrbitControls.js"></script>
   <script src="three.js-master/examples/js/loaders/GLTFLoader.js"></script>

I would suggest trying to import from your local javascript folder instead of using from jsm. I hope this will solve your issue.

Mahyar Mottaghi Zadeh
  • 1,178
  • 6
  • 18
  • 31