How to load 3D object using AMFLoader in three.js? - javascript

I am new to three.js.I am trying to load 3d object on web browser using AMFLoader and STLLoader in three.js. Both AMFLoader and STLLoader has same problem. The 3d object doesn't render on web browser and also doesn't show any error. I don't know how to fix this.Below is my code snippet which I have tried with AMFLoader.
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - loaders - amf 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;
}
</style>
</head>
<body>
<script src="three.js"></script>
<script src="OrbitControls.js"></script>
<script src="AMFLoader.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;
init();
animate();
function init() {
// camera
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 7;
camera.position.set( -0.140892, 0.00959548, 0.0602311);
controls = new THREE.OrbitControls( camera );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x999999 );
scene.add( camera );
// light
ambient = new THREE.AmbientLight(0xffffff, 1.0);
scene.add(ambient);
keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 100%, 75%)'), 1.0);
keyLight.position.set(-100, 0, 100);
fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 100%, 75%)'), 0.75);
fillLight.position.set(100, 0, 100);
backLight = new THREE.DirectionalLight(0xffffff, 1.0);
backLight.position.set(100, 0, -100).normalize();
/*var dirLight = new THREE.DirectionalLight( 0xffffff );
dirLight.position.set( 200, 200, 1000 ).normalize();
camera.add( dirLight );
camera.add( dirLight.target );*/
var loader = new THREE.AMFLoader();
loader.load( 'Method1-ConeThenCube.amf', function ( object ) {
var material = new THREE.MeshPhongMaterial( { color: 0xff5533, specular: 0x111111, shininess: 200 } );
var mesh = new THREE.Mesh( object, material );
scene.add( object );
} );
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
stats = new Stats();
container.appendChild( stats.dom );
//
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 );
renderer.render( scene, camera );
stats.update();
}
</script>
</body>
</html>
Help me to fix this problem.

Related

How to create a Sphere using three.js?

I was making a sphere using three.js but the output is just a black screen as shown.
The code I used is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>
<script>
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 );
const geometry = new THREE.SphereGeometry( 15, 32, 16 );
const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
const sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );
camera.position.z = 5;
function animate() {
requestAnimationFrame( animate );
sphere.rotation.x += 0.01;
sphere.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
</script>
</body>
</html>
I couldn't explain why the code was unable to render the sphere. What went wrong?
Your camera is inside the sphere. Move it a bit further away from the origin like in the following live example:
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 50;
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.SphereGeometry(15, 32, 16);
const material = new THREE.MeshBasicMaterial({
color: 0xffff00
});
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);
function animate() {
requestAnimationFrame(animate);
sphere.rotation.x += 0.01;
sphere.rotation.y += 0.01;
renderer.render(scene, camera);
};
animate();
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three#0.143/build/three.min.js"></script>

How to create a Sphere with World Map using three.js?

