Load Models Three.js GLTFLoader Syntax error JSON.parse - javascript

I learn how to use Three.js by following the tutorial on discoverthreejs.com.
I have no worries about creating meshes and geometry via three.js
The problem is when I want to load models coming from blender or others.
I use blender 2.8 to create my model and export it as a .glb file. I test the file with a gtlf viewer and everything works as expected.
But as soon as I want to import my model with Three.js to my website, I get this error:
I thought it came from my model, I tried to export it in gltf or glb: same error.
I downloaded another model available on the web: same error.
I use parcel.js if it helps.
{
"name": "cedric_grvl",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"clean": "rm -rf dist",
"dev": "parcel src/index.html --host 192.168.0.37 --open Firefox"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {},
"devDependencies": {
"autoprefixer": "^9.7.3",
"parcel-bundler": "^1.12.4",
"postcss-custom-properties": "^9.0.2",
"postcss-modules": "^1.4.1",
"postcss-preset-env": "^6.7.0",
"sass": "^1.23.7",
"three": "^0.111.0"
}
}
Everything is test in my index.js.
Here is how I call Three.js: (all is good here)
*index.js*
import * as THREE from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
Here are the function for Three.js (tutorial)(all good here)
*index.js*
// these need to be accessed inside more than one function so we'll declare them first
let container;
let camera;
let controls;
let renderer;
let scene;
let mesh;
function init() {
container = document.querySelector( `[data-js="canvas"]` );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xFFFFFF );
createCamera();
createControls();
createLights();
createMeshes();
createRenderer();
// start the animation loop
renderer.setAnimationLoop( () => {
update();
render();
} );
}
function createCamera() {
camera = new THREE.PerspectiveCamera(
35, // FOV
container.clientWidth / container.clientHeight, // aspect
0.1, // near clipping plane
100, // far clipping plane
);
camera.position.set( -4, 4, 10 );
}
function createControls() {
controls = new OrbitControls( camera, container );
}
function createLights() {
const ambientLight = new THREE.HemisphereLight(
0xddeeff, // sky color
0x202020, // ground color
5, // intensity
);
const mainLight = new THREE.DirectionalLight( 0xffffff, 5 );
mainLight.position.set( 10, 10, 10 );
scene.add( ambientLight, mainLight );
}
function createMeshes() {
const geometry = new THREE.BoxBufferGeometry( 2, 2, 2 );
const material = new THREE.MeshStandardMaterial( { color: 0x800080 } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
}
function createRenderer() {
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( container.clientWidth, container.clientHeight );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.gammaFactor = 2.2;
renderer.gammaOutput = true;
renderer.physicallyCorrectLights = true;
container.appendChild( renderer.domElement );
}
// perform any updates to the scene, called once per frame
// avoid heavy computation here
function update() {
// Don't delete this function!
}
// render, or 'draw a still image', of the scene
function render() {
renderer.render( scene, camera );
}
// a function that will be called every time the window gets resized.
// It can get called a lot, so don't put any heavy computation in here!
function onWindowResize() {
// set the aspect ratio to match the new browser window aspect ratio
camera.aspect = container.clientWidth / container.clientHeight;
// update the camera's frustum
camera.updateProjectionMatrix();
// update the size of the renderer AND the canvas
renderer.setSize( container.clientWidth, container.clientHeight );
}
window.addEventListener( 'resize', onWindowResize );
// call the init function to set everything up
init();
Problem is here maybe I do something wrong.
const loader = new GLTFLoader();
const url = "./assets/models/test.glb";
// Here, 'gltf' is the object that the loader returns to us
const onLoad = ( gltf ) => {
console.log( gltf );
};
loader.load( url, onLoad );
I've been thinking about a problem with the path
I tried :
'/src/assets/models/test.glb'
'assets/models/test.glb'
Here is my folder structure:
Thx for your time

In your code import the model like this
import MODEL from './assets/Horse.glb'
Model will be the path to the glb asset then use it to load like this:
loader.load( MODEL, function ( glb ) {
that.scene.add( glb.scene );
}, undefined, function ( error ) {
console.error( error );
});

I found a solution discourse.threejs.org
const parcelPath = new URL('./public/models/hands.glb', import.meta.url);
loader.load( parcelPath.href , function ( glb ) {
that.scene.add( glb.scene );
});

Related

ThreeJS How to use Bloom Post-Processing Without NPM in VanillaJS

I want a bloom effect for my scene when using an emissive map like shown in this ThreeJS Example.
I've tried to understand the code a little bit but I'm basically stuck. The examples are all made with NPM and I do not use this method for my project. I'm sure it is possible to have the bloom effect without the help of this but I struggle to make sense of it all.
As for what I have already, just a basic setup with StandarMeshMaterial:
scene = new THREE.Scene();
loader = new THREE.TextureLoader()
camera = new THREE.PerspectiveCamera( 47, (window.innerWidth/window.innerHeight) / (windowHeight*heightRatio), 0.01, 10000 );
renderer = new THREE.WebGLRenderer( { canvas: document.getElementById( canvasElement ), antialias: true, alpha: true } );
controls = new THREE.OrbitControls( camera, renderer.domElement );
ect..
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
};
ect..
I really just want to apply some post-processing effect so my emissive materials actually appear to be glowing, which is not whats happening at the moment but I just cannot figure out how..
What would be the simplest way to get this result?
The examples are not made with npm.
Here's the example running below. The only thing changed is the paths of the modules and the url of the model.
#info > * {
max-width: 650px;
margin-left: auto;
margin-right: auto;
}
<link type="text/css" rel="stylesheet" href="https://threejs.org/examples/main.css">
<div id="container"></div>
<div id="info">
three.js - Bloom pass by Prashant Sharma and Ben Houston
<br/>
Model: Primary Ion Drive by
Mike Murdock, CC Attribution.
</div>
<script type="module">
import * as THREE from 'https://threejs.org/build/three.module.js';
import Stats from 'https://threejs.org/examples/jsm/libs/stats.module.js';
import { GUI } from 'https://threejs.org/examples/jsm/libs/dat.gui.module.js';
import { OrbitControls } from 'https://threejs.org/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'https://threejs.org/examples/jsm/loaders/GLTFLoader.js';
import { EffectComposer } from 'https://threejs.org/examples/jsm/postprocessing/EffectComposer.js';
import { RenderPass } from 'https://threejs.org/examples/jsm/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'https://threejs.org/examples/jsm/postprocessing/UnrealBloomPass.js';
let camera, stats;
let composer, renderer, mixer, clock;
const params = {
exposure: 1,
bloomStrength: 1.5,
bloomThreshold: 0,
bloomRadius: 0
};
init();
function init() {
const container = document.getElementById( 'container' );
stats = new Stats();
container.appendChild( stats.dom );
clock = new THREE.Clock();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.toneMapping = THREE.ReinhardToneMapping;
container.appendChild( renderer.domElement );
const scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 100 );
camera.position.set( - 5, 2.5, - 3.5 );
scene.add( camera );
const controls = new OrbitControls( camera, renderer.domElement );
controls.maxPolarAngle = Math.PI * 0.5;
controls.minDistance = 1;
controls.maxDistance = 10;
scene.add( new THREE.AmbientLight( 0x404040 ) );
const pointLight = new THREE.PointLight( 0xffffff, 1 );
camera.add( pointLight );
const renderScene = new RenderPass( scene, camera );
const bloomPass = new UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 );
bloomPass.threshold = params.bloomThreshold;
bloomPass.strength = params.bloomStrength;
bloomPass.radius = params.bloomRadius;
composer = new EffectComposer( renderer );
composer.addPass( renderScene );
composer.addPass( bloomPass );
new GLTFLoader().load( 'https://threejs.org/examples/models/gltf/PrimaryIonDrive.glb', function ( gltf ) {
const model = gltf.scene;
scene.add( model );
mixer = new THREE.AnimationMixer( model );
const clip = gltf.animations[ 0 ];
mixer.clipAction( clip.optimize() ).play();
animate();
} );
const gui = new GUI();
gui.add( params, 'exposure', 0.1, 2 ).onChange( function ( value ) {
renderer.toneMappingExposure = Math.pow( value, 4.0 );
} );
gui.add( params, 'bloomThreshold', 0.0, 1.0 ).onChange( function ( value ) {
bloomPass.threshold = Number( value );
} );
gui.add( params, 'bloomStrength', 0.0, 3.0 ).onChange( function ( value ) {
bloomPass.strength = Number( value );
} );
gui.add( params, 'bloomRadius', 0.0, 1.0 ).step( 0.01 ).onChange( function ( value ) {
bloomPass.radius = Number( value );
} );
window.addEventListener( 'resize', onWindowResize );
}
function onWindowResize() {
const width = window.innerWidth;
const height = window.innerHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize( width, height );
composer.setSize( width, height );
}
function animate() {
requestAnimationFrame( animate );
const delta = clock.getDelta();
mixer.update( delta );
stats.update();
composer.render();
}
</script>
What you need to do is use <script type="module"> so that modern import statements work
You should then copy the three.js files as tree like this
someFolder
|
├-build
| |
| +-three.module.js
|
+-examples
|
+-jsm
|
+-controls
| |
| +-OrbitControls.js
| +-TrackballControls.js
| +-...
|
+-loaders
| |
| +-GLTFLoader.js
| +-...
|
...
And adjust your paths as appropriate
See this article
First, NPM is not a framework. It is a package manager to install libraries your project depends on without manually downloading and copying the scripts to your project folder. What I read from your question is that you are not familiar with that module approach. You want to insert scripts and all three.js related stuff should be available under the global namespace THREE?
Assuming that you downloaded three.js to a folder named three, you could import the scripts as follows. Ensure to load the scripts from examples/js and not examples/jsm.
<script src="three/build/three.min.js"></script>
<script src="three/examples/js/controls/OrbitControls.js"></script>
<script src="three/examples/js/loaders/GLTFLoader.js"></script>
<script src="three/examples/js/postprocessing/EffectComposer.js"></script>
<script src="three/examples/js/postprocessing/RenderPass.js"></script>
<script src="three/examples/js/postprocessing/UnrealBloomPass.js"></script>
Now, you can use these classes under the THREE namespace.
const renderScene = new THREE.RenderPass( scene, camera );
const bloomPass = new THREE.UnrealBloomPass( new THREE.Vector2( window.innerWidth, window.innerHeight ), 1.5, 0.4, 0.85 );
Follow the example code, remove the import statements and add THREE where missing.

