how to load gltf in three JS - three.js

I'm a beginner in ThreeJS. I want to import a cube basic from Blender in gLTF format... This is my code.
What is it missing?
var canvas = document.getElementById('canvas');
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var scene = new THREE.Scene();
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(rosa, 1);
renderer.setSize(window.innerWidth, window.innerHeight);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
canvas.appendChild(renderer.domElement);
// Instantiate a loader
var loader = new THREE.GLTFLoader();
function renderingScene() {
renderer.render(scene, camera);
}
function cargarGLTF() {
// Load a glTF resource
loader.load('./glTF/resources/cube/untitled.gltf', function (gltf) {
scene.add(gltf.scene);
});
// renderingScene();
}
cargarGLTF();
controlMouse();
renderingScene();
Output console

Related

three.js - Model showing with blank (black) texture despite material loaded

I have a 3D model file 3dbaotang.obj and a material file 3dbaotang.mtl. I've loaded both of them using three.js OBJLoader and MTLLoader. The model has shown up, but not the material, as it's solely covered with black. Can anyone help?
Here is my code:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth /
window.innerHeight, 0.1, 10000);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var keyLight = new THREE.DirectionalLight('hsl(30, 100%, 75%)', 1.0);
var fillLight = new THREE.DirectionalLight('hsl(240, 100%, 75%)', 0.75);
var backLight = new THREE.DirectionalLight(0xffffff, 1.0);
backLight.position.set(100, 0, -100).normalize();
keyLight.position.set(-100, 0, 100);
fillLight.position.set(100, 0, 100);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
controls.update();
renderer.setSize(window.innerWidth, window.innerHeight, false);
renderer.setClearColor(new THREE.Color(0xf2f2f2), 1);
document.body.appendChild(renderer.domElement);
// LOAD MODEL
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setResourcePath('/models/');
mtlLoader.setPath('/models/');
mtlLoader.load('/3dbaotang.mtl', (materials) => {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('/models/');
objLoader.load('3dbaotang.obj', (object) => {
scene.add(object);
});
});
camera.position.z = 200;
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
Result:
Adding to Brother Eye's answer, I'm brand new and and spent quite a lot of time in the dark but this got me on to the solution so I thought I'd elaborate for anyone in the same position.
Adding a light can be some simply as follows;
//Add light
var light = new THREE.AmbientLight(0xffffff);
scene.add(light);
The reference docs are located at https://threejs.org/docs/#api/en/lights/AmbientLight
It was the lack of light that caused this problem, not the material. After adding ambient light to the scene, the object can be seen normally

Threejs texture map to sphere error (three.min.js:120 THREE.WebGLRenderer: image is not power of two (1000x500))

