Hi I have created an environment map that stitches 6 images to create a room, I have an object in the room that casts a shadow in attempt to make it look attached to the floor but I still get the effect that the object is floating in 3D space. Is there a way that I can get around this to glue the object to the ground. Keeping in mind the env map is rendered around the cameras position.
-- example1.js
function envMap(scene) {
var testMaterials = [
'image1.png',
'image2.png',
'image3.png',
'image4.png',
'image5.png',
'image6.png'
];
reflectionCube = new THREE.CubeTextureLoader().load( cubeMaterials );
reflectionCube.format = THREE.RGBFormat;
scene.background = reflectionCube;
}
-- example1.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>test</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 {
margin: 0px;
background-color: #000000;
overflow: hidden;
}
</style>
</head>
<body>
<script src="three.js"></script>
<script>
var camera, scene, renderer;
var mesh;
init();
animate();
function init() {
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
.shadowMap.type = THREE.PCFShadowMap;
scene = new THREE.Scene();
envMap( scene );
document.body.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 );
renderer.render( scene, camera );
}
</script>
</body>
</html>
That code won't work my friend. Try to add a camera, lights and so on.
Help us to help you...
Related
I have rendered a simple cube in Three.JS to the screen, now the way I have found online is that I need to use PointerLockControls.js lock the mouse and look around the scene. I have managed to look the cursor and hide it using this, however I am unsure how I go about implementing "look around"
Here is my code so far:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
</style>
</head>
<body>
<script src="javascript/three.js"></script>
<script src="javascript/PointerLockControls.js"></script>
<script>
var scene, camera, renderer, geometry, material, cube;
var init = function(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
geometry = new THREE.BoxGeometry();
material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
document.addEventListener("mousedown", doMouseDown, false);
//const controls = new PointerLockControls( camera, document.body);
controls = new THREE.PointerLockControls( camera, document.body );
}
function doMouseDown(event){
controls.lock();
}
function render() {
renderer.render( scene, camera );
};
init();
render();
</script>
</body>
</html>
By "looking around", I assume you want to move the camera around?
This may be a start for you.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My first three.js app</title>
<style>
body { margin: 0; }
#js3canvas { width:800px; height:600px; }
</style>
</head>
<body>
<canvas id="js3canvas"></canvas>
<script src="javascript/three.js"></script>
<script>
var scene, camera, renderer, geometry, material, cube;
var canvaselt = document.getElementById("js3canvas");
var init = function(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, canvaselt.clientWidth/canvaselt.clientHeight, 0.1, 1000 );
renderer = new THREE.WebGLRenderer( { canvas:canvaselt } );
renderer.setSize(canvaselt.clientWidth, canvaselt.clientHeight);
geometry = new THREE.BoxGeometry();
material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
canvaselt.addEventListener("mousemove", doMouseMove, false);
}
function doMouseMove(ev) { // point camera
camera.lookAt((ev.pageX-400)/100, -(ev.pageY-300)/100, 0);
}
function animate() { // need to animate, not just render once
renderer.render( scene, camera );
requestAnimationFrame( animate );
}
init();
animate();
</script>
</body>
</html>
I am trying to change the color of 3D object where intersected using color picker.I am trying with dat.gui.I want to change the color of 3d part where it gets clicked and change the selected from the colorPicker.I tried out some possible ways but it doesn't work out.Please,refer to the code I tried out. Help me out with some solution and draw my attention to where I am getting wrong. Thanks.
<!DOCTYPE html>
<html lang="en">
<head>
<title>color</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="Detector.js"></script>
<script src="stats.min.js"></script>
<script src="loaders/MTLLoader.js"></script>
<script src="loaders/OBJLoader.js"></script>
<script type='text/javascript' src='DAT.GUI.min.js'></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, controls, scene, renderer,effectController;
var raycaster;
var objects = [];
var selectedObject,selectedPos;
var rotation;
var pos,quat;
var INTERSECTED;
var guiColor;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 15;
controls = new THREE.OrbitControls( camera );
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x555000 );
scene.add( camera );
// light
var dirLight = new THREE.DirectionalLight( 0xffffff );
dirLight.position.set( 200, 200, 1000 ).normalize();
camera.add( dirLight );
camera.add( dirLight.target );
var mtlLoader = new THREE.MTLLoader(); mtlLoader.setBaseUrl('assets/'); mtlLoader.setPath('assets/'); mtlLoader.load('anno.mtl', function (materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.setPath('assets/');
objLoader.load('anno.obj', function (object) {
scene.add( object );
objects.push( object );
});
});
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
/* Controls */
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.enableZoom = false;
raycaster = new THREE.Raycaster();
gui = new dat.GUI();
parameters =
{
color: "#ff0000",
};
gui.add( parameters, 'reset' ).name("Reset");
guiColor = gui.addColor( parameters, 'color' ).name('Color');
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
stats = new Stats();
container.appendChild( stats.dom );
window.addEventListener( 'resize', onWindowResize, false );
renderer.domElement.addEventListener("click", onclick, false);
}
var mouse = new THREE.Vector2();
function onclick(event) {
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(objects, true);
if (intersects.length > 0) {
INTERSECTED = intersects[0].object;
if ( INTERSECTED && INTERSECTED.material.emissive != null ){
guiColor.onChange(function(){
INTERSECTED.material.emissive.setHex(parameters.color)
});
}
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>
I've create a little live demo with your code and a basic working solution. I'd like to highlight three important changes:
You can use the onChange() event handler in order to know when a certain dat.gui property has changed. The demo uses this feature to update the color of a selected object.
I have refactored your raycasting logic into something more simple. I've seen you've copied some code from the official three.js examples but the new code should be sufficient for your case. Besides, it's also better to update Material.color instead of Material.emissive.
If you set OrbitControls.enableDamping to true, you have to update the controls in your animation loop.
https://jsfiddle.net/btuzd23o/2/
three.js R103
I want to know on how does this website (http://www.cryptarismission.com/) do it's scene face to different directions when you move your mouse over.
On their home page, it seems that when you move your mouse, the scene follows smoothly in a very small amount of axis rotation.
What is the idea behind this thing using Three.js? I know that you can rotate object, scene or the camera but I am not sure what to rotate. I'm thinking of rotating the whole scene container but I don't know if that's good.
You can either change camera position and call lookAt in every loop depending on mouse position or change whole scene rotation. Here is how first approach works.
<!DOCTYPE html>
<html lang="en">
<head>
<title>ThreeJS full scene minimal rotation</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>
<style>
body {
margin: 0px;
padding: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<canvas></canvas>
</body>
<script>
var camera, scene, renderer, stats, windowHalfX = window.innerWidth / 2,
windowHalfY = window.innerHeight / 2,
mouseX = 0,
mouseY = 0;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.set(30, 30, 30)
scene = new THREE.Scene();
scene.add(new THREE.Mesh(
new THREE.BoxGeometry(5, 5, 5),
new THREE.MeshBasicMaterial({ color: 0x00ff00 })
));
renderer = new THREE.WebGLRenderer({ antialias: true, canvas: document.querySelector('canvas') });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
window.addEventListener('mousemove', onDocumentMouseMove, false);
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 10;
mouseY = (event.clientY - windowHalfY) / 10;
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
camera.position.x += (mouseX - camera.position.x) * .05;
camera.position.y += (-mouseY - camera.position.y) * .05;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
</script>
</html>
I render an equirectangular video on the three.js sphere and test the performance of Chromium WebVR on VIVE.
I notice that the video vibrates and shakes when I look around in VIVE. That makes me feel dizzy.
If I replace video to image, the vibration stop. I test different videos, every video vibrate. So maybe the problem happens when three.js tries to render these videos on the sphere.
I also check the fps. It's around 85~90 fps. Looks pretty good.
( Before that, I've test the same script on mobile using WebVR Boilerplate and watch video in Cardboard, it works fine. No shaking and vibration. The fps is around 50. )
While I'm testing, I accidentally figure out if I put an sphere in three.js example webvr_vive_sculp.html, the vibration reduce. Also the fps reduce to 50~60. If I limited the fps in my original script, nothing change.
Did anyone face this problem?
Here's my script:
<!DOCTYPE html>
<html lang="en">
<head>
<title>360 video in vive</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;
}
#info {
position: absolute;
top: 0px; width: 100%;
color: #ffffff;
padding: 5px;
font-family:Monospace;
font-size:13px;
font-weight: bold;
text-align:center;
}
a {
color: #ffffff;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="../build/three.js"></script>
<script src="js/controls/VRControls.js"></script>
<script src="js/effects/VREffect.js"></script>
<script src="js/vr/ViveController.js"></script>
<script src="js/vr/WebVR.js"></script>
<script>
if ( WEBVR.isAvailable() === false ) {
document.body.appendChild( WEBVR.getMessage() );
}
var camera, scene, renderer;
var effect, controls;
var video;
init();
animate();
function init() {
var container, mesh;
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1100 );
camera.target = new THREE.Vector3( 0, 0, 0 );
controls = new THREE.VRControls( camera );
controls.standing = true;
scene = new THREE.Scene();
// 360 video
video = document.createElement('video');
video.autoplay = true;
video.src = 'video/8Kevil_3840x1920_hq.webm'; // 'video/Danger in the Room.webm' // 8Kevil_3840x1920_hq
video.crossOrigin = '';
videoTexture = new THREE.Texture(video);
videoTexture.minFilter = THREE.LinearFilter;
videoTexture.magFilter = THREE.LinearFilter;
videoTexture.format = THREE.RGBFormat;
// 360 video sphere
var cubeGeometry = new THREE.SphereGeometry(500, 60, 40);
var sphereMat = new THREE.MeshBasicMaterial({map: videoTexture});
sphereMat.side = THREE.BackSide;
var cube = new THREE.Mesh(cubeGeometry, sphereMat);
scene.add(cube);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
effect = new THREE.VREffect( renderer );
if ( WEBVR.isAvailable() === true ) {
document.body.appendChild( WEBVR.getButton( effect ) );
}
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
effect.requestAnimationFrame( animate );
update();
}
function update() {
if( video.readyState === video.HAVE_ENOUGH_DATA ){
videoTexture.needsUpdate = true;
}
controls.update();
effect.render( scene, camera );
}
</script>
</body>
WebVr does not handle video textures well right now, if you pause the video the flickering stops right ?
You can try Firefox nightly, it handles video textures a little bit better, and has lower latency in general.
You can test it by opening the vive menu during the experience and shaking your head, in Chrome you'll notice much more latency between Vive's native menu performance and your experience in the dimmed background.
Try to usevideoTexture.minFilter = THREE.NearestFilter; and videoTexture.maxFilter = THREE.NearestFilter;
For the sphere use new THREE.SphereGeometry(500, 720, 4); I know it looks weird, but this way you'll get much smoother stitches on top/bottom of the sphere.
I am using the following code to render a Blender model (the default cube one just to start out) and nothing is showing up:
<html>
<head>
<title>Test page for the </title>
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
</head>
<body>
<div id="container"></div>
<script src="src/three.min.js"></script>
<script src="src/Stats.js"></script>
<script>
var camera, scene, renderer, loader;
init();
render();
function init(){
var container = document.getElementById('container');
camera = new THREE.PerspectiveCamera(10, window.innerWidth/window.innerHeight, 1, 500);
camera.position.y = 100;
camera.position.z = 100;
controls = new THREE.TrackballControls( camera );
scene = new THREE.Scene();
loader = new THREE.JSONLoader();
loader.load('obj/one.js', function (geometry){
mesh = new THREE.Mesh( geometry, new THREE.MeshNormalMaterial({overdraw: true}));
scene.add(mesh);
});
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
window.addEventListener( 'resize', onWindowResize, false );
}
function render(){
renderer.render(scene, camera);
controls.update();
stats.update();
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
</script>
</body>
</html>
Everything is placed in their paths correctly and all I get is a blank screen. Advice?
Its because you aren't animating. The collada loader is a callback function so it finishes loading well after the initial page render and then adds the object to the scene. Since there is no animation loop, the page will never redraw once the model finishes loading.