Three.js Multiple textures and images in one scene - javascript

I am using THREE.js to display a 3d rotating earth in the browser. I also want a image to appear around the rotating earth.
I tried using the built in method,
var img = new THREE.ImageLoader();
img.load("texture/circle.png");
But the image does not appear only. It's just the rotating sphere.
I want something like this
Here is my script tag,
<script>
var container, stats;
var camera, scene, renderer;
var group;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 650;
scene = new THREE.Scene();
group = new THREE.Object3D();
scene.add( group );
// earth
var loader = new THREE.TextureLoader();
loader.load( 'textures/land_ocean_ice_cloud_2048.jpg', function ( texture ) {
var geometry = new THREE.SphereGeometry( 200, 20, 20 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
} );
// shadow
var canvas = document.createElement( 'canvas' );
canvas.width = 128;
canvas.height = 128;
var context = canvas.getContext( '2d' );
var gradient = context.createRadialGradient(
canvas.width / 2,
canvas.height / 2,
0,
canvas.width / 2,
canvas.height / 2,
canvas.width / 2
);
//gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
//gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
context.fillStyle = gradient;
context.fillRect( 0, 0, canvas.width, canvas.height );
var texture = new THREE.Texture( canvas );
texture.needsUpdate = true;
var geometry = new THREE.PlaneGeometry( 300, 300, 3, 3 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 250;
mesh.rotation.x = - Math.PI / 2;
group.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 );
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( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
//camera.position.x += ( mouseX - camera.position.x ) * 0.05;
//camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
camera.lookAt( scene.position );
group.rotation.y -= 0.003;
renderer.render( scene, camera );
}
</script>

The plane is horizontal. Remove this line:
mesh.rotation.x = - Math.PI / 2;
Make sure the gradient is set up the way you want it, e.g.,
gradient.addColorStop( 0.9, 'rgba( 210, 210, 210, 1 )' );
gradient.addColorStop( 1, 'rgba( 0, 0, 0, 0 )' );
Also, CanvasRenderer will have artifacts with intersecting objects.
three.js r.62

Related

Apply VideoTexture on a loaded .obj doesn't works three.js

I load an .obj exported from sketchup and representing a simple rectangle.
I want to apply a video texture on the front face of loaded .obj but it doesn't work and no error on the console. I'm quite stuck,the problem may come the UV, but I found nothing which can help me. I tried to use a VideoTexture but same problems.
here my code:
<div id="ThreeJS" style="position: absolute; left:0px; top:0px"></div>
<video id="video" autoplay muted loop crossOrigin="anonymous" webkit-playsinline style="display:none">
<source src="assets/output.mp4" type='video/mp4'>
</video>
<script>
var AMOUNT = 100;
var container;
var camera, scene, renderer;
var video, image, imageContext,
imageReflection, imageReflectionContext, imageReflectionGradient,
texture, textureReflection;
var mesh;
var mouseX = 0;
var mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.z = 1000;
scene = new THREE.Scene();
scene.background = new THREE.Color( 0xf0f0f0 );
video = document.createElement( 'video' );
// video.id = 'video';
// video.type = ' video/ogg; codecs="theora, vorbis" ';
video.src = "assets/output.mp4";
video.load(); // must call after setting/changing source
video.muted = true;
video.play();
//
image = document.createElement( 'canvas' );
image.width = 480;
image.height = 204;
imageContext = image.getContext( '2d' );
imageContext.fillStyle = '#000000';
imageContext.fillRect( 0, 0, 480, 204 );
texture = new THREE.Texture( image );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: 0.5 } );
imageReflection = document.createElement( 'canvas' );
imageReflection.width = 480;
imageReflection.height = 204;
imageReflectionContext = imageReflection.getContext( '2d' );
imageReflectionContext.fillStyle = '#000000';
imageReflectionContext.fillRect( 0, 0, 480, 204 );
imageReflectionGradient = imageReflectionContext.createLinearGradient( 0, 0, 0, 204 );
imageReflectionGradient.addColorStop( 0.2, 'rgba(240, 240, 240, 1)' );
imageReflectionGradient.addColorStop( 1, 'rgba(240, 240, 240, 0.8)' );
textureReflection = new THREE.Texture( imageReflection );
var materialReflection = new THREE.MeshBasicMaterial( { map: textureReflection, side: THREE.BackSide, overdraw: 0.5 } );
// var plane = new THREE.PlaneBufferGeometry( 480, 204, 4, 4 );
// mesh = new THREE.Mesh( plane, material );
// mesh.scale.x = mesh.scale.y = mesh.scale.z = 1;
// scene.add(mesh);
// mesh = new THREE.Mesh( plane, materialReflection );
// mesh.position.y = -306;
// mesh.rotation.x = - Math.PI;
// mesh.scale.x = mesh.scale.y = mesh.scale.z = 1.5;
// scene.add( mesh );
// this works
//model
var loader = new THREE.OBJLoader();
loader.load( 'assets/model3D.obj', function (object) {
var instance;
object.traverse( function (child) {
if ( child instanceof THREE.Mesh ) {
child.material = materialReflection;
child.material.needsUpdate = true;
// this doesn't works
}
});
object.position.y = - 80;
scene.add( object );
});
renderer = new THREE.CanvasRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
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( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY ) * 0.2;
}
//
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
camera.position.x += ( mouseX - camera.position.x ) * 0.05;
camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
camera.lookAt( scene.position );
if ( video.readyState === video.HAVE_ENOUGH_DATA ) {
imageContext.drawImage( video, 0, 0 );
if ( texture ) texture.needsUpdate = true;
if ( textureReflection ) textureReflection.needsUpdate = true;
}
imageReflectionContext.drawImage( image, 0, 0 );
imageReflectionContext.fillStyle = imageReflectionGradient;
imageReflectionContext.fillRect( 0, 0, 480, 204 );
renderer.render( scene, camera );
}
</script>
here my .obj:
# Alias OBJ Model File
# Exported from SketchUp, (c) 2000-2012 Trimble Navigation Limited
# File units = meters
g Mesh1 Model
usemtl FrontColor
v 12.4942 0 7.12249
vt 491.898 280.413
vn 0 -1 0
v 1.26421 0 7.12249
vt 49.7719 280.413
v 1.26421 0 0.472495
vt 49.7719 18.6021
v 12.4942 0 0.472495
vt 491.898 18.6021
f 1/1/1 2/2/1 3/3/1 4/4/1
ps: I’m beginner in three.js