I am learning three js now. What I am trying to do now is draw a sphere and then texture map an image on the sphere. Basically, I am following this tutorial, http://learningthreejs.com/blog/2013/09/16/how-to-make-the-earth-in-webgl/.
This is my code
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script type="text/javascript">
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.addEventListener('resize', function() {
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
})
controls = new THREE.OrbitControls(camera, renderer.domElement);
var geometry = new THREE.SphereGeometry(0.5, 32, 32)
var material = new THREE.MeshPhongMaterial();
var earthMesh = new THREE.Mesh(geometry, material)
scene.add(earthMesh)
// TheJim01: Replacing local file with accessible web resource
// License and source: https://commons.wikimedia.org/wiki/File:Earthmap1000x500compac.jpg
//material.map = THREE.ImageUtils.loadTexture("world.jpg");
material.map = THREE.ImageUtils.loadTexture("https://upload.wikimedia.org/wikipedia/commons/c/c4/Earthmap1000x500compac.jpg");
camera.position.z = 10; //3
//game logic
var update = function() {
};
//draw scene
var render = function() {
renderer.render(scene, camera);
}
// run game loop (update, render, repeat)
var GameLoop = function() {
requestAnimationFrame(GameLoop);
update();
render();
}
GameLoop();
</script>
When I run the code, I got this error in the console.
three.min.js:120 THREE.WebGLRenderer: image is not power of two (1000x500)
My image file actually have 1000X500 size as well. But nothing is displayed on the canvas. What is wrong and how can I fix it?
I was unable to load the texture without errors (in three.js r93) with THREE.ImageUtils.loadTexture. It threw a "tainted canvas" error in Chrome. I switched to using THREE.TextureLoader, which you can see in the code below.
All that said, that was probably not the real problem. Your scene is lacking a light, and without a light, everything will render as black. In the code below, I added a simple point light to the camera.
With those two fixes in place, your code runs as expected.
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script type="text/javascript">
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.addEventListener('resize', function() {
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
})
controls = new THREE.OrbitControls(camera, renderer.domElement);
scene.add(camera);
camera.add(new THREE.PointLight(0xfffff, 1, Infinity));
var geometry = new THREE.SphereGeometry(0.5, 32, 32)
var material = new THREE.MeshPhongMaterial();
var earthMesh = new THREE.Mesh(geometry, material)
scene.add(earthMesh)
// TheJim01: Replacing local file with accessible web resource
// License and source: https://commons.wikimedia.org/wiki/File:Earthmap1000x500compac.jpg
//material.map = THREE.ImageUtils.loadTexture("world.jpg");
var loader = new THREE.TextureLoader();
material.map = loader.load("https://upload.wikimedia.org/wikipedia/commons/c/c4/Earthmap1000x500compac.jpg");
camera.position.z = 10; //3
//game logic
var update = function() {
};
//draw scene
var render = function() {
renderer.render(scene, camera);
}
// run game loop (update, render, repeat)
var GameLoop = function() {
requestAnimationFrame(GameLoop);
update();
render();
}
GameLoop();
</script>

Threejs animation issue

