Positional Audio in WebVR

In this tutorial, we’ll learn how to use SpotLight and PositionalAudio to create a nightclub like environment in VR.

This is part of #DaysInVR series. View All VR Projects. Yesterday we learnt how to create a car showroom using collada objects in WebVR . Today we’re going to use SpotLight and PositionalAudio in WebVR to create a nightclub effect.

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 150$ for all 3 courses (SAVE 70%)

Using Spotlights to create a nightclub

We’ll use multiple SpotLights and tween its position around to create a nightclub light effect. We’ll use MeshPhongMaterial as the floor material so that it reflects the lights to create the effect.

var spotLight1 = createSpotlight(0xFF700); var spotLight2 = createSpotlight(0x00FF7F); var spotLight3 = createSpotlight(0x7F00FF); var spotLight4 = createSpotlight(0xE7C312); spotLight1.position.set(555, 10, 45); spotLight2.position.set(-15, 10, 35); spotLight3.position.set(-25, 10, 45); spotLight4.position.set(-25, 10, 25); function createSpotlight(color) { var obj = new THREE.SpotLight(color, 2); obj.castShadow = true; obj.angle = Math.PI/8; obj.penumbra = 0.2; obj.decay = 2; obj.distance = 50; obj.shadow.mapSize.width = 1024; obj.shadow.mapSize.height = 1024; return obj; } scene.add(spotLight1, spotLight2, spotLight3, spotLight4); 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 var spotLight1 = createSpotlight ( 0xFF700 ) ; var spotLight2 = createSpotlight ( 0x00FF7F ) ; var spotLight3 = createSpotlight ( 0x7F00FF ) ; var spotLight4 = createSpotlight ( 0xE7C312 ) ; spotLight1 . position . set ( 555 , 10 , 45 ) ; spotLight2 . position . set ( - 15 , 10 , 35 ) ; spotLight3 . position . set ( - 25 , 10 , 45 ) ; spotLight4 . position . set ( - 25 , 10 , 25 ) ; function createSpotlight ( color ) { var obj = new THREE . SpotLight ( color , 2 ) ; obj . castShadow = true ; obj . angle = Math . PI / 8 ; obj . penumbra = 0.2 ; obj . decay = 2 ; obj . distance = 50 ; obj . shadow . mapSize . width = 1024 ; obj . shadow . mapSize . height = 1024 ; return obj ; } scene . add ( spotLight1 , spotLight2 , spotLight3 , spotLight4 ) ;

We’ll use a tween library to move the SpotLights around.

function moveLights() { tween(spotLight1); tween(spotLight2); tween(spotLight3); tween(spotLight4); setTimeout(moveLights, 2000); } function tween(light) { new TWEEN.Tween(light).to({ angle: (Math.random() * 0.7) + 0.1, penumbra: Math.random() + 1 }, Math.random() * 3000 + 2000) .easing( TWEEN.Easing.Quadratic.Out ).start(); new TWEEN.Tween( light.position ).to( { x: ( Math.random() * 30 ) - 15, y: ( Math.random() * 10 ) + 15, z: ( Math.random() * 30 ) - 15 }, Math.random() * 3000 + 2000 ) .easing( TWEEN.Easing.Quadratic.Out ).start(); } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 function moveLights ( ) { tween ( spotLight1 ) ; tween ( spotLight2 ) ; tween ( spotLight3 ) ; tween ( spotLight4 ) ; setTimeout ( moveLights , 2000 ) ; } function tween ( light ) { new TWEEN . Tween ( light ) . to ( { angle : ( Math . random ( ) * 0.7 ) + 0.1 , penumbra : Math . random ( ) + 1 } , Math . random ( ) * 3000 + 2000 ) . easing ( TWEEN . Easing . Quadratic . Out ) . start ( ) ; new TWEEN . Tween ( light . position ) . to ( { x : ( Math . random ( ) * 30 ) - 15 , y : ( Math . random ( ) * 10 ) + 15 , z : ( Math . random ( ) * 30 ) - 15 } , Math . random ( ) * 3000 + 2000 ) . easing ( TWEEN . Easing . Quadratic . Out ) . start ( ) ; }

Adding Speaker and Positional Audio to VR

We’ll add a speaker object as our sound source in the Scene . Adding an object is similar to the movie theatre in VR tutorial we did on before. We’ll position the object in front of the camera.

var mtlLoader = new THREE.MTLLoader(); mtlLoader.setPath('/projects/day15/'); mtlLoader.setTexturePath('/projects/day15/'); mtlLoader.load('speaker.mtl', function(materials) { materials.preload(); var objLoader = new THREE.OBJLoader(); objLoader.setMaterials(materials); objLoader.setPath('/projects/day15/'); objLoader.load('speaker.obj', function(object) { object.position.z = -15; object.position.x = 3; object.position.y = 0; object.rotation.y = 3 * Math.PI/2; scene.add(object); }); }); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var mtlLoader = new THREE . MTLLoader ( ) ; mtlLoader . setPath ( '/projects/day15/' ) ; mtlLoader . setTexturePath ( '/projects/day15/' ) ; mtlLoader . load ( 'speaker.mtl' , function ( materials ) { materials . preload ( ) ; var objLoader = new THREE . OBJLoader ( ) ; objLoader . setMaterials ( materials ) ; objLoader . setPath ( '/projects/day15/' ) ; objLoader . load ( 'speaker.obj' , function ( object ) { object . position . z = - 15 ; object . position . x = 3 ; object . position . y = 0 ; object . rotation . y = 3 * Math . PI / 2 ; scene . add ( object ) ; } ) ; } ) ;

For playing sound, we need an AudioListener , AudioLoader and PositionalAudio . We’ll add AudioListener to the camera, load the audio and use PositionalAudio in WebVR to place in at the speaker’s location. That way when the user moves his head, it feels like the audio is coming from the speaker.

var listener = new THREE.AudioListener(); camera.add( listener ); var sound = new THREE.PositionalAudio( listener ); var audioLoader = new THREE.AudioLoader(); audioLoader.load('dance.mp3', function( buffer ) { sound.setBuffer( buffer ); sound.setRefDistance( 30 ); sound.setLoop(true); sound.play(); }); 1 2 3 var listener = new THREE . AudioListener ( ) ; camera . add ( listener ) ; var sound = new THREE . PositionalAudio ( listener ) ; var audioLoader = new THREE . AudioLoader ( ) ; audioLoader . load ( 'dance.mp3' , function ( buffer ) { sound . setBuffer ( buffer ) ; sound . setRefDistance ( 30 ) ; sound . setLoop ( true ) ; sound . play ( ) ; } ) ;

Its your turn

Create your own customization of nightclub VR. Try adding different lights and multiple PositionalAudio . Don’t forget to share your experience with it in the comments below.