How to position sprites in Three.js?

I'm currently using PointCloud to generate a particle system but within that I would like one single sprite that floats in the position of my indication. When I tried using this three.js example: http://threejs.org/examples/#webgl_sprites I found that the Orthographic Camera limited my ability to still zoom about.
var container, stats;
var camera, scene, renderer, particles, geometry, materials =[], i, h, color, sprite, size;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 55, window.innerWidth / window.innerHeight, 2, 2000 );
camera.position.z = 1000;
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2( 0x000000, 0.001 );
geometry = new THREE.Geometry();
sprite = THREE.ImageUtils.loadTexture( "disc.png" );
for ( i = 0; i < 5000; i ++ ) {
var vertex = new THREE.Vector3();
vertex.x = 2000 * Math.random() - 1000;
vertex.y = 2000 * Math.random() - 1000;
vertex.z = 2000 * Math.random() - 1000;
geometry.vertices.push( vertex );
}
// size = Math.random() * 10;
material = new THREE.PointCloudMaterial( { size: 5, sizeAttenuation: false, map: sprite, alphaTest: 0.5, transparent: true } );
particles = new THREE.PointCloud( geometry, material );
scene.add( particles );
var map2 = THREE.ImageUtils.loadTexture( "astronaut.png" );
var material2 = new THREE.SpriteMaterial( { map: map2, color: 0xffffff, fog: true } );
var sprite2 = new THREE.Sprite( material2 );
sprite2.position.x = 0;
sprite2.position.y = 0;
sprite2.position.z = 498;
scene.add( sprite2 );
//
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild( renderer.domElement );
//
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'touchstart', onDocumentTouchStart, false );
document.addEventListener( 'touchmove', onDocumentTouchMove, 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( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = event.clientX - windowHalfX;
mouseY = event.clientY - windowHalfY;
}
function onDocumentTouchStart( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
function onDocumentTouchMove( event ) {
if ( event.touches.length == 1 ) {
event.preventDefault();
mouseX = event.touches[ 0 ].pageX - windowHalfX;
mouseY = event.touches[ 0 ].pageY - windowHalfY;
}
}
//
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
var time = Date.now() * 0.00005;
camera.position.x += ( mouseX - camera.position.x ) * 0.05;
camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
camera.lookAt( scene.position );
h = ( 360 * ( 1.0 + time ) % 360 ) / 360;
renderer.render( scene, camera );
}
My attempt at solving it was:
var map2 = THREE.ImageUtils.loadTexture( "astronaut.png" );
var material2 = new THREE.SpriteMaterial( { map: map2, color: 0xffffff, fog: true } );
var sprite2 = new THREE.Sprite( material2 );
sprite2.position.x = 0;
sprite2.position.y = 0;
sprite2.position.z = 498;
scene.add( sprite2 );
Right now the sprite is in the center of the screen when I first load but instantly disappears when I begin to move the camera. Ideally, I would like the astronaut.png sprite to move with the other particles but if this is difficult, having him always fixed to the center of the screen would work fine as well.
Resolved this on my own. I created a second THREE.Geometry and THREE.Vector3 an positioned it with vertices.
geometry2 = new THREE.Geometry();
var vertex2 = new THREE.Vector3(0, 0, -50);
geometry2.vertices.push( vertex2 );
var material2 = new THREE.PointCloudMaterial( { size: 100, sizeAttenuation: false, map: map2, alphaTest: 0.5, transparent: true } );
particles2 = new THREE.PointCloud( geometry2, material2 );
scene.add( particles2 );
It seems to me that your values for mouse position would be way too high for camera positions. OpenGL works on the (-1,1) (1,1) (1,-1) (-1,-1) bounding rectangle as a unit. Pixels for your cursor position are in screen pixels like 350,720 etc.
When you increment by the half distance, your numbers are still too large. So here you have to divide by your width/height:
camera.position.x += ( mouseX / window.innerWidth- camera.position.x ) * 0.05;
camera.position.y += ( - mouseY /window.innerHeight- camera.position.y ) * 0.05;
assuming your GL portal is the same size as the window.

Adding clickable image to a mesh

This may be a really stupid question, but I am new to three.js and while I've gotten the obj file to load on the web and be controllable via mouse, I'm not quite sure how to handle the next step.
What I'd really like to do is overlay a clickable .jpg or .png file over a section of the existing mesh linking out to some web pages I already have completed. How would I go about doing this? I'd appreciate it if someone could point me to an example or let me know if it's not doable so I can look for possible alternatives.
The code I currently have is below -- it's mostly cobbled together from online example so forgive me if it seems redundant or inelegant.
var container, stats;
var camera, scene, renderer;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 10;
controls = new THREE.TrackballControls( camera );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [ 65, 83, 68 ];
controls.addEventListener( render );
// scene
scene = new THREE.Scene();
var ambient = new THREE.AmbientLight( 0xFFFFFF );
scene.add( ambient );
/*var directionalLight = new THREE.DirectionalLight( 0xffffff );
directionalLight.position.set( 1, 1, 0 ).normalize();
scene.add( directionalLight );*/
var hemisphereLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, .70);
scene.add( hemisphereLight );
// model
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 ) {
};
THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
THREE.Loader.Handlers.add( /\.dds$/i, new THREE.DDSLoader() );
var loader = new THREE.OBJMTLLoader();
loader.load( 'obj/test/test_model.obj', 'obj/test/test_model.mtl', function ( object ) {
object.scale = new THREE.Vector3( 25, 25, 25 );
//object.position.y = - 80;
scene.add( object );
}, onProgress, onError );
//
renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize( window.innerWidth, window.innerHeight );
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( window.innerWidth, window.innerHeight );
controls.handleResize();
}
function onDocumentMouseMove( event ) {
// mouseX = ( event.clientX - windowHalfX ) / 2;
// mouseY = ( event.clientY - windowHalfY ) / 2;
}
//
function animate() {
requestAnimationFrame( animate );
controls.update();
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 );
}
In your onDocumentMouseMove - or in a click event - you must compute a ray-picking intersection with http://threejs.org/docs/#Reference/Core/Raycaster and handle the reaction from there.
There are multiples examples of this, in the Three.js examples (like http://threejs.org/examples/#webgl_geometry_terrain_raycast) and on StackOverflow.
A very naive solution could be:
// note that you may have to use other properties if the renderer is not fullscreen"
// like here http://stackoverflow.com/questions/13542175/three-js-ray-intersect-fails-by-adding-div
var mouseX = ( event.clientX / window.innerWidth ) * 2 - 1;
var mouseY = -( event.clientY / window.innerHeight ) * 2 + 1;
var vector = new THREE.Vector3( mouseX, mouseY, camera.near );
// Convert the [-1, 1] screen coordinate into a world coordinate on the near plane
vector.unproject( camera );
var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
// See if the ray from the camera into the world hits one of our meshes
var intersects = raycaster.intersectObjects( scene, true ); // true for recursive
// Toggle rotation bool for meshes that we clicked
if ( intersects.length > 0 ) {
var clickedObject = intersects[ 0 ].object;
// here, handle the clickedObject properties to react accordingly
// show an overlay, jump to a page, etc..
}

Three.js - Applying a texture( 2D png image ) around 3D sphere appears black

I am using THREE.js to display a 3d rotating earth in the browser.
I also want a image to appear around the rotating earth.
I tried a few methods but they didnt work at all.
I used the image loader but it shows nothing.
var img = new THREE.ImageLoader();
img.load("texture/circle.png");
I basically wanted something like this, http://imgur.com/AV28hq6
The globe is working well, I just need to have the circular image over it as seen in the picture.
Here is my script tag,
<script>
var container, stats, raycaster;
var camera, scene, renderer;
var group;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.getElementById( 'container' );
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 500;
scene = new THREE.Scene();
group = new THREE.Object3D();
scene.add( group );
// earth
var loader = new THREE.TextureLoader();
loader.load( 'textures/1.jpg', function ( texture ) {
var geometry = new THREE.SphereGeometry( 200, 20, 20 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
raycaster = new THREE.Raycaster();
} );
// shadow
var canvas = document.createElement( 'canvas' );
canvas.width = 128;
canvas.height = 128;
var context = canvas.getContext( '2d' );
var gradient = context.createRadialGradient(
canvas.width / 2,
canvas.height / 2,
0,
canvas.width / 2,
canvas.height / 2,
canvas.width / 2
);
//gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
//gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
context.fillStyle = gradient;
context.fillRect( 0, 0, canvas.width, canvas.height );
var texture = new THREE.Texture( canvas );
texture.needsUpdate = true;
var geometry = new THREE.PlaneGeometry( 300, 300, 3, 3 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 250;
//mesh.rotation.x = - Math.PI / 2;
group.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 );
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( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
}
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
//camera.position.x += ( mouseX - camera.position.x ) * 0.05;
//camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
camera.lookAt( scene.position );
group.rotation.y -= 0.001;
renderer.render( scene, camera );
}
</script>
if you looking for some thing like this....Your code might need changes... check this link..http://jsfiddle.net/MP6BF/
var container, stats, raycaster;
var camera, scene, renderer;
var group;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
init();
animate();
function init() {
container = document.createElement('div');
document.body.appendChild(container);
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 2000 );
camera.position.z = 500;
scene = new THREE.Scene();
group = new THREE.Object3D();
scene.add( group );
// earth
var loader = new THREE.TextureLoader();
//loader.load( 'http://i.imgur.com/AV28hq6.jpg', function ( texture ) {
loader.load('http://www.joshcarllewis.com/static/articles/html5-3d-canvas-tutorial/earth.jpg',function(texture){
var geometry = new THREE.SphereGeometry( 200, 25, 200 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var mesh = new THREE.Mesh( geometry, material );
group.add( mesh );
raycaster = new THREE.Raycaster();
} );
loader.load( 'http://i.imgur.com/AV28hq6.jpg', function ( texture ) {
var geometry = new THREE.PlaneGeometry( 600, 575, 30, 30 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.z = 100;
//mesh.rotation.x = - Math.PI / 2;
scene.add( mesh );
});
// shadow
var canvas = document.createElement( 'canvas' );
canvas.width = 128;
canvas.height = 128;
var context = canvas.getContext( '2d' );
var gradient = context.createRadialGradient(
canvas.width / 2,
canvas.height / 2,
0,
canvas.width / 2,
canvas.height / 2,
canvas.width / 2
);
//gradient.addColorStop( 0.1, 'rgba(210,210,210,1)' );
//gradient.addColorStop( 1, 'rgba(255,255,255,1)' );
context.fillStyle = gradient;
context.fillRect( 0, 0, canvas.width, canvas.height );
var texture = new THREE.Texture( canvas );
texture.needsUpdate = true;
var geometry = new THREE.PlaneGeometry( 300, 300, 3, 3 );
var material = new THREE.MeshBasicMaterial( { map: texture, overdraw: true } );
var mesh = new THREE.Mesh( geometry, material );
mesh.position.y = - 250;
//mesh.rotation.x = - Math.PI / 2;
scene.add( mesh );
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
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( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
mouseX = ( event.clientX - windowHalfX );
mouseY = ( event.clientY - windowHalfY );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
//camera.position.x += ( mouseX - camera.position.x ) * 0.05;
//camera.position.y += ( - mouseY - camera.position.y ) * 0.05;
camera.lookAt( scene.position );
group.rotation.y -= 0.001;
renderer.render( scene, camera );
}
Could it be that you forgot yo add some light?
/ add subtle ambient lighting
var ambientLight = new THREE.AmbientLight(0x555555);
scene.add(ambientLight);
// add directional light source
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
Hope it helps!

How to click and slide into three js cube?

i have this code which works nice and i want to add a situation that when i click on the red cube all the page "jump" closer to the cube. (maybe the camera ?).
i do not have any idea and i will hope you can help me.
In general, i want to learn how to click in one object in three js and move into a second object in my page.
this is my code :
<html>
<head>
<script src="js/three.js"></script>
</head>
<body>
<script>
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(document.body.clientWidth, document.body.clientHeight);
document.body.appendChild(renderer.domElement);
renderer.setClearColorHex(0xEEEEEE, 1.0);
renderer.clear();
renderer.shadowCameraFov = 50;
renderer.shadowMapWidth = 1024;;
renderer.shadowMapHeight = 1024;
var fov = 45; // camera field-of-view in degrees
var width = renderer.domElement.width;
var height = renderer.domElement.height;
var aspect = width / height; // view aspect ratio
var near = 1; // near clip plane
var far = 10000; // far clip plane
var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.z = -400;
camera.position.x = 200;
camera.position.y = 350;
var scene = new THREE.Scene();
var cube = new THREE.Mesh(
new THREE.CubeGeometry(50, 50, 50),
new THREE.MeshLambertMaterial({ color: 0xff0000 })
);
scene.add(cube);
cube.castShadow = true;
cube.receiveShadow = true;
var plane = new THREE.Mesh(
new THREE.PlaneGeometry(400, 200, 10, 10),
new THREE.MeshLambertMaterial({ color: 0xffffff }));
plane.rotation.x = -Math.PI / 2;
plane.position.y = -25.1;
plane.receiveShadow = true;
scene.add(plane);
var light = new THREE.SpotLight();
light.castShadow = true;
light.position.set(170, 330, -160);
scene.add(light);
var litCube = new THREE.Mesh(
new THREE.CubeGeometry(50, 50, 50),
new THREE.MeshLambertMaterial({ color: 0xffffff }));
litCube.position.y = 50;
litCube.castShadow = true;
scene.add(litCube);
renderer.shadowMapEnabled = true;
renderer.render(scene, camera);
var paused = false;
var last = new Date().getTime();
var down = false;
var sx = 0, sy = 0;
window.onmousedown = function (ev) {
down = true; sx = ev.clientX; sy = ev.clientY;
};
window.onmouseup = function () { down = false; };
window.onmousemove = function (ev) {
if (down) {
var dx = ev.clientX - sx;
var dy = ev.clientY - sy;
camera.position.x += dx;
camera.position.y += dy;
sx += dx;
sy += dy;
}
}
function animate(t) {
if (!paused) {
last = t;
litCube.position.y = 60 - Math.sin(t / 900) * 25;
litCube.position.x = Math.cos(t / 600) * 85;
litCube.position.z = Math.sin(t / 600) * 85;
litCube.rotation.x = t / 500;
litCube.rotation.y = t / 800;
renderer.clear();
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
window.requestAnimationFrame(animate, renderer.domElement);
};
animate(new Date().getTime());
onmessage = function (ev) {
paused = (ev.data == 'pause');
};
</script>
</body>
</html>
waiting for your replay,
thanks :)
You need to implement different and separated parts to do this:
Selecting an object can be done by using a Raycaster, you'll find many examples here on SO and in the three.js examples such as this one
Orienting the camera - see camera.lookAt( target.position ) - and zooming can be done in many ways, but you might want to use a kind of Control to ease the camera placement process, such as one of these. The TrackballControls for example seems appropriate.
One last bit, as your title says "sliding", is how the "camera jump" is done. If you want a smooth zoom, you'll need a kind of easing function. Have a look on Tween.js for this.
vincent wrote an excellent answer. I just want to add an example to help to understand.
Jsfiddle
<script>
var container, stats;
var camera, scene, projector, raycaster, renderer, selected;
var target, zoom=false;
var mouse = new THREE.Vector2(), INTERSECTED;
var radius = 100, theta = 0;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
scene = new THREE.Scene();
var light = new THREE.DirectionalLight( 0xffffff, 2 );
light.position.set( 1, 1, 1 ).normalize();
scene.add( light );
var light = new THREE.DirectionalLight( 0xffffff );
light.position.set( -1, -1, -1 ).normalize();
scene.add( light );
var geometry = new THREE.CubeGeometry( 20, 20, 20 );
var cube = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: '#F3B557' } ) );
cube.rotation = new THREE.Euler(0,Math.PI/4,0);
cube.position = new THREE.Vector3(-20,0,0);
scene.add(cube);
cube = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial( { color: '#F05B47' } ) );
cube.rotation = new THREE.Euler(0,Math.PI/4,0);
cube.position = new THREE.Vector3(20,0,0);
scene.add(cube);
projector = new THREE.Projector();
raycaster = new THREE.Raycaster();
renderer = new THREE.WebGLRenderer();
renderer.setClearColor( 0xf0f0f0 );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
window.addEventListener( 'resize', onWindowResize, false );
renderer.domElement.addEventListener( 'mousedown', onCanvasMouseDown, false);
}
function animate() {
requestAnimationFrame( animate );
render();
}
function render() {
// set lookAt position according to target position
if(target){
camera.lookAt( target.position );
}else{
camera.lookAt(new THREE.Vector3(0,0,0));
}
//zoom in and out
if(zoom && camera.fov>10){
camera.fov-=1;
camera.updateProjectionMatrix();
}else if(!zoom && camera.fov<70){
camera.fov+=1;
camera.updateProjectionMatrix();
}
camera.position = new THREE.Vector3(0,100,100);
// find intersections
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
raycaster.set( camera.position, vector.sub( camera.position ).normalize() );
var intersects = raycaster.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
if ( INTERSECTED != intersects[ 0 ].object ) {
if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
INTERSECTED = intersects[ 0 ].object;
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
INTERSECTED.material.emissive.setHex( 0xff0000 );
}
} else {
if ( INTERSECTED ) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex );
INTERSECTED = null;
}
renderer.render( scene, camera );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
//detect selected cube
function onCanvasMouseDown( event ){
if(INTERSECTED){
target = INTERSECTED;
zoom = true;
}else{
zoom = false;
}
}
</script>

Categories

Resources