ThreeJS Upload multiple textures for .obj

So I'm trying to upload a .obj file that also has multiple .png and .jpg files that are it's textures. The problem is I'm not sure how to even handle all these textures when they are uploaded.
Heres my code so far:
var loader = new THREE.OBJLoader(manager);
loader.load(obj_path, function (obj) {
model = obj;
modelWithTextures = true;
model.traverse( function ( child ) {
if ( child.isMesh ) child.material.map = texture;
} );
var textureLoader = new THREE.TextureLoader( manager );
var i;
for (var i = 0; i < files.length; i++) {
file = files[i];
console.log('Texture Files:' + files[i].name);
var texture = textureLoader.load(files[i].name);
}
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
setCamera(model);
setSmooth(model);
model.position.set(0, 0, 0);
setBoundBox(model);
setPolarGrid(model);
setGrid(model);
setAxis(model);
scaleUp(model);
scaleDown(model);
fixRotation(model);
resetRotation(model);
selectedObject = model;
outlinePass.selectedObjects = [selectedObject];
outlinePass.enabled = false;
renderer.render( scene, camera );
scene.add(model);
});
As you can see I'm using the textureLoader but just not sure what to do.
I'm very new to threeJS and 3d models.
Any help or advice would be much appreciated.
Thank you.
In your code, you probably won't see very much, because you render the scene before you add the model to the scene. You should render the scene after you did any changes (unless you have a render loop with requestAnimationFrame). Loading textures also is asynchronous. Use the callback of the .load method to better react when things are finished loading, e.g. trigger render().
I would load the textures within model.traverse() callback. But you have to determine which texture belongs to which mesh. This depends on how your data is structured.
var files = ['mesh1_tex.jpg', 'mesh2_tex.jpg'];
var loader = new THREE.OBJLoader( manager );
var textureLoader = new THREE.TextureLoader( manager );
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 0, 0, -100); // depends on the size and location of your loaded model
var renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
var scene = new THREE.Scene();
loader.load(obj_path, function ( model ) {
model.traverse( function ( child ) {
if ( child instanceof THREE.Mesh ) {
// here you have to find a way how to choose the correct texture for the mesh
// the following is just an example, how it could be done, but it depends on your data
const file = files.find( f => f === child.name + '_tex.jpg');
if (!file) {
console.warn(`Couldn't find texture file.`);
return;
}
textureLoader.load(file, ( texture ) => {
child.material.map = texture;
child.material.needsupdate = true;
render(); // only if there is no render loop
});
}
} );
scene.add( model );
camera.lookAt( model ); // depends on the location of your loaded model
render(); // only if there is no render loop
});
function render() {
renderer.render( scene, camera );
}
Disclaimer: I just wrote down this code without testing.

