I’m trying to make a piece using three js where the object tilts away from the mouse on mouseover, like the locations here (mouse over the VIST tab):
https://meowwolf.com/explore
I don’t know whether this utilized three js or another library, but I don’t know how to go about it. I can’t find any examples on three js.org with the same “tilt away” technology.
So far Im just working with the basic cube example, but ultimately want to be able to "tilt" other objects/particles.
var camera, scene, renderer;
var mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 400;
scene = new THREE.Scene();
var texture = new THREE.TextureLoader().load( 'textures/crate.gif' );
var geometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
var material = new THREE.MeshBasicMaterial( { map: texture } );
mesh = new THREE.Mesh( geometry, 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 );
How can I do this, starting with just a box?
FOR CLARITY:
The meow wolf site has the objects tilt toward the corner of the object where the mouse is, and lerp back to original rotation when mouse exits
Related
I'm trying to load images with TextureLoader and I have a big problem. I don't know how I can add images to mesh in scale 1:1 and how I can calculate PlaneGeometry. I want to display the loaded image in its original size without function scaling. It is very important that the image is displayed in its original size without distortions and blurring.
My code:
function init() {
container = document.getElementById('cad-view');
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xffffff );
height = $('.page-footer').offset().top - $('.frame-wrap').offset().top - $('.frame-wrap').outerHeight();
camera = new THREE.PerspectiveCamera( 70, window.screen.width / height, 1, 5000 );
camera.position.z = 1;
camera.position.x = 100;
camera.position.y = 0;
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
var loader = new THREE.TextureLoader();
var mapGeometry = new THREE.PlaneGeometry(1.052, 0.6329);
var imageMap = new THREE.MeshBasicMaterial({ map: loader.load('mapa.jpg') });
var objectMap = new THREE.Mesh(mapGeometry, imageMap);
console.log(objectMap);
objectMap.position.set(100,0,0);
scene.add(objectMap);
objects.push( objectMap );
controls = new DragControls( [ ... objects ], camera, renderer.domElement );
controls.addEventListener( 'drag', render );
window.addEventListener( 'resize', onWindowResize );
document.addEventListener( 'click', onClick );
window.addEventListener( 'keydown', onKeyDown );
window.addEventListener( 'keyup', onKeyUp );
render();
}
Thank you a lot for any help :)
If you're stretching a square plane with PlaneGeometry(1.052, 0.6329), then you have two options:
Resize your original texture in image-editing software so it matches that aspect ratio.
Use the Texture.repeat() attribute to make the texture scale. You'll have to get your aspect ratio, then use that. I'm not sure of the math, but I think it's something like:
const texture = loader.load('mapa.jpg');
const ratio = 0.6329 / 1.052;
texture.repeat.set(1, ratio);
var imageMap = new THREE.MeshBasicMaterial({map: texture});
Read more about texture.repeat in the docs.
I am working on 3D Modelling using Thrre.js , and have to display neat and clean product after reading a .DAE file but my product display is not well clean and good . Can anybody please help me , i have also given the light sources but still product shown are very dull .Actual product to be shown
My product image render screen shot , no leather is shown in product and also very dull
I am trying following Code :
<script>
var renderer, scene, camera, controls, light;
var geometry, material, mesh;
init();
animate();
function init() {
document.body.style.cssText = 'margin: 0; overflow: hidden' ;
renderer = new THREE.WebGLRenderer( { alpha: 1, antialias: true, clearColor: 0xffffff } );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 50000 );
camera.position.set( 100, 100, 100 );
//camera.position.set(-15, 10, 15);
controls = new THREE.TrackballControls( camera, renderer.domElement );
scene.add(camera);
light = new THREE.AmbientLight(0xffffff, 10);
light.position.set(100,100, 100).normalize();
scene.add(light);
light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(10, 10, 10).normalize();
scene.add(light);
var pointlight = new THREE.PointLight(0xffffff, 1, 0);
pointlight.position.set(50, 100, 50)
camera.add(pointlight);
scene.add(pointlight);
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(10,10,10);
scene.add(spotLight);
var pointHelper = new THREE.PointLightHelper(pointlight, 0.1);
scene.add(pointHelper);
this.renderer.render(this.scene, this.camera);
geometry = new THREE.BoxGeometry( 10, 10, 10 );
material = new THREE.MeshLambertMaterial( { ambient: 0x333333, color: 0x888888, opacity: 0.000001, transparent: true } );
// material = new THREE.MeshLambertMaterial({ color: 0xffffff, vertexColors: THREE.FaceColors });
mesh = new THREE.Mesh( geometry, material );
mesh.name = 'basic template mesh';
mesh.visible = false;
scene.add( mesh );
}
function animate() {
requestAnimationFrame( animate );
renderer.render( scene, camera );
controls.update();
}``
Through this code , i got the very dull product.
Can Anyone Please help me to sort out this problem ?
You are using the wrong material. The MeshLambertMaterial is used for diffuse surfaces, those that do not have specular highlights (paper, raw wood, cloth). You need to use the MeshPhongMaterial which allows the specular highlights (white spots) in the chair.
In your model, you have two types of surface: leather and wood. Even though both of them have specular highlights, their shininess are different. You will have to define separate materials for both surfaces. But, since I see you have a single object, this can be difficult. You can define a single MeshPhongMaterial for both surfaces, but you will have to try several values in the parameters to get the desired effect.
I'm very new to Three.JS and 3D web dev in general what I'm trying to do is mimic this action: https://www.youtube.com/watch?v=HWSTxPc8npk&feature=youtu.be&t=7s Essentially this is a set of 3D planes and upon click the whole stack reacts and gives space around the one that's clicked.
For now, my base case is 3 planes and figuring first out if I can click the the middle one, how do I get the others to jump back smoothly as if they were pushed rather than instant appear and disappear as they do now on the click of a button.
The long term goal is to have a separate button for every plane so that on click, the selected plane will have padding around it and the rest of the planes in stack move accordingly.
I've looked into Tween.js, and CSS3D but pretty overwhelmed as a newbie. Any tutorials or tips would be greatly appreciated!
// Our Javascript will go here.
window.addEventListener( 'resize', onWindowResize, false );
function onWindowResize(){
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
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.PlaneGeometry( 3, 3, 1 );
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
var plane = new THREE.Mesh( geometry, material );
plane.rotation.y = -.7;
var material2 = new THREE.MeshBasicMaterial( { color: 0x0000ff } );
var material3 = new THREE.MeshBasicMaterial( { color: 0xff0000 } );
var plane2 = new THREE.Mesh(geometry, material2 );
plane2.rotation.y = -.7;
plane2.position.x = 1;
var plane3 = new THREE.Mesh(geometry, material3);
plane3.rotation.y = -.7;
plane3.position.x = -1;
scene.add( plane, plane2, plane3 );
camera.position.z = 5;
function render() {
requestAnimationFrame( render );
// cube.rotation.x += 0.1;
// cube.rotation.y += 0.1;
renderer.render( scene, camera );
}
render();
function clickFirst() {
TWEEN.removeAll();
var tween = new TWEEN.Tween(plane3.position).to({x: -2}, 1000).start();
tween.easing(TWEEN.Easing.Elastic.InOut);
render();
}
</script>
<button onclick="clickFirst();" style="background-color: white; z-index: 9999;">Click me</button>
First, you need to locate the 2 planes.
Second, you need to make the planes clickable:
https://threejs.org/examples/#webgl_interactive_cubes
https://github.com/josdirksen/learning-threejs/blob/master/chapter-09/02-selecting-objects.html
Third, you should use Tween.js for the transition.
after picking the right plane, make a tween for the other planes with a tween, all to move on the same Axis:
example:
createjs.Tween.get(plane3.position.z).to(
plane3.position.z + 100
, 1000, createjs.Ease.cubicOut)
If you will add some code here after starting to implement i would be able to help more.
I am making my first steps coding with JavaScript and playing with Three.js.
I am experimenting with this example from threejs.org :http://threejs.org/examples/#misc_controls_deviceorientation
and this is the code that they have:
(function() {
"use strict";
window.addEventListener('load', function() {
var container, camera, scene, renderer, controls, geometry, mesh;
var animate = function(){
window.requestAnimationFrame( animate );
controls.update();
renderer.render(scene, camera);
};
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1100);
controls = new THREE.DeviceOrientationControls( camera );
scene = new THREE.Scene();
var geometry = new THREE.SphereGeometry( 500, 16, 8 );
geometry.scale( - 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( {
map: new THREE.TextureLoader().load( 'textures/2294472375_24a3b8ef46_o.jpg' )
} );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
var geometry = new THREE.BoxGeometry( 100, 100, 100, 4, 4, 4 );
var material = new THREE.MeshBasicMaterial( { color: 0xff00ff, side: THREE.BackSide, wireframe: true } );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.domElement.style.position = 'absolute';
renderer.domElement.style.top = 0;
container.appendChild(renderer.domElement);
window.addEventListener('resize', function() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}, false);
animate();
}, false);
})();
I am trying to control an object that I made with the orientation of a mobile device. I can do it, is just change this line
controls = new THREE.DeviceOrientationControls( camera );
for this line: controls = new THREE.DeviceOrientationControls( object );
But now, my problem is that It changes the initial rotation of the object:
It should be like this:
And I see this in my desktop:
And this in a mobile device:
I tryied to change the DeviceOrientationControls file but is not the best way I think.
Then I found this in Stack Overflow Orbiting around the origin using a device's orientation and they said that is not possible to do it with control device orientation, its necessary to modify the Orbit Controls, and it is very complicated too.
So my question is: Is there a simple way to change the initial rotation of an object and to limit it too? Using DeviceOrientationControls.js
EDIT
I found a way to make it without using the device orientation controls. I used this:
window.addEventListener('deviceorientation', function(e) {
var gammaRotation = e.gamma ? e.gamma * (Math.PI / 600) : 0;
monogram.rotation.y = gammaRotation;
});
It works perfectly when I use my device in a vertical position,but when I use it in landscape position it doesn't work. Do you have a suggestion?
I'm trying to detect collision with terrain, that is created by modifying plane's verticles heights.
But Raycaster detects collision correctly only in about 10% of all attempts.
You can see one of those intersections, that does not detect properly on following example:
http://cerno.ch/~kamen/threejs/test.html
What am I doing wrong?
EDIT: Here's jsfiddle
var camera, scene, renderer, gump = 0;
var geometry, material, mesh, map, axis, ray;
init();
animate();
function init() {
//Create cam, so we can see what's happening
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.x = 500;
camera.position.y = 300;
//Init scene
scene = new THREE.Scene();
//Load terrain material
material = new THREE.MeshBasicMaterial( { color: 0xff6666, wireframe: false } );
geometry = new THREE.PlaneGeometry(128, 128, 127, 127);
mesh = new THREE.Mesh( geometry, material );
mesh.scale.set(50,50,50);
mesh.rotation.x = -Math.PI/2;
scene.add( mesh );
//Create axis with position and rotation of ray
axis = new THREE.AxisHelper( 100 );
axis.position = new THREE.Vector3(333.2637, 216.6575, -515.6349);
axis.rotation = new THREE.Vector3(1.6621025025, 0.119175114, -2.2270436357);
axis.scale.z = 10;
scene.add(axis);
//Create actual ray, use axis position and rotation
ray = new THREE.Raycaster();
ray.ray.origin.copy(axis.position);
ray.ray.direction.copy(axis.rotation);
//Renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
if (mesh)
{
var intersecionts = ray.intersectObject(mesh);
if (intersecionts.length > 0)
{
//Never actually happens
console.log("OK");
}
//Move axis so you can see, that it clearly goes throught mesh object
axis.translateZ(Math.cos(gump) * 2);
gump += 0.01;
//Focus camera on axis
camera.lookAt(axis.position);
}
renderer.render( scene, camera );
}
http://jsfiddle.net/BAGnd/
EDIT: Adding system specs as requested:
Windows 7 64bit
Chrome 26.0.1410
Threejs 57
Graphics card: GTX 560 Ti
Found my error.
I thought, that rotation vector, used to rotate object, and direction vector, used in ray, are same things.
After I transfer my rotation vector to direction vector, it works just fine.
How to transfer rotation vector to direction vector: How to get Orientation of Camera in THREE.js