Set Three.js Background from user upload - javascript

I want a user to be able to upload an image from his own computer, which should be set as a background image for Three.js. This image should be a static background. Is it possible to save the image just in a variable?
My current code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>See your new car where you want it</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
</head>
<body>
<input type="file" onchange="selectBackground()" multiple accept='image/*'><br>
<script src="js/three.js"></script>
<script src="js/OrbitControls.js"></script>
<script>
var scene;
var camera;
var renderer;
function selectBackground()
{
console.log("getting image");
var newBackground;
function previewFile() {
var preview = document.querySelector('img');
var file    = document.querySelector('input[type=file]').files[0];
var reader  = new FileReader();
reader.addEventListener("load", function () {
newBackground = reader.result;
}, false);
if (file) {
  reader.readAsDataURL(file);
}
}
setBackground(newBackground);
}
function setBackground(image)
{
console.log("setting background");
//init of three.js
//init Three.js
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 400, 200, 0 );
//set background color to white
//scene.background = new THREE.Color(0xffffff);
//set background
scene.backgroundImage = new THREE.CanvasTexture(image);
renderer = new THREE.WebGLRenderer();
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
document.body.appendChild( renderer.domElement );
controls = new THREE.OrbitControls( camera, renderer.domElement );
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 2;
animate();
}
var animate = function () {
requestAnimationFrame( animate );
renderer.render( scene, camera );
};
</script>
</body>
</html>
It would be awesome if you would be able to help me with this.

You'll want to run this full page, otherwise it's hard to see the result....
var scene;
var camera;
var renderer;
function selectBackground() {
//console.log("getting image");
var newBackground;
function previewFile() {
var preview = document.querySelector('img');
var file   = document.querySelector('input[type=file]').files[0];
var reader  = new FileReader();
reader.addEventListener("load", function() {
//console.log("Loaded.");
newBackground = reader.result;
var img = document.createElement('img');
//preview.src =
img.src = reader.result;
var tex = new THREE.Texture(img);
tex.needsUpdate = true;
setBackground(tex);
}, false);
if (file) { 
reader.readAsDataURL(file);
}
}
previewFile()
}
function setBackground(tex) {
//console.log("setting background");
//init of three.js
//init Three.js
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(10, 10, 10);
//set background color to white
//scene.background = new THREE.Color(0xffffff);
//set background
scene.background = tex; //new THREE.CanvasTexture(image);
renderer = new THREE.WebGLRenderer();
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(800, 600); //window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
var geometry = new THREE.BoxGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
color: 0x00ff00
});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 2;
animate();
}
var animate = function() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
};
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>See your new car where you want it</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<input type="file" onchange="selectBackground()" multiple accept='image/*'><br>
<!--img id="preview">preview</img-->
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>
</body>
</html>

Related

What did i do wrong here? The 3D module is not showing up

