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
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
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.