Three.js Gltf loader returns errors - three.js

I am just learning THREE.js, and have a gltf file that I want to load into a file.
Here is my html file:
<html>
<head>
<title>Liftoff!!</title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script type="module">
import { GLTFLoader } from 'file:///Users/name/Desktop/three.js-practice/node_modules/three/examples/jsm/loaders/GLTFLoader.js';
import * as THREE from "file:///Users/name/Desktop/three.js-practice/node_modules/three/build/three.js"
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 );
var loader = new GLTFLoader.GLTFLoader();
loader.load( 'gltf.html', function (gltf) {
scene.add( gltf.scene )
}, undefined, function ( error ) {
console.error( error )
} )
</script>
</body>
</html>
I am opening my file in google chrome, and when I open it, it doesn't work, and the JavaScript console returns this error:
"gltf.html:1 Access to script at 'file:///Users/isaac/Desktop/three.js-practice/node_modules/three/examples/jsm/loaders/GLTFLoader.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
GLTFLoader.js:1 Failed to load resource: net::ERR_FAILED
gltf.html:1 Access to script at 'file:///Users/isaac/Desktop/three.js-practice/node_modules/three/build/three.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
three.js:1 Failed to load resource: net::ERR_FAILED"
I have tried to do this in localhost, but that also doesn't work.

Related

threejs loading animated object cannot decode

hey guys i am new to threejs and i am trying to import this animated dinosaur that i have downloaded online from. i am trying to load and import and run in my web but met some errors. for file structure, the material_diffuse.png and material_specularGlossiness.png and scene.gltf and scene.bin are all in the same folder as index.html.
some of the errors i face are listed.
textures/Material_diffuse.png:1 Failed to load resource: the server responded with a status of 404 (Not Found)
textures/Material_specularGlossiness.png:1 Failed to load resource: the server responded with a status of 404 (Not Found)
GLTFLoader.js:127 DOMException: The source image could not be decoded.
this is my code
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>3d model</title>
<style>
body {
margin: 0;
}
canvas {
display: block;
}
</style>
</head>
<body>
<script src="three.js"></script>
<script type="module" src="GLTFLoader.js"></script>
<script type="module">
import { GLTFLoader } from "./GLTFLoader.js";
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.01,
1000
);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var loader = new GLTFLoader();
var obj;
loader.load("scene.gltf", function (gltf) {
obj = gltf.scene;
scene.add(gltf.scene);
});
scene.background = new THREE.Color(0xffffff);
var light = new THREE.HemisphereLight(0xffffff, 0x444444);
scene.add(light);
// camera.position.set(0, 5, 30);
camera.position.set(0, 5, 8);
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
function rotateFunction() {
obj.rotation.y += 0.01;
}
document.addEventListener('scroll', function(e) { rotateFunction() });
</script>
<div>
</div>
</body>
</html>
thanks in advance.
According to the reported errors, the file structure should look like so:
+-- scene.gltf
+-- scene.bin
+-- textures
| +-- Material_diffuse.png
| +-- Material_specularGlossiness.png
Meaning you have to put your textures into a textures directory.
Besides, the imports of your app are wrong. Use these imports for now until your app works:
<script type="module">
import * as THREE from 'https://cdn.skypack.dev/three#0.135.0/build/three.module.js';
import { GLTFLoader } from 'https://cdn.skypack.dev/three#0.135.0/examples/jsm/loaders/GLTFLoader.js';

Blank White screen and ReferenceError: THREE is not defined

I have been practicing 3d modeling in few years without coding at. As, the demand for loading ready made 3d models to 3js is increasing, I have decided to start coding. After 2 days of trial and error with my first code, I am sharing with you the code that does not seem to work properly. I am not sure where the error is because part of it is HTML and the other one is a three.js script. Note that, the obj file was converted to JavaScript. I have been following this video https://www.youtube.com/watch?v=NtRrYUAd8rs which does not show the entire html texts. So I decided to add the HTML of https://threejs.org/docs/#manual/en/introduction/Creating-a-scene which shows the basic doc for setting up a scene. Once I open up the html file in the browser an errors of Uncaught ReferenceError: THREE is not defined! I found out that some one in this world was able to solve this error using UMD version of Three.js but I can not see how it should be stated in the html file. You may have a look at my code below;
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script src="Desktop/convert/three.js"></script><script>
// Our Javascript will go here.
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 );
document.body.appendChild( renderer.domElement );
var particleMaterial = new THREE.MeshBasicMaterial();
particleMaterial.map = THREE.ImageUtils.loadTexture('img/convert/china-politics.jpg');
particleMaterial.side = THREE.DoubleSide;
var itmArr = [];
</script>
</body>
</html>