Trying to load a STL model into a canavas with Threejs is giving me an error every time the animate function is runned;
Uncaught TypeError: Cannot read property 'render' of undefined
at animate (
I know the STL file is good it worked before.
Here is my code;
// Globals
var scene, camera, light, renderer;
init();
animate();
// Sets up the scene.
function init() {
// Create the scene and set the scene size.
scene = new THREE.Scene();
//Scene Lighting
scene.add( new THREE.AmbientLight( 0x000000 ) );
//Renderer
var renderer = new THREE.WebGLRenderer({canvas: document.getElementById('modelCan'), antialias:true});
renderer.setClearColor(0xfffffff);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize( window.innerWidth/3, window.innerHeight/3 );
//Camera
var camera = new THREE.PerspectiveCamera(1000, window.innerWidth/window.innerHeight, 1, 10000);
scene.add(camera);
//Camera Lightning
var light = new THREE.PointLight( 0xffffff, 1);
camera.add( light );
var loader = new THREE.STLLoader();
loader.load( 'Sac_Fuel_Tank.stl', function ( geometry ) {
var material = new THREE.MeshLambertMaterial( { color: 0x286617,
wireframe: true
} );
var mesh = new THREE.Mesh( geometry, material );
mesh.rotation.x = Math.PI / 2;
mesh.position.set(20,10,-10);
// mesh.rotation.z = Math.PI;
scene.add( mesh );
} );
controls = new THREE.OrbitControls(camera, renderer.domElement);
}
function animate() {
// Read more about requestAnimationFrame at http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
requestAnimationFrame(animate);
// Render the scene.
renderer.render(scene, camera);
controls.update();
}
So what am I doinng wrong?
You have to remove the var keyword when creating the renderer. Just do:
renderer = new THREE.WebGLRenderer( { canvas: document.getElementById('modelCan'), antialias:true } );

ThreeJS BoxHelper scale Not working

var sphere = new THREE.BoxGeometry(6,20,6);
var object = new THREE.Mesh( sphere, new THREE.MeshBasicMaterial( 0xff0000 ));
var box = new THREE.BoxHelper( object, 0xffff00 );
var gui = new dat.GUI();
gui.add(box.scale,'x',0,50).name('Width').listen();
the datgui shows the slider for box scale but changing it does not have any effect.Please help.
First, you have to set the color property ot the THREE.MeshBasicMaterial:
var boxGeometry = new THREE.BoxGeometry(6,20,6);
var object = new THREE.Mesh( boxGeometry, new THREE.MeshBasicMaterial( {color:0xff0000} ));
Then you have to add the THREE.BoxHelper to the scene:
var box = new THREE.BoxHelper( object, 0xffff00 );
scene.add(boxHelper);
Further you have to change the scale property of the THREE.Mesh and not the scale property of the THREE.BoxHelper. But you have to update (onUpdate) the THREE.BoxHelper:
var gui = new dat.GUI();
gui.add(object.scale,'x',0.1,5).name('Width').onChange(function(){
boxHelper.update();
} );
See the code snippet:
(function onLoad() {
var container, loader, camera, scene, renderer, controls, boxHelper;
init();
animate();
function init() {
container = document.getElementById('container');
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true;
container.appendChild(renderer.domElement);
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 100);
camera.position.set(15, -20, 15);
loader = new THREE.TextureLoader();
loader.setCrossOrigin("");
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
scene.add(camera);
window.onresize = resize;
controls = new THREE.OrbitControls(camera, renderer.domElement);
var boxGeometry = new THREE.BoxGeometry(6,20,6);
var object = new THREE.Mesh( boxGeometry, new THREE.MeshBasicMaterial( {color:0xff0000} ));
scene.add(object);
boxHelper = new THREE.BoxHelper( object, 0x000000 );
scene.add(boxHelper);
var gui = new dat.GUI();
gui.add(object.scale,'x',0.1,5).name('Width').onChange(function(){
boxHelper.update();
} );
}
function resize() {
var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
})();
<script src="https://threejs.org/build/three.min.js"></script>
<!--script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script-->
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.5/dat.gui.min.js"></script>
<div id="container"></div>

Importing 3D model exported from Blender/maya in Threejs and rendering it using CanvasRenderer for iPad

Am trying to create an app which will import the 3D model exported from Blender/Maya into ThreeJS. I have installed Blender and three js export option is also coming, however when am trying to load the exported JS (I tried renaming extension to json also) it is not working and showing blank screen. Can anyone help me with this by providing a sample code for this?
TIA.
Regards,
NileshW
add a div to the body
<div id="myScene"></div>
then..
<script>
// global
var scene, renderer, camera, cube, controls;
init();
animate();
function init() {
// scene box
var myScene = document.getElementById("myScene");
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, .01, 10000);
camera.position.z = 500;
var light = new THREE.AmbientLight(0xffffff); // soft white light
scene.add(light);
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
/* ==== OPTIONAL SPOTLIGHT ====
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(100, 1000, 2000);
spotLight.castShadow = true;
spotLight.shadowMapWidth = 1024;
spotLight.shadowMapHeight = 1024;
spotLight.shadowCameraNear = 500;
spotLight.shadowCameraFar = 4000;
spotLight.shadowCameraFov = 30;
scene.add(spotLight);
*/
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
myScene.appendChild(renderer.domElement);
loader = new THREE.JSONLoader();
loader.load("your_json_file.js", function (geometry, materials) {
mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial(materials));
scene.add(mesh);
});
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
renderer.render(scene, camera);
}
</script>
Have you tried the code from chawk - just change to use your test.js (check folder path)
If the code in you function init() is complete then it looks like you've missed a couple of things
You have created a camera, created a scene, created a loader, loaded a file and added mesh to the scene
You need to add the camera to the scene
You also need to add some light(s) to your scene
var camera, scene, renderer;
var geometry, material, mesh;
var controls;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 5, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 50, 50, 50 );
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = false;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
scene = new THREE.Scene();
var light = new THREE.PointLight(0xffffff);
light.position.set(-100,200,100);
scene.add(light);
// Load in the mesh and add it to the scene.
var loader = new THREE.JSONLoader();
loader.load( "models/testnew.js", function(geometry){
var material = new THREE.MeshNormalMaterial({color: 0x55B663});
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
});
//
renderer = new THREE.CanvasRenderer();
renderer.setSize( 1000, 600);
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
renderer.render( scene, camera );
}

Resources