I was making a sphere with world map using three.js but the output is just a black screen as shown.
The code I used is:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>
<script>
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( 0, 0, 50 );
camera.lookAt( 0, 0, 0 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.SphereGeometry( 15, 32, 16 );
const texture = new THREE.TextureLoader().load( 'C:\Users\pc\Desktop\Lines\land_ocean_ice_cloud_2048.jpg' );
const material = new THREE.MeshBasicMaterial( { map: texture } );
const sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );
function animate()
{
requestAnimationFrame( animate );
sphere.rotation.x += 0.01;
sphere.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
</script>
</body>
</html>
I couldn't explain why the code was unable to render the sphere. What went wrong?
This is the correct code.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r79/three.min.js"></script>
<script>
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
camera.position.set( 0, 0, 50 );
camera.lookAt( 0, 0, 0 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.SphereGeometry( 15, 32, 16 );
const texture = new THREE.TextureLoader().load( 'https://i.imgur.com/kFoWvzw.jpg' );
const material = new THREE.MeshBasicMaterial( { map: texture } );
const sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );
function animate()
{
requestAnimationFrame( animate );
sphere.rotation.x += 0.01;
sphere.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
</script>
</body>
</html>
I never thought that downloading the source and image from Internet and render it on web browser is impossible. The source and the image that should be rendered on web browser must be coming from the Internet itself and link it to the code via <source> and <texture> command using Internet URL.
What is more amazing is that once that the source and the image coming from the Internet via Internet URL has been rendered on web browser, it works even without any Internet!

Draw image on canvas using threejs

Hi I m trying to draw an image on canvas using threejs
Code:
<html lang="en">
<head>
<title>three.js webgl - materials - canvas texture</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="main.css">
<style>
#drawing-canvas {
position: absolute;
background-color: #000000;
top: 0px;
right: 0px;
z-index: 3000;
cursor: crosshair;
}
</style>
</head>
<body>
<img id="endPoint" width="15" height="15" src="endpoint.png" alt="The End Point">
<div id="info">
three.js - webgl - canvas as a texture
<div>click and draw in the white box</div>
</div>
<canvas id="drawing-canvas" height="100" width="100"></canvas>
<script type="module">
import * as THREE from '../build/three.module.js';
var camera, scene, renderer, mesh, material;
var drawStartPos = new THREE.Vector2();
init();
setupCanvasDrawing();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 500;
scene = new THREE.Scene();
material = new THREE.MeshBasicMaterial();
mesh = new THREE.Mesh( new THREE.BoxBufferGeometry( 200, 200, 200 ), material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
}
// Sets up the drawing canvas and adds it as the material map
function setupCanvasDrawing() {
var selectedPoints = 0;
// get canvas and context
var drawingCanvas = document.getElementById( 'drawing-canvas' );
var img = document.getElementById('endPoint');
var drawingContext = drawingCanvas.getContext( '2d' );
var imgmap = new THREE.TextureLoader().load( "endpoint.png" );
var imgmaterial = new THREE.SpriteMaterial( { map: imgmap, color: 0x0000ff } );
// draw white background
drawingContext.fillStyle = '#FFFFFF';
drawingContext.fillRect( 0, 0, 128, 128 );
// set canvas as material.map (this could be done to any map, bump, displacement etc.)
material.map = new THREE.CanvasTexture( drawingCanvas );
// set the variable to keep track of when to draw
var paint = false;
// add canvas event listeners
drawingCanvas.addEventListener( 'mousedown', function ( e ) {
selectedPoints++;
if ( selectedPoints == 1 ) {
drawStartPos.set( e.offsetX, e.offsetY );
//drawingContext.drawImage(img, 5, 5);
var imgsprite = new THREE.Sprite( imgmaterial );
scene.add( imgsprite );
//imgsprite.scale.set(5,5,1);
imgmap.needsUpdate = true;
}
if ( selectedPoints == 2 ) {
//drawingContext.drawImage(img, 5, 5);
selectedPoints = 0;
draw(drawingContext, e.offsetX, e.offsetY);
//drawingContext.drawImage(img, 5, 5);
var imgsprite = new THREE.Sprite( imgmaterial );
scene.add( imgsprite );
//imgsprite.scale.set(5,5,1);
imgmap.needsUpdate = true;
}
//console.log("Paint in mousedown : " + paint)
} );
}
function draw( drawContext, x, y ) {
drawContext.beginPath();
drawContext.moveTo( drawStartPos.x, drawStartPos.y );
drawContext.strokeStyle = '#0000FF';
drawContext.lineTo( x, y );
drawContext.closePath();
drawContext.fill();
drawContext.stroke();
// reset drawing start position to current position.
drawStartPos.set( x, y );
// need to flag the map as needing updating.
material.map.needsUpdate = true;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.01;
renderer.render( scene, camera );
}
</script>
</body>
</html>
This is modified from the existing example of drawing on canvas in threejs as shown here
Problem is I was able to draw lines between two points that are selected by a mouse click but cannot see the image. I don't know if I m doing right by adding the image to the scene. Please advise.

I want multiple Three.js animations inside my html, but they are overlapping

I'm professional graphicdesigner and have problem with Three.js
I have try many things, but this not good. I just duplicated the imported model and renamed it. I try everything on the interwebs. This works, but they overlap, I also have 2 different names. Here is my .js
var container, stats;
var camera, scene, renderer;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 4;
var windowHalfY = window.innerHeight / 4;
init();
animate();
function init() {
// important for multiple canvasuse
container = document.getElementById( 'container1' );
document.body.appendChild( container );
// cam
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 4;
// scene
scene = new THREE.Scene();
// light
var ambient = new THREE.AmbientLight( 0x444444 );
scene.add( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 1, 1 ).normalize();
scene.add( directionalLight );
// BG
scene.background = new THREE.Color( 0xffffff );
// BEGIN Clara.io JSON loader code
var objectLoader = new THREE.ObjectLoader();
objectLoader.load("untitled-scene.json", function ( obj ) {
scene.add( obj );
} );
// mlg render
renderer = new THREE.WebGLRenderer();
renderer.setSize( 400, 200 );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
// resize?
window.addEventListener( 'resize', onWindowResize, false );
}
// draw a different, next canvas
container = document.getElementById( 'container2' );
document.body.appendChild( container );
// cam
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 4;
// scene
scene = new THREE.Scene();
// light
var ambient = new THREE.AmbientLight( 0x444444 );
scene.add( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffeedd );
directionalLight.position.set( 0, 1, 1 ).normalize();
scene.add( directionalLight );
// BG
scene.background = new THREE.Color( 0xffffff );
// BEGIN Clara.io JSON loader code
var objectLoader = new THREE.ObjectLoader();
objectLoader.load("untitled-scene2.json", function ( obj ) {
scene.add( obj );
} );
// mlg rendere reloaded
renderer = new THREE.WebGLRenderer();
renderer.setSize( 400, 200 );
container.appendChild( renderer.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
//
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( canvas_width, canvas_height );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX ) / 16;
mouseY = ( event.clientY - windowHalfY ) / 16;
}
//
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
camera.position.x += ( mouseX - camera.position.x ) * .03;
camera.position.y += ( - mouseY - camera.position.y ) * .03;
camera.lookAt( scene.position );
renderer.render( scene, camera );
}
and here ma html
<!DOCTYPE html>
<html lang="en">
<head>
<title>farts</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 {
color: #808080;
font-family:Monospace;
font-size:13px;
text-align:center;
background-color: #fff;
margin: 0px;
overflow: hidden;
width: 100%;
height: 100%;
}
#info {
color: #00f;
position: absolute;
top: 10px;
width: 100%;
text-align: left;
z-index: 100;
display:block;
}
#container1 {
width: 300px;
height: 200px;
border: 5px solid red;
float:left;
margin-top: 200px;
}
#container2 {
width: 300px;
height: 200px;
border: 1px solid blue;
float:left;
}
</style>
</head>
<body>
<div id="info">
farts <br />
</div>
<div id="container1">
<script src="num1.js"></script><br/>
<script src="three.js"></script>
<script src="Detector.js"></script>
<script src="stats.min.js"></script>
</div>
<div id="container2">
<script src="num1.js"></script><br/>
<script src="three.js"></script>
<script src="Detector.js"></script>
<script src="stats.min.js"></script>
</div>
</body>
</html>
It's just a fun project, but I have love to offer.
Change:
renderer.setSize( 400, 200 );
for:
renderer.setSize( 300, 200 );
Because your div has the dimensions (300,200) and you send it to render other dimensions (400,200), that's why your canvas comes out of your div and with that you should not have problems editing your css.

