So I'm trying to load a GLTF file and I am receiving this error:
I don't know why it can't locate and open the file. Do I have to set up a local server?
I looked up other examples online and this one includes a DRACOLoader. Admittedly, I don't know what this is for and was wondering if I need to implement this in order for it to load.
Here is my code:
<html>
<head>
<meta charset="utf-8">
<title>Website first attempt</title>
<style>
body { margin: 0;
background: linear-gradient(to bottom, #33ccff 0%, #ffffff 20%);}
canvas { display: block; }
</style>
</head>
<body>
<!-- <script type = "module" src="build/myScript.js"></script>-->
<script type = "module">
import * as THREE from '../build/three.module.js';
import { GLTFLoader } from '../build/GLTFLoader.js';
let scene, camera, renderer, hlight;
function init () {
//scene
scene = new THREE.Scene();
//camera
camera = new THREE.PerspectiveCamera(40, window.innerWidth/ window.innerHeight, 1, 5000);
//light
hlight = new THREE.AmbientLight (0x404040, 100);
scene.add(hlight);
//render
renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setClearColor( 0x000000, 0 );
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//3d
let loader = new GLTFLoader();
loader.load('assets/londonmap.gltf', function(gltf){
scene.add(gltf.scene);
})
}
function onWindowResize () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
window.addEventListener('resize', onWindowResize, false);
function animate () {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render( scene, camera );
}
init ();
animate();
</script>
</body>
</html>
DracoLoader is only necessary if the glTF asset was compressed with the same-named compression algorithm.
A HTTP 404 means that it was not possible to load the file (in your case assets/londonmap.gltf) from the given path. So you have to make sure that the asset is actually present in the respective directory.
And yes, it's highly recommended to work with a local web server. Especially to avoid any security related browser issues. The project actually provides a small guide about this topic: How to run things locally.
Related
I hope that there are some experienced people on this platform who'd be willing to help me with my three.js problem.
My current problem is this, I can't seem to properly run the three.js library on my localhost, all I get is a white screen.
My files:
My Javascript code:
import * as THREE from 'three.js-master/three.js';
import { OrbitControls } from "three.js-master/examples/OrbitControls.js";
const scene = new THREE.Scene(); //generate scene
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); //generate camera
const renderer = new THREE.WebGLRenderer(); //launch renderer using WebGl
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
const controls = new OrbitControls( camera, renderer.domElement );
const animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.05;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
And my HTML code:
<!DOCTYPE html>
<html>
<head>
<title>EMBÄR</title>
<link src="style.css" type="stylesheet">
</head>
<body>
<script src = "three.js" type="module"></script>
<script src="Main.js" type="module"> </script>
</body>
</html>
Now, this just gives a white screen all the time, but I've managed to use the link:
https://unpkg.com/three/build/three.module.js (instead of three.js-master/three.js) in combination with:
https://cdn.jsdelivr.net/npm/three#0.114/examples/jsm/controls/OrbitControls.js (instead of three.js-master/examples/OrbitControls.js)
to successfully run the script, but this really isn't a solution, since I had to search for days to find these links, and it surely isn't efficient if I want to include more modules besides these.
It'd be awesome if someone knew the answer, but please, don't feel pressured to do a lot of research.
Your HTML should look like so:
<!DOCTYPE html>
<html>
<head>
<title>EMBÄR</title>
<link src="style.css" type="stylesheet">
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims#1.3.6/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "./three.js-master/build/three.module.js",
"three/addons/": "./three.js-master/examples/jsm/"
}
}
</script>
<script src="Main.js" type="module"> </script>
</head>
<body>
</body>
</html>
In your Main.js file, use the following imports:
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
The imports in your JS should look exactly like the ones from the official examples. The only thing that differs is the import map. In your case, you refer to your locally hosted version of the three.js repo. Keep in mind to always use the module.js version of three.js. Not the UMD build.
You find more information about the setup/installation of three.js in this guide.
I'm trying to import a 3D module into three.js and I was reading here and here. But it's all black. I've tried moving the Camera's z position to 5, but still black. I've just started with Three.js. I loaded the model in online Three.js viewers and it loads fine. Here's my 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>Import 3D Model into Three JS</title>
<link rel="stylesheet" href="../common.css">
</head>
<body>
<div id="container">
</div>
</body>
<script src="../three.js-master/build/three.js"></script>
<script type="module">
// import { THREE } from '../three.js-master/build/three.js';
import { GLTFLoader } from '../three.js-master/examples/jsm/loaders/GLTFLoader.js';
const container = document.querySelector('div#container');
const path_to_model = './Mini-Game Variety Pack/Models/gltf/tree_forest.gltf.glb';
const loader = new GLTFLoader();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
loader.load(path_to_model, function (gltf)
{
console.log('Adding glTF model to scene...');
scene.add(gltf.scene);
console.log('Model added.');
console.log('Moving camera 5z...');
camera.position.z = 5;
console.log('Camera moved.');
}, undefined, function (error)
{
console.error(error);
});
container.appendChild(renderer.domElement);
function animate()
{
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
</script>
</html>
My folders are like this:
Three JS/
common.css
three.js-master/
ImportModel/
index.html
Mini-Game Variety Pack/
Models/
gltf/
tree_forest.glb
tree_forest.gltf.glb
(Not all files are shown, only necessary ones)
I downloaded all the models from here, but using the tree_forest one.
When I load the page, all I see is:
I'm on a Mac and I'm using Five Server on VSCode.
<script src="../three.js-master/build/three.js"></script>
<script type="module">
// import { THREE } from '../three.js-master/build/three.js';
import { GLTFLoader } from '../three.js-master/examples/jsm/loaders/GLTFLoader.js';
Mixing global scripts with ES6 modules is no good idea and quickly leads to undefined behavior. I suggest you organize imports like so until the app works:
import * as THREE from 'https://cdn.skypack.dev/three#0.129.0/build/three.module.js';
import { OrbitControls } from 'https://cdn.skypack.dev/three#0.129.0/examples/jsm/loaders/GLTFLoader.js';
You should also add some lights to your scene otherwise you just see a black screen. Try it with:
const hemiLight = new THREE.HemisphereLight( 0xffffff, 0x444444 );
hemiLight.position.set( 0, 10, 0 );
scene.add( hemiLight );
const dirLight = new THREE.DirectionalLight( 0xffffff );
dirLight.position.set( 0, 0, 10 );
scene.add( dirLight );
I am trying to add a 3D object to the scene.
Uncaught TypeError: Class constructor ol cannot be invoked without 'new' at new GLTFLoader
Major line error let loader = new THREE.GLTFLoader();
But I can't figure out what to put in brackets? New? .., or what?
Constructor:
https://threejs.org/docs/#examples/en/loaders/GLTFLoader
Model 2(Mb): https://drive.google.com/file/d/1bPnC5coazNFIcsyvV9U29BFiFhXhriYg/view?usp=sharing
Source:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/loaders/GLTFLoader.js"></script>
<script>
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 10; // Отдаление камеры
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x000000, 0);
renderer.setSize(1280 , 720);
renderer.domElement.setAttribute("id", "Church3DObj");
document.body.insertBefore(renderer.domElement, document.body.firstChild);
const aLight = new THREE.AmbientLight(0x404040, 1.2);
scene.add(aLight);
let loader = new THREE.GLTFLoader();
let obj = null;
loader.load('/3d/Church.gltf', function(gltf) {
obj = gltf;
obj.scene.scale.set(1.3, 1.3, 1.3);
scene.add(obj.scene);
});
</script>
</body>
</html>
It is telling you that you cannot invoked GLTFLoader without 'new' at new GLTFLoader
If you look at the doc you linked in the code exemple they use
const loader = new GLTFLoader(); before doing anything with it.
You must instance GLTFLoader.
To avoid this error, we must download from GitHub файлы .js:
three.js, GLTFLoader.js, OrbitControls.js, three.module.js
<script src="scripts/three.js"></script>
<script type="module"> src="scripts/GLTFLoader.js"></script>
<script type="module"> src="scripts/OrbitControls.js"></script>// IF THERE IS A CAMERA CONTROL IN SPACE
Place them in the root of the project and open GLTFLoader.js. At the time of 05/24/2021 we find 64 lines
from './smthPath/smthPath/smthPath/three.module.js';
and remove the excess. (that is, we specify the path to the three.module.js file). In my case:
from './three.module.js';
(If there is a camera control, then we do the same with the OrbitControls.js file, line 9)
from './three.module.js';
Further it is IMPORTANT in the script, in which all the brains add type = "module", and import the files - that is, it turns out
<script type="module">
import {GLTFLoader} from "./scripts/GLTFLoader.js";
import {OrbitControls} from './scripts/OrbitControls.js';
//...
</script>
IMPORTANT
*For people who have not worked with 3D on the web, but model in Cinema4D, 3Ds Max, ZBrush ... (like me). You need not only a .gltf file but also a .bin file
How do I get them?
Go to the site [Scetchfab] (https://sketchfab.com/feed).
Load the model (set the settings for free download (then
you can delete the model)).
We are waiting for it to be processed.
4.download the required format (glFT)
Remove the model from Scetchfab *
IMPORTANT
***The final view of the html file ***
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Dragon</title>
</head>
<body id="c" style="margin: 0;">
<!--3D-->
<script src="scripts/three.js"></script>
<script type="module" src="scripts/GLTFLoader.js"></script>
<script type="module" src="scripts/OrbitControls.js"></script>
<script type="module">
import {GLTFLoader} from "./scripts/GLTFLoader.js";
import {OrbitControls} from './scripts/OrbitControls.js';
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x555555);
const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(0, 5, 15);
const renderer = new THREE.WebGLRenderer({alpha: true, antialias: true});
renderer.setClearColor(0x000000, 0);
renderer.setSize(1920 , 1080);
document.body.appendChild(renderer.domElement);
const aLight = new THREE.AmbientLight(0x404040, 15);
aLight.position.set(0,10,10)
scene.add(aLight);
const pLight = new THREE.PointLight(0xFFFFFF, 15);
pLight.position.set(0,5,0)
scene.add(pLight);
const phelper = new THREE.PointLightHelper(pLight);
scene.add(phelper);
const loader = new GLTFLoader();
let obj = null;
loader.load("3d/Dragon/scene.gltf", function(gltf) {
obj = gltf.scene;
scene.add(gltf.scene);
});
const canvas = document.getElementById("c");
const controls = new OrbitControls(camera, canvas);
controls.target.set(0, 1, 0);
controls.update();
function animate(){
requestAnimationFrame(animate)
obj.rotation.y += 0.005;
renderer.render(scene, camera)
}
animate();
</script>
</body>
</html>
I'm following several tutorials on Three.js, yet I keep getting a Uncaught ReferenceError: OBJLoader is not defined error when trying to implement my own .obj file. Tried different methods, nothing is helping. Been stuck on this problem for days.
I'm running on localhost using http-server.
Oddly enough, when I switch the new OBJLoader(); to new THREE.ObjectLoader(); it seems to work as it tries to load the file, albeit the file is not a .json file, it is an .obj so it throws an error.
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>three.js crash course</title>
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<script type="module" src="js/jQuery.js"></script>
<script type="module" src="js/three.min.js"></script>
<script type="module" src="js/OrbitControls.js"></script>
<script type="module" src="loaders/GLTFLoader.js"></script>
<script type="module" src="loaders/OBJLoader.js"></script>
<script type="module" src="js/index.js"></script>
</body>
</html>
JS
window.onload = function() {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
$(window).resize(function(){
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width/height;
camera.updateProjectionMatrix();
});
var controls = new THREE.OrbitControls(camera, renderer.domElement);
const loader = new OBJLoader();
loader.load (
// resource URL
'./models/boat_large.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' );
}
);
camera.position.z = 3;
var ambientLight = new THREE.AmbientLight(0xFFFFFF, 0.8);
// game logic
var update = () => {
};
// draw scene
var render = () => {
renderer.render(scene, camera);
};
// run game loop (update, render, repeat)
var GameLoop = () => {
requestAnimationFrame(GameLoop);
update();
render();
}
GameLoop();
}
You need to use new THREE.OBJLoader() when you reference the javascript files like that.
The reason it works in the ThreeJS example is, because it is imported via
import { OBJLoader } from './jsm/loaders/OBJLoader.js';
.
Alternatively you could include the file like it is shown in the example
.
In your case it would obviously be something like
import { OBJLoader } from '../loaders/OBJLoader.js';
assuming the JS posted above is from index.js.
it worked for me adding the following import:
import {OBJLoader} from 'three/examples/jsm/loaders/OBJLoader';
i am trying to learn how to use modules. I thought I would start with the simplest possible but already then I have the problem that it doesn't want to run. I have to overlook something important but I just don't see what.
Including "three.module.js" or executing the script as "module" does not work.
Does anyone have a working example?
I got this example from:
https://threejs.org/examples/webgl_geometry_cube
Why doesn't that work if I do it locally
<script type="module">
import * as THREE from "lib/three.module.js";
var camera, scene, renderer;
var mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 400;
scene = new THREE.Scene();
var geometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.x += 0.005;
mesh.rotation.y += 0.01;
renderer.render( scene, camera );
}
</script>
Ok i have researched intensively for the last two days. "export / import" only works via http and not with local directories. So you have to set up your own server. The alternative that I am currently using is a bundler. Parcel is not compatible with my tablet but webpack works very well. To do this, I first had to install a terminal. I chose termux. Then I installed node.js (v12.18.3) via termux and then webpack. At first it seemed like a big effort to me, but after you've done it all once, it doesn't seem that bad anymore. Important point! Termux must be configured in the app manager on android in order to have access to the sdcard in the device. By default, access is forbidden and the command line then shows "permission denied" if you want to access the internal memory with "cd /sdcard/".
I created the project normaly with an editor, you don't need the terminal for that. termux is then only required to run webpack with "npx webpack" after going to the project directory in termux.
My first example:
//path-structure
webpack-demo
|
|_page.html
|_webpack.config.js
|_src
|_index.js
|_bar.js
//page.html
<!doctype html>
<html>
<head> </head>
<body>
<div id="message"></div>
<script src="dist/bundle.js"></script>
</body>
</html>
//webpack.config.js
const path = require('path');
module.exports = {
//mode: 'development',
mode: 'production',
entry: './src/index.js',
output: { path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js' }
};
//index.js
import bar from './bar';
bar();
//bar.js
export default function bar() {
document.getElementById("message").innerHTML = "Hello World";
}
Software source:
termux: install from google play
node.js: https://nodejs.org/en/download/package-manager/
webpack: https://webpack.js.org/guides/installation/
now I am satisfied, because now I can write properly structured javascript code 😁