loading texture issue, works with animation, blank without

I am new to three.js, but am just coming off of a project using Java and JMonkeyEngine, so I know my way around 3d.
My issue comes with loading a texture. I'm sure this question has come up quite a few times coming from the topics I've read, however the topics I have seen are older, and it didn't work with what I needed.
I took an example from the site and tried editing it to my own needs. I was able to load my texture fine, and it spun around just like the example....
HOWEVER, when I removed the animation from the rendering process my image poofed. I can use a regular square with color just fine, but no texture.
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - geometries</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,
user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="three.min.js"></script>
<script>
var container, stats;
var camera, scene, renderer;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera(
45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.y = 400;
scene = new THREE.Scene();
var light, object;
scene.add( new THREE.AmbientLight( 0x404040 ) );
light = new THREE.DirectionalLight( 0xffffff );
light.position.set( 0, 1, 0 );
scene.add( light );
var map = THREE.ImageUtils.loadTexture( 'butter.jpg' );
map.wrapS = map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 16;
var material =
new THREE.MeshLambertMaterial(
{ ambient: 0xbbbbbb, map: map, side: THREE.DoubleSide } );
//
object = new THREE.Mesh(
new THREE.PlaneGeometry(100, 100, 4, 4 ), material );
object.position.set( -400, 0, 0 );
scene.add( object );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
container.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 );
render();
}
function render() {
var timer = Date.now() * 0.0001;
camera.position.x = Math.cos( timer ) * 800;
camera.position.z = Math.sin( timer ) * 800;
camera.lookAt( scene.position );
for ( var i = 0, l = scene.children.length; i < l; i ++ ) {
var object = scene.children[ i ];
object.rotation.x = timer * 5;
object.rotation.y = timer * 2.5;
}
renderer.render( scene, camera );
}
</script>
</body>
I read up something here Using textures in THREE.js stating I needed to call the render after the texture loads. Sure, no problem, but it doesn't work. I assumed this could be the case, but I think about the animation. Did it load and since the animation is constant it just loaded after a render pass and then was okay during the rest of it, or something else?
Next I saw Texture from hard disk not loading in three.js - showing black
Now the user says he cannot see anything doing all sorts of things, I haven't tried any of that, but I'm using Netbeans 8.0 and it calls from the LocalHost, and I can see the animated textures, so I'm assuming this isn't the issue.
I saw another forum like this as well, with similar answers to the 2 above."
Any thoughts to think? Hopefully it's something simple.
Thanks for the help all, hopefully this library works out great!
EDIT: I found a post here ThreeJS texture issue saying there is an issue with chrome (which I was using as the browser to test). I tried the internal netbeans browser (it just gave me an error with webgl so meh) and ie didn;t work either...
I also tried to use a loader as suggested but his method gives off an "undefined" error.
I saw another post stating R58 -> R59 had changes to thw ImageLoader, so idk :(
EDIT2: Trying out the starting example of Three.JS I cannot get the texture to work stationary or during the animation.... weird..
<html>
<head>
<title>My first Three.js app</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
<script src="three.min.js"></script>
<script>
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 );
var geometry = new THREE.BoxGeometry(1,1,1);
var map = THREE.ImageUtils.loadTexture('butter.jpg', {}, function() {render();});
// render();
map.wrapS = map.wrapT = THREE.RepeatWrapping;
map.anisotropy = 16;
var material = new THREE.MeshLambertMaterial( { ambient: 0xbbbbbb, map: map, side: THREE.DoubleSide } );
//var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
function render()
{
requestAnimationFrame(render);
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
}
render();
</script>
</body>
EDIT3: Thought about this last night as I was going to sleep, and realized today that there is no NPOT... I tried another image that was 184x184 with no luck :(

Load Blender scene

Some difficulties to load a blender exported scene:
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
background-color: #ffffff;
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<script src="JS/Stats.js"></script>
<script src="JS/three.js"></script>
<script src="JS/basic4.js"></script>
<script>
var camera, scene;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var callbackFinished =function ( result ) {
console.log (result);
// scene=result.scene;
// camera=result.camera;
}
var callbackProgress=function(progress, result){
console.log (progress);
}
loader = new THREE.ObjectLoader();
loader.callbackProgress= callbackProgress;
loader.load( "JS/basic4.js", callbackFinished );
}
function animate() {
requestAnimationFrame( animate );
//renderer.render( scene, camera );
}
</script>
</body>
</html>
When run in browser i get these errors:
Uncaught SyntaxError: Unexpected token : /JS/basic4.js:3
THREE.WebGLRenderer 65 three.js:19742
Uncaught TypeError: Cannot read property 'type' of undefined three.js:11864
(anonymous function) three.js:11864
THREE.ObjectLoader.parse three.js:11684
(anonymous function) three.js:11668
(anonymous function)
So, what's wrong?
unexpected Token means the first ":" after metadata in basic4.js
I tested various loaders and the result is always the same.
Any help out there to understand how to load a simple blender - scene to 3JS ?
Greetings
jewtis
I modified the script tag to
<script src="JS/basic4.js" type="text/JSON"></script>
and the error: unexpected token was gone.
Then i used the THREE.SceneLoader() and the scene could be loaded.
Regards jewtis

