Raycasting in WebVR – Using Threejs to select objects using raycasting
Raycasting in WebVR
In this tutorial, we’ll be using raycasting in WebVR to select objects. We’ll make use of THREE.Raycaster
for this.
This is part of #DaysInVR series. View All VR Projects. Yesterday, we learnt how to create glitch effect in WebVR. Today, we’ll see how to use raycasting in WebVR to select objects.
Join 6000+ Students
Upgrade your programming skills to include Virtual Reality. A premium step-by-step training course to get you building real world Virtual Reality apps and website components. You’ll have access to 40+ WebVR & Unity lessons along with their source code.
Start Learning Now
Adding objects in WebVR
We’ll be using the same objects from our shopping in VR tutorial for our scene. We’ll use OBJLoader
and MTLLoader
to load the objects to the scene. We’ll then use TextGeometry
and FontLoader
to add text to our scene.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
var object1; var mtlLoader = new THREE.MTLLoader(); mtlLoader.setPath('/projects/day16/dancer07/'); mtlLoader.setTexturePath('/projects/day16/dancer07/'); mtlLoader.load('dancer07.mtl', function(materials) { materials.preload(); var objLoader = new THREE.OBJLoader(); objLoader.setMaterials(materials); objLoader.setPath('/projects/day16/dancer07/'); objLoader.load('dancer07.obj', function(object) { object.position.y = -3; object.position.z = -10; scene.add(object); object1 = object; spotLight1.target = object; scene.add(spotLight1); }); }); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
var fontLoader = new THREE.FontLoader().load('helvetiker_regular.typeface.json', function(font) { // title of first item var name1Geo = new THREE.TextGeometry('Dress', { font: font, size: 0.3, bevelEnabled: false, height: 0 }); name1 = new THREE.Mesh(name1Geo, textMaterial); name1.position.set(1, 2, -10); name1.name = 'name1'; scene.add(name1); objectsArray.push(name1); }); |
Adding Raycasting in WebVR
For the raycaster, we’ll provide it with list of objects that it can intersect with. We’ll use ArrowHelper
to visualize the ray from the camera.
1 2 3 4 5 6 |
var raycaster = new THREE.Raycaster(); var arrow = new THREE.ArrowHelper( raycaster.ray.direction, raycaster.ray.origin, 100, Math.random() * 0xffffff ); scene.add( arrow ); |
Inside the animate
function, we’ll add the following.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
// update the position of arrow arrow.setDirection(raycaster.ray.direction); // update the raycaster raycaster.set(camera.getWorldPosition(), camera.getWorldDirection()); // intersect with all scene meshes. var intersects = raycaster.intersectObjects(scene.children); intersectedObject = intersects; if (intersects.length > 0) { // if the ray intersects with the object 1 text, start rotating the object if (intersects[0].object.name === 'price1' || intersects[0].object.name === 'name1') { var timer = Date.now() * 0.0005; if (object1 && object1.rotation) { object1.rotation.y = Math.cos( timer ) * 3; object1.updateMatrix(); } } if (intersects[0].object.name === 'price2' || intersects[0].object.name === 'name2') { var timer = Date.now() * 0.0005; if (object2 && object2.rotation) { object2.rotation.y = Math.cos( timer ) * 3; object2.updateMatrix(); } } if (intersects[0].object.name === 'price3' || intersects[0].object.name === 'name3') { var timer = Date.now() * 0.0005; if (object3 && object3.rotation) { object3.rotation.y = Math.cos( timer ) * 3; object3.updateMatrix(); } } if (INTERSECTED != intersects[0].object) { // when intersected, update the color of text intersects[0].object.material.color.set(0xff0000); if (INTERSECTED) INTERSECTED.material.emissive.setHex( INTERSECTED.currentHex ); INTERSECTED = intersects[0].object; INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex(); INTERSECTED.material.emissive.setHex( 0xff0000 ); } } else { // update the color when the ray is no longer intersecting if (INTERSECTED) INTERSECTED.material.color.set(0xffffff); INTERSECTED = null; for (var j = 0; j < intersectedObject.length; j ++) { intersectedObject[j].object.material.color.set(0xffffff); } } |
If the user points the ray over the text, the object will start rotating. Once the ray moves away from the text, we remove the effect.
Its your turn
Try adding more objects to the scene and interact with them using raytracing in WebVR. Don’t forget to share your experiences in the comments below.
Download Source Code
Kickstart VR development by downloading source code for this project. You’ll have instant access to source code and asset files. You can use them in your personal or commercial projects.
Leave a Reply