can't import obj loader in three.js

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!
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">
three.js - GLTFLoader<br />
Battle Damaged Sci-fi Helmet by
theblueturtle_<br />
Royal Esplanade by HDRI Haven
</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>

three.js mtl loader renders black

I am trying to add a level .obj for my program but it renders black. The .mtl file requires several images placed everywhere (not one space is non-textured). I used to same object in my last project and it works, but it doesn't in my current project. When I remove the materials the lighting affects it, but when I add it, it is pitch black. The renderer renders continously. Also, there are no errors in the console.
Here is the code used in my current project: (MaterialLoader is an MTLLoader instance and ObjectLoader is an OBJLoader instance)
MaterialLoader.load("bbb/bbb.mtl",
function(materials) {
materials.preload()
ObjectLoader.setMaterials(materials)
ObjectLoader.load("bbb.obj",
function(model) {
let mesh = model.children[0]
scene.add(mesh)
}, null, function(error) {alert(error)}
)
}, null, function(error) {alert(error)}
)
Here is the code from my previous project (the loader variable is an OBJLoader instance, and the materials load successfully here.)
mtlLoader.load(
"bbb.mtl",
function(materials) {
materials.preload()
loader.setMaterials(materials)
loader.load("bbb.obj",
function(obj) {
level = obj.children[0]
scene.add(level)
}, null,
function(error) { alert(error) }
)
}, null,
function(error) { alert(error) }
)
https://discourse.threejs.org/t/objloader-mtlloader-not-loading-texture-image/2534
try change object material color, like this:
model.children[0].material.color.r = 1;
model.children[0].material.color.g = 1;
model.children[0].material.color.b = 1;
its work for me
Your code works when tested! Maybe it's an issue with the material export, uv unwrapping, the texture's path, do you have lighting added to the scene, etc. Here's my test code:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75,320/240,1,500);
camera.position.set( 0,2,2 );
camera.lookAt( scene.position );
var lightIntensity = 1;
var lightDistance = 10;
var light = new THREE.AmbientLight( 0xFFFFFF, lightIntensity, lightDistance );
light.position.set( 0, 5, 0 );
scene.add( light );
var grid = new THREE.GridHelper(10,10);
scene.add( grid );
var renderer = new THREE.WebGLRenderer({});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( 320,240 );
renderer.domElement.style.margin = '0 auto';
renderer.domElement.style.display = 'block';
renderer.domElement.style.backgroundColor = '#dddddd';
$(document.body).append(renderer.domElement);
function update(){
renderer.render( scene, camera );
requestAnimationFrame( update );
}
update();
mtl_loader = new THREE.MTLLoader();
mtl_loader.load("assets/doughnut.mtl",
function(materials) {
materials.preload()
var obj_loader = new THREE.OBJLoader();
obj_loader.setMaterials(materials)
obj_loader.load("assets/doughnut.obj",
function(object) {
let mesh = object.children[0]
scene.add(mesh);
}, null, function(error) {alert(error)}
)
}, null, function(error) {alert(error)}
);