I am trying to use three.js to open an obj 3d module, but for some reason i cannot manage to generate the module out on the web, is there anything wrong i done here? (i just directly follow this tutorial video https://www.youtube.com/watch?v=wHuSQ7I1aKs)
My obj and mtl file is at directory "/Documents/js/bugatti" while my html file is at "/Documents/js"
<!DOCTYPE html>
<html>
<head>
<title>My first three.js app</title>
<style>
body { margin: 0; }
canvas {width: 100%; height: 100%}
</style>
</head>
<body>
<script src="OrbitControls.js"></script>
<script src="three.min.js"></script>
<script type = "module" src="OBJLoader.js"></script>
<script type = "module" src="MTLLoader.js"></script>
<script type = "module">
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.z = 200;
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = true;
var keyLight = new THREE.DirectionalLight(new THREE.Color('hsl(30, 100%, 75%)'), 1.0);
keyLight.position.set(-100, 0, 100);
var fillLight = new THREE.DirectionalLight(new THREE.Color('hsl(240, 100%, 75%)'), 0.75);
fillLight.position.set(100, 0, 100);
var backLight = new THREE.DirectionalLight(0xffffff, 1.0);
backLight.position.set(100, 0, -100).normalize();
scene.add(keyLight);
scene.add(fillLight);
scene.add(backLight);
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setTexturePath('/Document/js/bugatti/');
mtlLoader.setPath('/Documents/js/bugatti/');
mtlLoader.load('bugatti.mtl', function (materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('/Documents/js/bugatti/');
objLoader.load('bugatti.obj', function (object) {
scene.add(object);
object.position.y -= 60;
});
});
var animate = function () {
requestAnimationFrame( animate );
controls.update();
renderer.render(scene, camera);
};
animate();
</script>
</body>
</html>

Cant load textures in threejs on plane

Any time i try loading textures with the following code i get no errors and a black screen
here is the javascript
the file name is 3d_stuff.js
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.PlaneGeometry( 16, 16);
const texture = new THREE.TextureLoader().load( '/vaporwater.jpg' );
const material = new THREE.MeshBasicMaterial( { map: texture} );
//const material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
const plane = new THREE.Mesh( geometry, material );
scene.add( plane );
camera.position.z = 3 ;
camera.position.y = -1
camera.rotation.x = -30
function animate() {
renderer.render( scene, camera );
};
animate();
here is the index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="three.js"></script>
<script src="3d_stuff.js"></script>
</body>
</html>
Does anyone know what might have gone wrong
Im running the server on ubuntu using the python3 -m http.server command by the way
Actually, try this first :
Note: the js script import is type module
import * as THREE from 'https://cdn.jsdelivr.net/npm/three#0.118/build/three.module.js';
let camera, scene, renderer;
let geometry, material;
init();
function init() {
camera = new THREE.PerspectiveCamera(
70,
window.innerWidth / window.innerHeight,
0.01,
10
);
camera.position.z = 1;
scene = new THREE.Scene();
//get texture add path to image
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('https://picsum.photos/200/300');
texture.encoding = THREE.sRGBEncoding;
const geometry = new THREE.PlaneGeometry(1, 1);
const material = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.DoubleSide
});
const plane = new THREE.Mesh(geometry, material);
scene.add(plane);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setAnimationLoop(animation);
document.body.appendChild(renderer.domElement);
}
function animation(time) {
renderer.render(scene, camera);
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body {
margin: 0;
}
</style>
</head>
<body>
<!--note that the script tag is of type module-->
<script src="./3d_stuff.js" type="module">
</script>
</body>
</html>

Three.js just drawing a white screen

I am trying to follow the tutorial on here: https://threejs.org/docs/#manual/en/introduction/Creating-a-scene and my browser just shows me a white window. I tried to seperate the files into both js and html file.
What I already tried:
adding / deleting the nomodule parameter in the script tag
running a local live server
Here is my code:
My index.html file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script nomodule src="js/main.js"></script>
<script>
// Our Javascript will go here.
</script>
</body>
</html>
My js file called main.js in the folder 'js'. I installed Three.js via npm.
import * as THREE from 'three'
//import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
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.BoxGeometry();
const material = new THREE.MeshBasicMaterial({color:0x00ff00});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
const animate = function () {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
};
animate();
The example code on the contrary:
<!DOCTYPE html>
<html>
<head>
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="js/three.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.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
const animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
</script>
</body>
</html>
This renders a green rotating cube:
<!DOCTYPE html>
<html>
<head>
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script type="module">
import * as THREE from 'https://unpkg.com/three/build/three.module.js';
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.BoxGeometry();
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
const animate = function () {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render( scene, camera );
};
animate();
</script>
</body>
</html>
You need to include "three.js" in the js/ folder.
"Before we start" Section:
https://threejs.org/docs/#manual/en/introduction/Creating-a-scene
"Save the following HTML to a file on your computer, along with a copy of three.js in the js/ directory, and open it in your browser."

STLLoader.js code example for starting with three.js? Is there any good clean sample code?

I have to include the STLLoader.js of three.js into my web application but can't find some good clean code examples on how to start.
On the https://threejs.org website there is only the example demonstration for the STLLoader (https://threejs.org/examples/#webgl_loader_stl) but I can't find some clean sample code for the STLLoader (except for this one: https://github.com/mrdoob/three.js/blob/master/examples/webgl_loader_stl.html which is still quite difficult to understand for beginners), like there is for some other Loaders e.g. the OBJLoader (https://threejs.org/docs/index.html#examples/en/loaders/OBJLoader)...
Please help me out with this:)
That is what i came up with at the end...
For all those who had problems figuring it out too:)
HTML:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>STLLoader Test</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<script src="three.js-master/build/three.js"></script>
<script src="three.js-master/examples/jsm/controls/OrbitControls.js"></script>
<script src="three.js-master/examples/jsm/loaders/STLLoader.js"></script>
<script src="js/custom.js"></script>
</body>
</html>
JS (custom.js):
// Necessary for camera/plane rotation
var degree = Math.PI/180;
// Setup
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);
// Resize after viewport-size-change
window.addEventListener("resize", function () {
var height = window.innerHeight;
var width = window.innerWidth;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
});
// Adding controls
controls = new THREE.OrbitControls(camera, renderer.domElement);
// Ground (comment out line: "scene.add( plane );" if Ground is not needed...)
var plane = new THREE.Mesh(
new THREE.PlaneBufferGeometry(500, 500 ),
new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } )
);
plane.rotation.x = -90 * degree;
plane.position.y = 0;
scene.add( plane );
plane.receiveShadow = true;
// ASCII file - STL Import
var loader = new THREE.STLLoader();
loader.load( './stl/1.stl', function ( geometry ) {
var material = new THREE.MeshLambertMaterial( { color: 0xFFFFFF, specular: 0x111111, shininess: 200 } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0, 0, 0);
scene.add( mesh );
} );
// Binary files - STL Import
loader.load( './stl/2.stl', function ( geometry ) {
var material = new THREE.MeshLambertMaterial( { color: 0xFFFFFF, specular: 0x111111, shininess: 200 } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set( 0, 20, 0);
scene.add( mesh );
} );
// Camera positioning
camera.position.z = 100;
camera.position.y = 100;
camera.rotation.x = -45 * degree;
// Ambient light (necessary for Phong/Lambert-materials, not for Basic)
var ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);
// Draw scene
var render = function () {
renderer.render(scene, camera);
};
// Run game loop (render,repeat)
var GameLoop = function () {
requestAnimationFrame(GameLoop);
render();
};
GameLoop();
And of course you need to download the three.js project and include it into your project root.
Leon

