Model not rendering on screen - three.js

I'm trying to load a 3D model on the screen but the screen is black, and sometimes I receive an error depending on the way I try to implement my code.
Here is my HTML file:
<!DOCTYPE html>
<html lang="en">
<head>
<title>T1 CG</title>
</head>
<body>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</body>
<script src="./lib/threejs/build/three.min.js"></script>
<script src="./lib/threejs/examples/js/loaders/GLTFLoader.js"></script>
<script src="./poke.js"></script>
</html>
Here is my javascript file:
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 loader = new THREE.GLTFLoader();
loader.load('./assets/Squirtle/Squirtle.gltf', function(gltf) {
scene.add( gltf );
});
When I try to run like that, I receive the following error: THREE.Object3D.add: object not an instance of THREE.Object3D. But when I try to do something like scene.add(gltf.scene), I don't receive any error but the screen turns black and nothing happens.
Hope that somebody can help me, I'll appreciate it!
Thanks in advance.

Have you tried adding any lights to your scene? Most materials need to be illuminated in order to be visible. You can try a simple AmbientLight:
var light = new THREE.AmbientLight( 0x404040 );
scene.add( light );
Also make sure your camera is positioned a little far from the origin, otherwise the loaded .gltf and the camera will both be occupying the same spot. For instance, if the object is 2 units wide, you could place your camera 5 units away:
camera.position.z = 5;

Related

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>

About the control of threejs

I am practicing threejs while watching the tutorial.
However, one problem occurred.
Mouse control code is not working. Only black screen.
I checked, but it's exactly the same code as the tutorial.
But mine doesn't work.
I am the latest version of Chrome and I got the latest file from OrbitControls.js from GitHub.
I think the only difference from the tutorial is the OrbitControls.js file.
What should I do?
<html>
<head>
<meta charset="utf-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script>
window.addEventListener('load', init);
function init() {
const width = 960;
const height = 540;
const renderer = new THREE.WebGLRenderer({
canvas: document.querySelector('#myCanvas')
});
renderer.setSize(width, height);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, width / height);
camera.position.set(0, 0, 1000);
const controls = new THREE.OrbitControls(camera);
const mesh = new THREE.Mesh(
new THREE.BoxGeometry(300, 300, 300),
new THREE.MeshNormalMaterial()
);
scene.add(mesh);
tick();
function tick() {
renderer.render(scene, camera);
requestAnimationFrame(tick);
}
}
</script>
</head>
<body>
<canvas id="myCanvas"></canvas>
</body>
</html>
One common root cause for such importing issues is the usage of three.js components from different releases. You can easily verify this by importing your code like so:
<script src="https://cdn.jsdelivr.net/npm/three#0.110/build/three.js"></script>
<script src="https://cdn.jsdelivr.net/npm/three#0.110/examples/js/controls/OrbitControls.js"></script>
Another possible problem is the way you create OrbitControls. In recent versions of three.js, the second parameter is mandatory. Meaning the code should look like so:
const controls = new THREE.OrbitControls(camera, renderer.domElement);

How to add object to scene?

I have code like this:
<html>
<head>
<script src="js/three.js"></script>
<script type="text/javascript">
function init()
{
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(0, window.innerWidth / window.innerHeight, 100, 100);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(1000, 1000);
document.body.appendChild(renderer.domElement);
var sphere_geometry = new THREE.SphereGeometry(150);
var material1 = new THREE.MeshPhongMaterial({ color: 0x0033ff, specular: 0x555555 });
var sphere_mesh = new THREE.Mesh(sphere_geometry, material1);
scene.add(sphere_mesh);
renderer.render(scene, camera);
}
</script>
</head>
<body onload="init()">
<canvas id="mycanvas" width="100" height="100"></canvas>
</body>
</html>
and i can't add a sphere into the scene. The only thing that i get is black square. How can I do it?
Just some fast tips:
-Place the camera to see the object, not just position but the direction where it is facing, do you have all your objects in front?
-Make the object visible, choose a good material definition, start with a boiler plate/hello world scene, once it works, modify it to get the scene as you want it to be.

Interact/rotate object using Three.js

I am using the basic example on three.js but am unable to interact with the object to rotate via mouse interaction. Am I missing something obvious? My desired functionality is to rotate an object (such as a box) left,right,up,down, etc. The code I am using is as follows:
<!DOCTYPE html>
<script src="scripts/three.min.js"></script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My first Three.js app</title>
<style>
body {
margin: 0;
}
canvas {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script src="scripts/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( 3, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
var render = function () {
requestAnimationFrame( render );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
};
render();
</script>
</body>
</html>
You are missing EventListeners, your scene doesnt know about your mouse moving.
See this simple example from mr.doob on how to spin a cube with the mouse:
http://mrdoob.github.io/three.js/examples/canvas_geometry_cube.html
Similiar to the rotation on the Y-Axis (left, right) you can add rotation on the X-Axis (up, down) too.

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 :(

Resources