ThreeJS cannot load Json files

first, i have already read this question didn't help
How i do: first i export a model from C4D to .ojb. Then i import the obj into www.trheejs/editor
I fill all the blank
then from the tree i select my object and export it to a Threejs Object, it save a .json file
My code
<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 kiss = new THREE.Object3D(), loader = new THREE.JSONLoader(true);
loader.load( "brikk2.json", function ( geometry, materials ) {
var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: 0xff0000, ambient: 0xff0000 } ) );
scene.add( mesh );
});
var render = function () {
requestAnimationFrame(render);
renderer.render(scene, camera);
};
render();
</script>
When i run i have theses error messages
THREE.WebGLRenderer 67 three.js:20806
THREE.WebGLRenderer: elementindex as unsigned integer not supported. three.js:26942
XHR finished loading: "http://xxxxxx.xx/tst/mrdoob-three2/brikk2.json". three.js:12018
THREE.JSONLoader.loadAjaxJSON three.js:12018
THREE.JSONLoader.load three.js:11942
load test.html:23
(anonymous function) test.html:28
Uncaught TypeError: Cannot read property 'length' of undefined three.js:12087
parseModel three.js:12087
THREE.JSONLoader.parse three.js:12028
xhr.onreadystatechange three.js:11969
the Json i load
{
"metadata": {
"version": 4.3,
"type": "Object",
"generator": "ObjectExporter"
},
"geometries": [
{
"uuid": "213E28EF-E388-46FE-AED3-54695667E086",
"name": "brikkG",
"type": "Geometry",
"data": {
"vertices": [0.036304,-0.016031,-0.027174,0.036304,0.......
........ 232,1228,1139,1141,1140,1]
}
}],
"materials": [
{
"uuid": "F74C77E4-8371-41BC-85CA-31FC96916CC6",
"name": "lego",
"type": "MeshPhongMaterial",
"color": 16721408,
"ambient": 16777215,
"emissive": 0,
"specular": 16777215,
"shininess": 30,
"opacity": 1,
"transparent": false,
"wireframe": false
}],
"object": {
"uuid": "3BAAB8CA-1EB7-464A-8C6D-FC4BBB3C63C6",
"name": "BrikkM",
"type": "Mesh",
"geometry": "213E28EF-E388-46FE-AED3-54695667E086",
"material": "F74C77E4-8371-41BC-85CA-31FC96916CC6",
"matrix": [1000,0,0,0,0,1000,0,0,0,0,1000,0,0,0,0,1]
}
}
structure of the json file
basically i have tried all i have read about importing native json into ThreeJS, i tried files from the treejs/editor or clara.io still have the same error message, i have no idea anymore, i spend 3 days trying all the way i read to solve this.
If i try to create geometry like CubeGeometry it render without problems, but at soon as i try with native json, nothing work anymore
somebody could help ?
Ok, i found the answer here: http://helloenjoy.com/2013/from-unity-to-three-js/
the native json code is perfect, it's just no be mean to be loaded with JSONLoader but with ObjectLoader (do not mismatch with OBJLoader like i did i one of my experiment). JSONLoader is mean to load json, but with a different format/structure. ObjectLoader is mean to load native format that is also written in json but with a native structure/format.
so use
var loader = new THREE.ObjectLoader();
loader.load( 'brikk2.json', function ( object ) {
scene.add( object );
} );
and it's working
full example code
<body>
<script src="build/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.setClearColor( 0xffffff, 1);
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var ambient = new THREE.AmbientLight( 0x101030 );
scene.add( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 0, 1 );
scene.add( directionalLight );
var loader = new THREE.ObjectLoader();
loader.load( 'brikk2.js', function ( object ) {
scene.add( object );
} );
camera.position.z = 5;
var render = function () {
requestAnimationFrame(render);
renderer.render(scene, camera);
};
render();
</script>
</body>
EDIT
The top code i showed in the top question was right but it was for Geometry loading
loader = new THREE.JSONLoader();
loader.load( 'ugeometry.json', function ( geometry ) {
mesh = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { envMap: THREE.ImageUtils.loadTexture( 'environment.jpg', new THREE.SphericalReflectionMapping() ), overdraw: 0.5 } ) );
scene.add( mesh );
So the recap.
if from threes/editor or Clara.io you save GEOMETRY use JSONLoader, if you save as OBJECT use ObjectLoader, and if you save as SCENE they should be a SceneLoader (unverified)

Categories