OBJ file not rendering properly in threejs

Some faces are missing from the obj file where they are not rendered properly.
The part with grey colour shows the same object viewed in an online viewer, where all the face/parts are rendered correctly.
the below image is the one I'm trying to render in localhost. using THREE.js obj loader.
javascript file- main.js
window.onload=function(){
init();
animate();
}
function init() {
container = document.getElementById('container');
console.log(container)
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.x = 100;
camera.position.y = 50;
camera.position.z = 70;
scene = new THREE.Scene();
var ambient = new THREE.AmbientLight( 0xffff , 4);
scene.add( ambient );
var directionalLight = new THREE.DirectionalLight( 0xffffff ,0.5 );
directionalLight.position.set( 0, 0, 1000 );
scene.add( directionalLight );
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 5.0;
controls.zoomSpeed = 2;
controls.panSpeed = 1;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.5;
controls.keys = [ 65, 83, 68 ];
controls.addEventListener( 'change', render );
// texture
var manager = new THREE.LoadingManager();
manager.onProgress = function (item, loaded, total) {
console.log(item, loaded, total);
};
var texture = new THREE.Texture();
var onProgress = function (xhr) {
if (xhr.lengthComputable) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete, 2) + '% downloaded');
}
};
var onError = function (xhr) {
};
var loader = new THREE.ImageLoader(manager);
loader.load('textures/GreenWall.jpg', function (image) {
texture.image = image;
texture.needsUpdate = true;
});
var loader = new THREE.OBJLoader(manager);
loader.load( './obj/male02/feder.jt.obj', function ( object ) {
object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material.map = texture;
}
});
scene.add(object);
}, onProgress, onError);
renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0xdddddd);
renderer.setSize( window.innerWidth/1.5 , window.innerHeight/1.5);
container.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
render();
controls.update();
}
function render() {
//camera.lookAt(scene.position);
renderer.render( scene, camera );
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - loaders - OBJ loader</title>
<meta charset="utf-8">
<meta io ="view" name="viewport" content="width=device-width, height=device-height user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<script src="./build/three.js"></script>
<script src="./build/Detector.js"></script>
<script src="./build/three.min.js"></script>
<script src="./loaders/OBJLoader.js"></script>
<script src="main.js"></script>
<script src= "Controls/TrackballControls.js"></script>
<div id="container" ></div>
</body>
</html>
By adding child.material.side = THREE.DoubleSide;inside the loader, it worked perfectly.

Categories

Resources