I follow this three.js beginners tutorial and I'm stuck at part 2 because nothing is rendering on my web page. I read / watched other tutorials but I'm facing the same problem everytime.
I installed three.js with the npm install three --save command and the code is below.
<!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>My First three.js Project</title>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<script type="module" src="./js/app.js"></script>
</body>
</html>
import * as THREE from '../node_modules/three/build/three.module.js';
import { TrackballControls } from '../node_modules/three/examples/jsm/controls/TrackballControls.js';
// Scene
const scene = new THREE.Scene();
// Camera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.6, 1200);
camera.position.z = 5;
// Renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor("#233143");
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Make Canvas Responsive
window.addEventListener('resize', () => {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
})
// Create Box
const boxGeometry = new THREE.BoxGeometry(2, 2, 2);
const boxMaterial = new THREE.MeshLambertMaterial({ color: 0xFFFFFF });
const boxMesh = new THREE.Mesh(boxGeometry,
boxMaterial);
boxMesh.rotation.set(40, 0, 40);
scene.add(boxMesh);
const rendering = function () {
requestAnimationFrame(rendering);
// Constantly rotate box
scene.rotation.z -= 0.005;
scene.rotation.x -= 0.01;
renderer.render(scene, camera);
}
rendering();
body {
margin: 0px;
height: 100vh;
}
canvas {
display: block;
}
Something is definitely wrong, but what?
First always run three.js project in a live server not just by clicking index.html second keep file structure same as shown in image.
Related
I'm a complete noob in three.js and am trying to create a site that displays a .obj model, I've gone through the docs and tutorials online, I'm facing a problem where all .obj models are leading to a black screen, the code is down below along with the output.
function main(){
// creating the camera
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 200);
// creating the renderer and inserting it into the html file
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// creating the scene
var scene = new THREE.Scene();
var ambientLight = new THREE.AmbientLight(0xfffff);
scene.add(ambientLight);
// loading the model along with the materials
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath( 'IronMan/' );
var url = "IronMan.mtl";
mtlLoader.load( url, function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( 'IronMan/' );
objLoader.load('IronMan.obj', function (object) {
object.position.y = - 95;
scene.add( object );
var loader = new THREE.OBJLoader();
loader.addEventListener('load', function (event){
scene.add(event.content);
});
renderer.render(scene, camera);
},
undefined,
function(err){
console.error(err);
});
});
}
main();
body{
margin: 0;
}
canvas {
position: absolute;
height: 100%;
width: 100%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="styles.css">
<title>Face Model</title>
</head>
<body>
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/108/three.min.js'></script>
<script src="https://threejs.org/examples/js/loaders/MTLLoader.js"></script>
<script src='https://cdn.jsdelivr.net/gh/mrdoob/Three.js#r92/examples/js/loaders/OBJLoader.js'></script>
<script src="app.js"></script>
</body>
</html>
Output:
Screenshot of the output
Repo link: https://github.com/chethan-hebbar/face-model
When looking for a way to create a three.js line with a changed width I came across this article which suggests to use a THREE.MeshLine class from here. However, when trying to follow the documentation on how to use it in my script I got an error:
require.js:5 Uncaught Error: Module name "three" has not been loaded yet for context: _. Use require([])
http://requirejs.org/docs/errors.html#notloaded
at makeError (require.js:5)
at Object.o [as require] (require.js:5)
at requirejs (require.js:5)
at test_line.html:13
Here are the lines of code I used in my script:
<html>
<head>
<script src="https://requirejs.org/docs/release/2.3.5/minified/require.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js"></script>
<script src="https://raw.githubusercontent.com/spite/THREE.MeshLine/master/src/THREE.MeshLine.js"></script>
<title>Test</title>
</head>
<body>
<script>
var THREE = require( 'three' );
var MeshLine = require( 'three.meshline' );
...
Do I miss something? (Hint: I am a beginner with javascript)
I also tried to follow the suggestions HERE, but as soon as I added type="module" in the script part I got an error container is not defined.
Here is a complete, stand-alone, static, easy, direct working html example of a single line in a browser window. I'd appreciate if the answer could contain a complete, stand-alone, static, easy, direct working example of the code fixed!
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js"></script>
<title>Test</title>
</head>
<body>
<script>
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 0, 150);
scene = new THREE.Scene();
scene.add(camera);
renderer = new THREE.WebGLRenderer({
clearAlpha: 1
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xcaffee, 1);
document.body.appendChild(renderer.domElement);
var material = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 10000000 } );
var points = [];
points.push( new THREE.Vector3(-50, 0, 0 ) );
points.push( new THREE.Vector3( 50, 0, 0 ) );
var geometry = new THREE.BufferGeometry().setFromPoints( points );
var line = new THREE.Line( geometry, material );
scene.add( line );
renderer.render( scene, camera );
animate();
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
</script>
</body>
</html>
Edit 2: As #user2589273 mentioned in the comment, this answer is no longer relevant, as the original repository (https://github.com/spite/THREE.MeshLine) has merged the below fork into the main repo. I will leave the answer below for posterity.
The Meshline repository you linked is not maintained any more and does not work with current three.js releases.
Here is the maintained fork that I currently use:
https://github.com/ryanking1809/threejs-meshline
It should work if you replace the link in your question with:
https://unpkg.com/threejs-meshline#2.0.11/src/index.js
Edit: with full working example:
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js"></script>
<script src="https://unpkg.com/threejs-meshline#2.0.11/src/index.js"></script>
<title>Test</title>
</head>
<body>
<script>
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.set(0, 0, 150);
scene = new THREE.Scene();
scene.add(camera);
renderer = new THREE.WebGLRenderer({
clearAlpha: 1
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xcaffee, 1);
document.body.appendChild(renderer.domElement);
let points = [];
points.push( new THREE.Vector3(-50, 0, 0 ) );
points.push( new THREE.Vector3( 50, 0, 0 ) );
const line = new MeshLine();
line.setVertices(points);
const material = new MeshLineMaterial();
const mesh = new THREE.Mesh( line, material );
scene.add( mesh );
renderer.render( scene, camera );
animate();
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
</script>
</body>
</html>
i'm very new to npms and i'm trying to import three.js into my scene but it is coming up with this error despite stating the type = "module" in my script tag in my html
I installed it through an npm and here is my javascript:
var $ = require('jquery');
var three = require('three');
import * as THREE from 'three';
import OrbitControls from 'three/examples/jsm/controls/OrbitControls';
var camera, scene, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 10 );
camera.position.z = 1;
scene = new THREE.Scene();
geometry = new THREE.BoxGeometry( 0.2, 0.2, 0.2 );
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render( scene, camera );
}
Here is my html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="#"/>
<title>Document</title>
<script type = "module" src="/bundle.js"></script>
</head>
<body>
</body>
</html>
Sorry if the answer is obvious, using browserify and module files is very new territory for me.
Edit: So in the official documentation, it says to do this :
var THREE = require('three');
var scene = new THREE.Scene();
...
which works except I want to use
import { MapControls } from 'three/examples/jsm/controls/OrbitControls.js';
which is only available through extracting it from the orbitcontrols library. Is there a way to do this without ES6 imports and using require() instead?
I'm trying to make a hologram with Three.JS (Pepperghost Effect) and for it to work I need 4 rotating models.
I have a working POC (https://gyazo.com/57da565593493a2c9971457632bb5552). This was an STL model, so I wasn't able to add textures to it. I did some research and gave gLTF's a shot. I got a model with textures and the importing all worked, but the rotation part was not working as I expected.
Here is a gif of the problem: https://gyazo.com/c5a1a8ee65f7da2cce1c83261d465b33
I want it to spin on its own axes instead of in circles. What I think is the problem, is that it doesn't import it centered, so it would be a problem with the model position and not the rotating part (which is mesh.rotation.y += 0.01; to be clear).
I tried moving the mesh with the mesh.position.set() function, but that moves the whole scene (I guess that's what you call it?).
Also, as you can see on the last gif, I have another problem where the chest is only displayed twice. Maybe this is tied to the other problem I have?
I tried putting it together in a jsfiddle, but since I cant upload the model that doesn't work. This is the 3D model I'm importing: https://sketchfab.com/3d-models/chest-92a8d45d2d5c43b8b0b5bf7d97816ada
The peppersghost file can be found here https://threejs.org/examples/jsm/effects/PeppersGhostEffect.js
<!DOCTYPE html>
<html lang="en">
<head>
<title>Three.js Hologram POC</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="style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.js"></script>
<script src="peppersghost.js"></script>
<!-- <script charset="utf-8" src="STLLoader.js"></script> -->
<!-- <script src="three.module.js"></script> -->
<!-- <script src="http://threejs.org/build/three.min.js"></script> -->
<script src="http://threejs.org/examples/js/loaders/MTLLoader.js"></script>
<script src="http://threejs.org/examples/js/loaders/OBJLoader.js"></script>
<script src="http://threejs.org/examples/js/loaders/GLTFLoader.js"></script>
</head>
<body>
<script type="module">
var container;
var camera, scene, renderer, effect, mesh, cube;
var group;
// var cameraTarget = new THREE.Vector3( 0, - 0.25, 0 );
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
// console.log(window.innerWidth / window.innerHeight)
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 100000 );
scene = new THREE.Scene();
// scene.background = new THREE.Color( 0xffd300 );
var ambientLight = new THREE.AmbientLight(0xffffff);
var light = new THREE.PointLight(0xffffff, 2.0, 200);
camera.add(ambientLight);
camera.add(light);
scene.add(camera);
camera.position.z = 1100;
camera.lookAt(scene.position);
const gltfLoader = new THREE.GLTFLoader();
gltfLoader.load('/media/autoconvert/scene.gltf', (gltf) => {
mesh = gltf.scene;
// mesh.position.set(0, 100, 0)
// mesh.scale.set(3, 1, 1);
scene.add(mesh);
const box = new THREE.Box3().setFromObject(mesh);
const boxSize = box.getSize(new THREE.Vector3()).length();
const boxCenter = box.getCenter(new THREE.Vector3());
});
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio( window.devicePixelRatio );
container.appendChild( renderer.domElement );
effect = new THREE.PeppersGhostEffect( renderer );
effect.setSize( window.innerWidth, window.innerHeight );
effect.cameraDistance = 5;
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
effect.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.y += 0.02;
// var timer = Date.now() * 0.0005;
// camera.position.x = Math.cos( timer ) * 3;
// camera.position.z = Math.sin( timer ) * 3;
// camera.lookAt( cameraTarget );
effect.render( scene, camera );
}
</script>
</body>
</html>
Thanks!
EDIT: Thanks for the help! I tried both solutions, but I am still encountering problems :(
First I tried getting the first child. Although it didnt spin in circles like it did before, it still rotates the wrong way and it only shows two models instead of four: https://gyazo.com/1da02beff790bbb440c42eec42540e56
Then I expanded and added a group like this:
group = new THREE.Group(); scene.add(group); and group.add(mesh) instead of scene.add(mesh).
This is what I got after that: https://gyazo.com/220f5eed04ec05c56000327b57837047
As you can see, it still isn't working. I am still trying to find a solution for my problem. Any other suggestions are welcome!
I am trying to attempt to learn Three.js from their getting started guide: http://threejs.org/docs/index.html#Manual/Introduction/Creating_a_scene and I have the code as exactly from the site. I am using the latest code from their site, as for the library. The error in the console is as follows:
Uncaught TypeError: Object #<Object> has no method 'mergeVertices'
I am not really too sure on what the issue is
Here is the code that is from the site that I am using:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>First Three JS App</title>
<style>
body {
margin: 0;
}
canvas {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
// To be able to view anything with Three.js we need a scene, a camera, and a renderer
// -> To render the scene with the camera
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 = THREE.BoxGeometry(10, 10, 10 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 });
var cube = new THREE.Mesh( geometry, material);
scene.add( cube );
camera.position.z = 5;
var render = function render() {
requestAnimationFrame( render )
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render( scene, camera );
};
render();
</script>
</body>
</html>
From what #WestLangley suggested, I needed to review my code. I was missing a new in geometry declaration, and my renderer.setSize call needed 2 params instead of 1 (I was using a ratio) and the final var render = function.... I needed to take out the second render
Sometimes it is good to have a second pair of eyes.. Thanks again #WestLangley