THREE.js rotation on loaded file

I've been playing around with this ThreeJS library for a couple of weeks now, and using inspiration from others, I've made a canvas that displays an external .stl-file.
My only problem is I can't seem to apply any transformations to it. I can move the camera around just fine, but I can't get even the most simple transformations to work. I'm not best with JavaScript, so I might have missed some essential parts.
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - STL</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 {
background-color: #000000;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/loaders/STLLoader.js"></script>
<script src="js/Detector.js"></script>
<script src="dat.gui.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container;
var rotationSpeed;
var camera, cameraTarget, scene, renderer;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 15 );
camera.position.set( -3, 1, 3 );
cameraTarget = new THREE.Vector3( 0, 0, 0 );
scene = new THREE.Scene();
scene.fog = new THREE.Fog( 0x72645b, 2, 15 );
// Ground
var plane = new THREE.Mesh( new THREE.PlaneGeometry( 40, 40 ), new THREE.MeshPhongMaterial( { ambient: 0x999999, color: 0x999999, specular: 0x101010 } ) );
plane.rotation.x = -Math.PI/2;
plane.position.y = -0.5;
scene.add( plane );
plane.receiveShadow = true;
// ASCII file
var loader = new THREE.STLLoader();
loader.addEventListener( 'load', function ( event ) {
var geometry = event.content;
var material = new THREE.MeshPhongMaterial( { ambient: 0xff5533, color: 0xff5533, specular: 0x111111, shininess: 200 } );
var model = new THREE.Mesh( geometry, material );
model.position.set( 0, 0.05, 0 );
model.rotation.set( Math.PI / 2.0, - Math.PI / 1.5, 0 );
model.scale.set( 0.01, 0.01, 0.01 );
model.castShadow = true;
model.receiveShadow = true;
scene.add( model );
} );
loader.load( './models/stl/ascii/cover.stl' );
// Lights
scene.add( new THREE.AmbientLight( 0x777777 ) );
addShadowedLight( 1, 1, 1, 0xffffff, 1.35 );
addShadowedLight( 0.5, 1, -1, 0xffaa00, 1 );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( scene.fog.color, 1 );
renderer.gammaInput = true;
renderer.gammaOutput = true;
renderer.shadowMapEnabled = true;
renderer.shadowMapCullFace = THREE.CullFaceBack;
container.appendChild( renderer.domElement );
window.addEventListener( 'resize', onWindowResize, false );
}
function addShadowedLight( x, y, z, color, intensity ) {
var directionalLight = new THREE.DirectionalLight( color, intensity );
directionalLight.position.set( x, y, z )
scene.add( directionalLight );
directionalLight.castShadow = true;
// directionalLight.shadowCameraVisible = true;
var d = 1;
directionalLight.shadowCameraLeft = -d;
directionalLight.shadowCameraRight = d;
directionalLight.shadowCameraTop = d;
directionalLight.shadowCameraBottom = -d;
directionalLight.shadowCameraNear = 1;
directionalLight.shadowCameraFar = 4;
directionalLight.shadowMapWidth = 1024;
directionalLight.shadowMapHeight = 1024;
directionalLight.shadowBias = -0.005;
directionalLight.shadowDarkness = 0.15;
}
/* var controls = new function()
{
this.rotationSpeed = 0.2;
}
var gui = new dat.GUI();
gui.add(controls, 'rotationSpeed',0,1);
*/
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.0005;
camera.lookAt( cameraTarget );
//THIS LINE DOESN'T WORK
//model.position.x = Math.cos( timer );
//model.position.z = Math.sin( timer );
renderer.render( scene, camera );
}
</script>
</body>
</html>
The last lines before the render() function just gives me a black, blank page.
Even things like model.position.x += 0.02; kills it
I could find the mistake here , but sorry some how not able to port your code to JSFIDDLE
Here is the problem I found,
model variable is not declared in the global scope. It is initialized locally in the init() function and you are trying the manipulate that variable with in the render function, where it does not have any scope.
So the solution is Just declare the variable model before calling the init() function just like other variables that you are declaring there by adding this below line.
var model;

Categories

Resources