webaudio_orientation.html 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <title>three.js webaudio - orientation</title>
  5. <meta charset="utf-8">
  6. <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  7. <link type="text/css" rel="stylesheet" href="main.css">
  8. <style>
  9. #overlay {
  10. position: absolute;
  11. top: 0;
  12. left: 0;
  13. width: 100%;
  14. height: 100%;
  15. display: flex;
  16. align-items: center;
  17. justify-content: center;
  18. opacity: 1;
  19. background-color: #000000;
  20. z-index: 1;
  21. }
  22. #overlay > div {
  23. text-align: center;
  24. }
  25. #overlay > div > button {
  26. height: 20px;
  27. width: 100px;
  28. background: transparent;
  29. color: #ffffff;
  30. outline: 1px solid #ffffff;
  31. border: 0px;
  32. cursor: pointer;
  33. }
  34. #overlay > div > p {
  35. color: #777777;
  36. font-size: 12px;
  37. }
  38. </style>
  39. </head>
  40. <body>
  41. <audio loop id="music" preload="auto" style="display: none">
  42. <source src="sounds/376737_Skullbeatz___Bad_Cat_Maste.ogg" type="audio/ogg">
  43. <source src="sounds/376737_Skullbeatz___Bad_Cat_Maste.mp3" type="audio/mpeg">
  44. </audio>
  45. <div id="overlay">
  46. <div>
  47. <button id="startButton">Click to Play</button>
  48. <p>Audio playback requires user interaction.</p>
  49. </div>
  50. </div>
  51. <div id="container"></div>
  52. <div id="info">
  53. <a href="https://threejs.org" target="_blank" rel="noopener noreferrer">three.js</a> webaudio - orientation<br/>
  54. music by <a href="http://www.newgrounds.com/audio/listen/376737" target="_blank" rel="noopener noreferrer">skullbeatz</a>
  55. </div>
  56. <script type="module">
  57. import {
  58. AudioListener as _AudioListener, // we don't want to override the native AudioListener function
  59. BoxBufferGeometry,
  60. Color,
  61. CubeTextureLoader,
  62. DirectionalLight,
  63. Fog,
  64. HemisphereLight,
  65. GridHelper,
  66. MeshBasicMaterial,
  67. MeshPhongMaterial,
  68. Mesh,
  69. PerspectiveCamera,
  70. PlaneBufferGeometry,
  71. PositionalAudio,
  72. PositionalAudioHelper,
  73. RGBFormat,
  74. Scene,
  75. WebGLRenderer
  76. } from "../build/three.module.js";
  77. import { OrbitControls } from './jsm/controls/OrbitControls.js';
  78. import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
  79. var scene, camera, renderer;
  80. var startButton = document.getElementById( 'startButton' );
  81. startButton.addEventListener( 'click', init );
  82. function init() {
  83. var overlay = document.getElementById( 'overlay' );
  84. overlay.remove();
  85. var container = document.getElementById( 'container' );
  86. //
  87. camera = new PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.1, 100 );
  88. camera.position.set( 3, 2, 3 );
  89. var reflectionCube = new CubeTextureLoader()
  90. .setPath( 'textures/cube/SwedishRoyalCastle/' )
  91. .load( [ 'px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg' ] );
  92. reflectionCube.format = RGBFormat;
  93. scene = new Scene();
  94. scene.background = new Color( 0xa0a0a0 );
  95. scene.fog = new Fog( 0xa0a0a0, 2, 20 );
  96. //
  97. var hemiLight = new HemisphereLight( 0xffffff, 0x444444 );
  98. hemiLight.position.set( 0, 20, 0 );
  99. scene.add( hemiLight );
  100. var dirLight = new DirectionalLight( 0xffffff );
  101. dirLight.position.set( 5, 5, 0 );
  102. dirLight.castShadow = true;
  103. dirLight.shadow.camera.top = 1;
  104. dirLight.shadow.camera.bottom = - 1;
  105. dirLight.shadow.camera.left = - 1;
  106. dirLight.shadow.camera.right = 1;
  107. dirLight.shadow.camera.near = 0.1;
  108. dirLight.shadow.camera.far = 20;
  109. scene.add( dirLight );
  110. // scene.add( new CameraHelper( dirLight.shadow.camera ) );
  111. //
  112. var mesh = new Mesh( new PlaneBufferGeometry( 50, 50 ), new MeshPhongMaterial( { color: 0x999999, depthWrite: false } ) );
  113. mesh.rotation.x = - Math.PI / 2;
  114. mesh.receiveShadow = true;
  115. scene.add( mesh );
  116. var grid = new GridHelper( 50, 50, 0x888888, 0x888888 );
  117. scene.add( grid );
  118. //
  119. var listener = new _AudioListener();
  120. camera.add( listener );
  121. var audioElement = document.getElementById( 'music' );
  122. audioElement.play();
  123. var positionalAudio = new PositionalAudio( listener );
  124. positionalAudio.setMediaElementSource( audioElement );
  125. positionalAudio.setRefDistance( 1 );
  126. positionalAudio.setDirectionalCone( 180, 230, 0.1 );
  127. var helper = new PositionalAudioHelper( positionalAudio, 0.1 );
  128. positionalAudio.add( helper );
  129. //
  130. var gltfLoader = new GLTFLoader();
  131. gltfLoader.load( 'models/gltf/BoomBox/glTF-Binary/BoomBox.glb', function ( gltf ) {
  132. var boomBox = gltf.scene;
  133. boomBox.position.set( 0, 0.2, 0 );
  134. boomBox.scale.set( 20, 20, 20 );
  135. boomBox.traverse( function ( object ) {
  136. if ( object.isMesh ) {
  137. object.material.envMap = reflectionCube;
  138. object.geometry.rotateY( - Math.PI );
  139. object.castShadow = true;
  140. }
  141. } );
  142. boomBox.add( positionalAudio );
  143. scene.add( boomBox );
  144. animate();
  145. } );
  146. // sound is damped behind this wall
  147. var wallGeometry = new BoxBufferGeometry( 2, 1, 0.1 );
  148. var wallMaterial = new MeshBasicMaterial( { color: 0xff0000, transparent: true, opacity: 0.5 } );
  149. var wall = new Mesh( wallGeometry, wallMaterial );
  150. wall.position.set( 0, 0.5, - 0.5 );
  151. scene.add( wall );
  152. //
  153. renderer = new WebGLRenderer( { antialias: true } );
  154. renderer.setSize( window.innerWidth, window.innerHeight );
  155. renderer.setPixelRatio( window.devicePixelRatio );
  156. renderer.gammaOutput = true;
  157. renderer.gammaFactor = 2.2;
  158. renderer.shadowMap.enabled = true;
  159. container.appendChild( renderer.domElement );
  160. //
  161. var controls = new OrbitControls( camera, renderer.domElement );
  162. controls.target.set( 0, 0.1, 0 );
  163. controls.update();
  164. controls.minDistance = 0.5;
  165. controls.maxDistance = 10;
  166. controls.maxPolarAngle = 0.5 * Math.PI;
  167. //
  168. window.addEventListener( 'resize', onWindowResize, false );
  169. }
  170. function onWindowResize() {
  171. camera.aspect = window.innerWidth / window.innerHeight;
  172. camera.updateProjectionMatrix();
  173. renderer.setSize( window.innerWidth, window.innerHeight );
  174. }
  175. function animate() {
  176. requestAnimationFrame( animate );
  177. renderer.render( scene, camera );
  178. }
  179. </script>
  180. </body>
  181. </html>