ThreeJs的音频和位置音频

Threejs的场景有时候需要引入声音,比如下雨声音,撞击声音等,这需要用到Threejs的两个类Audio和PositionalAudio,第一个Audio是普通的声音,比如下雨,在整个场景中听到的都是下雨的声音,而且每个位置的声音都一样大小,那么就需要用Audio,也可以作为3D场景的背景音乐来用,但是如果是某个位置发生了撞击,那么应该是距离越远,听到撞击的声音越小,也就是要把声源的位置固定,把耳朵绑定到相机上,相机距离声源越远听到的声音越小,相机距离声源越近听到的声音越大,此外,如果撞击声音在左侧,那么应该左侧耳机声音更大,如果撞击发生在右侧,正好想反,下面看下整个过程:

首先创建场景:

复制代码
initScene(){
      scene = new THREE.Scene();
    },
    initCamera(){
      this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
      this.camera.position.set(10,10,10);
      this.camera.lookAt(0,0,0)
    },
    initLight(){
      //添加两个平行光
      const directionalLight1 = new THREE.DirectionalLight(0xffffff, 1.5);
      directionalLight1.position.set(300,300,600)
      scene.add(directionalLight1);
      const directionalLight2 = new THREE.DirectionalLight(0xffffff, 1.5);
      directionalLight2.position.set(600,200,600)
      scene.add(directionalLight2);
    },
initRenderer(){
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.container = document.getElementById("container")
      this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);
      this.renderer.setClearColor('#AAAAAA', 1.0);
      this.container.appendChild(this.renderer.domElement);
    },
    initControl(){
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.enableDamping = true;
      this.controls.maxPolarAngle = Math.PI / 2.2;      // // 最大角度
    },
    initAnimate() {
      requestAnimationFrame(this.initAnimate);
      this.renderer.render(scene, this.camera);
    },

然后创建监听和声音,先创建一个监听:AudioListener,再创建一个Audio加载器用来加载声音,

AudioLoader,然后播放声音就可以了,

复制代码
initAudio(){
      // 创建一个监听者
      let listener = new THREE.AudioListener();
      // 创建一个非位置音频对象  用来控制播放
      let audio = new THREE.Audio(listener);
      // 创建一个音频加载器对象
      let audioLoader = new THREE.AudioLoader();
      // 加载音频文件,返回一个音频缓冲区对象作为回调函数参数
      audioLoader.load('/static/video/music.mp3', function(AudioBuffer) {
        // 音频缓冲区对象关联到音频对象audio
        audio.setBuffer(AudioBuffer);
        audio.setLoop(true); //是否循环
        audio.setVolume(0.5); //音量
        // 播放缓冲区中的音频数据
        audio.play();
      });
    },

这里也可以用一个简单的用html隐藏一个audio标签实现,并用js控制,因为这里不会对音乐做特殊的处理,这里就不演示效果了。

再来试下位置音频,同样是加载一个监听和一个声音,但是这里为了了解音频的位置,所以先创建一个模型,将音频绑定到模型上,后面就可以通过改变相机的位置,体验下不同距离和位置对听到的声音的影响。

复制代码
initAudio(){
      let geometry = new THREE.BoxGeometry(2,2,2);
      let material = new THREE.MeshPhysicalMaterial({color:'#1c32b5'});
      let audioMesh = new THREE.Mesh(geometry, material);
      // 设置网格模型的位置,相当于设置音源的位置
      audioMesh.position.set(0, 0, 0);
      scene.add(audioMesh);
      // 创建一个虚拟的监听者
      let listener = new THREE.AudioListener();
      // 监听者绑定到相机对象
      this.camera.add(listener);
      // 创建一个位置音频对象,监听者作为参数,音频和监听者关联。
      let PosAudio = new THREE.PositionalAudio(listener);
      //音源绑定到一个网格模型上
      audioMesh.add(PosAudio);
      // 创建一个音频加载器
      let audioLoader = new THREE.AudioLoader();
      // 加载音频文件,返回一个音频缓冲区对象作为回调函数参数
      audioLoader.load('/static/video/music.mp3', function(AudioBuffer) {
        // console.log(buffer);
        // 音频缓冲区对象关联到音频对象audio
        PosAudio.setBuffer(AudioBuffer);
        PosAudio.setVolume(0.9); //音量
        PosAudio.setRefDistance(200); //参数值越大,声音越大
        PosAudio.play(); //播放
      });
    },

效果如下:

threejs场景下的音频和位置音频

相关推荐
gis分享者5 天前
学习threejs,使用自定义GLSL 着色器,实现抽象艺术特效
threejs·着色器·glsl·shadermaterial·抽象艺术
allenjiao14 天前
WebGPU vs WebGL:WebGPU什么时候能完全替代WebGL?Web 图形渲染的迭代与未来
前端·图形渲染·webgl·threejs·cesium·webgpu·babylonjs
二川bro14 天前
第59节:常见问题汇编 - 60个典型问题解答
javascript·3d·threejs
孪生引擎观星台18 天前
数字孪生如何破解效率、性能与安全困局?
安全·数字孪生·threejs
gis分享者20 天前
学习threejs,添加ECharts图表
echarts·threejs·material·图表·canvastexture·planegeometry
二川bro23 天前
第40节:AR基础:Marker识别与跟踪
ar·threejs
二川bro25 天前
第33节:程序化生成与无限地形算法
前端·算法·3d·threejs
二川bro1 个月前
第30节:大规模地形渲染与LOD技术
前端·threejs
患得患失9491 个月前
【threejs】材质共享导致的典型问题
材质·threejs
gis分享者1 个月前
学习threejs,基于噪声函数的顶点着色器动态插桩技术实现模型形变
threejs·模型·着色器·顶点·动态插桩·噪声函数·形变