Add color to .obj in ThreeJS

I am new to ThreeJS and have a simple question. I have the following code that will work properly, but I cannot add color to my .obj. The short and narrow of it is that I designed a game controller in Solidworks 2012, then I exported the CAD file as a .stl. I then used MeshLab to export the .stl as a .obj. Now I use the .obj in ThreeJS and it works, but I cannot for the life of me get color added to the .obj. Here is the code
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - loaders - vtk loader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
#info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
</style>
</head>
<body>
<div id="info">
three.js -
vtk format loader test -
model from The GeorgiaTech Lagre Geometric Model Archive,
</div>
<script src="three.min.js"></script>
<script src="TrackballControls.js"></script>
<script src="OBJLoader.js"></script>
<script src="BinaryLoader.js"></script>
<script src="Detector.js"></script>
<script src="stats.min.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, controls, scene, renderer;
var cross;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.01, 1e10 );
camera.position.z = 200;
camera.position.y = 200;
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 5.0;
controls.zoomSpeed = 5;
controls.panSpeed = 2;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
scene = new THREE.Scene();
scene.add( camera );
// light
var dirLight = new THREE.DirectionalLight( 0xffffff );
dirLight.position.set( 20, 20, 100 ).normalize();
camera.add( dirLight );
camera.add( dirLight.target );
// texture
var manager = new THREE.LoadingManager();
manager.onProgress = function ( item, loaded, total ) {
console.log( item, loaded, total );
};
var texture = new THREE.Texture();
var loader = new THREE.ImageLoader( manager );
loader.load( 'bigthumbnail.jpg', function ( image ) {
texture.image = image;
texture.needsUpdate = true;
} );
var loader = new THREE.OBJLoader()
loader.load( 'Gamepad.obj', function ( object ) {
object.position.y = 0;
scene.add( object );
} );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setSize( window.innerWidth, window.innerHeight );
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
controls.handleResize();
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
stats.update();
}
</script>
</body>
</html>
I have poured through the threejs.org website and looked at most of the examples. All of the examples that use complex colors use .bin files or .js files. So I downloaded Python 2.7.6, installed it and ran convert_obj_three.py. This generated a .js file, but I'm not sure it is correctly formatted. Unfortunately, The output that convert_obj_three.py gave me is too large to post. My Second question is which file format is best for complex coloring, like chrome blue? .bin, .js or can I use .obj? If using a .js is the best way to go then how can I reliably convert the .obj file to .js? By the way, I tried using the .js that was created by convert_obj_three.py, but the webpage is blank all the time. Seems I cannot load the .js using THREE.JSONLoader().
Thanks in advance.
after loader.load function is executed you get a threejs Object3D object. which contains the meshes of your object .
so you need to traverse over them to change the color of the material. The code will be something like this.
var loader = new THREE.OBJLoader()
loader.load( 'Gamepad.obj', function ( object ) {
object.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
child.material.ambient.setHex(0xFF0000);
child.material.color.setHex(0x00FF00);
}
} );
object.position.y = 0;
scene.add( object );
} );
Now the object's material has two properties which decides its color as you may see in the code ambient and color .
So this is to say that if in the scene you have white AmbientLight the object will appear Red(because the ambient property is set to #FF0000)
If the object is luminated by some other type of light like pointlight or directionalLight (as in your above case) the objects will appear Green(as color is set to #00FF00).
Now the last case if you have say that you have one white AmbientLight and one DirectionalLight in the Scene, then the object will appear as yellow as both material.ambient and material.color both will come into play and Red+Green will render as Yellow.
Hoping this helps.

Resources