Three.js进阶之音频处理与展示
引擎在对音频处理提供了丰富的接口,本文展示两个音频处理示例。
一、声音可视化
Three.js中的声音可视化是以视觉为核心,以音乐为载体,为音乐提供直观的视觉呈现。通过对音乐数据的分析并结合开发需求,能实现酷炫的视觉效果。在本节案例中,16个长方体跟随音乐的律动在y轴方向上进行缩放,效果如图12-13所示。
(1)加载音频文件,然后创建音频加载对象、音频监听对象和创建音频对象,接下来获取音乐数据,根据此数组长度创建长方体,然后进行画面的渲染,具体代码如下。
1 var file; //文件对象
2 var fileUrl; //文件链接
3 ......//此省略了初始化场景中相关变量的代码,读者可自行查看随书源代码
4 function fileChange()
5 file=document.getElementById("importFile").files[0]; //获取文件
6 fileUrl=URL.createObjectURL(file); //创建文件链接
7 document.getElementById("WebGL-output").style.display="block";//将渲染所用的div进行显示
8 document.getElementById("label1").style.display="none"; //隐藏打开文件的标签
9 addAudio(); //加载音频文件
10 }
11 ......//此处省略了初始化场景的相关方法,读者可自行查看随书源代码
12 function addAudio() {
13 var audioLoder=new THREE.AudioLoader(); //创建音频加载
14 var listener = new THREE.AudioListener(); //创建音频监听
15 var audio = new THREE.Audio( listener ); //创建音频对象
16 audioLoder.load(fileUrl, function (audioBuffer ) { //加载音频
17 audio.setBuffer( audioBuffer ); //设置音频数据
18 audio.setLoop( true ); //音频循环
19 audio.play(); //音频播放
20 });
21 analyser = new THREE.AudioAnalyser( audio, fftSize ); //音频数据分析
22 misicDataArray=analyser.data; //指定音乐数组中的数据
23 for (var i=0; i<fftSize*0.5; i++){
24 tempGeometry[i]=new THREE.BoxGeometry( 12, misicDataArray[i]/4 ,12);//创建长方体
25 material=new THREE.MeshPhongMaterial({color: getColor()});//创建随机颜色的材质
26 mesh[i]=new THREE.Mesh(tempGeometry[i], material) ; //创建物体
27 mesh[i].position.x=20*i-160; //指定物体的 x坐标
28 mesh[i].castShadow=true; //接受阴影
29 mesh[i].rotation.y= Math.PI/4; //指定绕 y轴旋转的角度
30 scene.add(mesh[i]); //将物体添加进场景
31 }
32 renderScene(); //进行渲染
33 }
❑ 第1~10行的功能为获取音频文件,创建文件链接和加载音频文件。当我们打开音频文件的时候,会调用fileChange方法,获取音频文件并创建链接,然后将渲染用div显示,隐藏打开音频文件时的提示信息。
❑ 第12~31行的功能为创建音频加载对象,音频加载监听以及音频对象,然后加载音频并对音频对象进行数据设置和播放设置,对音频进行分析,
(2)介绍渲染场景的方法。在此方法中主要通过更新音乐数据来更新物体在y轴上的缩放比例以及请求绘制下一帧画面,具体的代码如下。
1 function renderScene() { //渲染场景的方法2 analyser.getFrequencyData(); //更新音乐数据3 misicDataArray=analyser.data; //更新音乐数据4 for (var i=0; i<fftSize*0.5; i++){ //更改物体在 y轴上的缩放比例5 if(misicDataArray[i]/4==0){ //如果数据大小为06 misicDataArray[i]=4; } //数据大小为47 mesh[i].scale.y=misicDataArray[i]/4; //更新物体 y轴的缩放比例8 mesh[i].position.y=0; //指定物体的 y坐标为09 }10 renderer.render( scene, camera ); //渲染场景11 requestAnimationFrame(renderScene); //请求重新绘制场景12 }
在渲染场景的方法中,主要是通过更新音乐数据来更新物体在y轴上的缩放比例,从而实现物体随音乐律动来改变高度的功能。然后进行场景渲染,并请求重新绘制场景。
二、 声音与距离
游戏音效是游戏中的重要组成部分,其最大功用就是烘托气氛、表达情感,给玩家营造出身临其境的游戏环境。Three.js引擎能够很好地处理游戏中的声音,并且能够根据摄像机位置与物体位置之间的距离来确定声音的大小。
本案例中乒乓球运动后弹起的时候会发出声音。声音随着摄像机位置与乒乓球位置间距离的改变而改变,距离变小声音增大,距离变大声音减小,这真实地模拟出现实世界的情况。案例的具体实现过程。
(1)单击界面之后对象加载音频及创建监听,然后进行场景的初始化(包括初始化场景中的基本组件,向场景中添加物体和光照,添加鼠标控制以及添加窗口变化监听),最后隐藏提示信息标签,
具体实现代码如下:
1 var flag=true; //单击标志位2 var audioLoader; //音频加载对象3 var listener; //音频监听4 ......//此处省略了其他变量的声明,请读者自行查阅随书源代码5 document.addEventListener("mousedown", function (){ //窗口单击监听6 if(flag){ //如果可以进行单击7 audioLoader = new THREE.AudioLoader(); //创建音频加载对象8 listener = new THREE.AudioListener(); //创建音频监听对象9 init(); //初始化界面10 document.getElementById("tip").hidden=true; //隐藏提示信息11 flag=false;12 }});13 function init() { //初始化界面14 initScene(); //初始化场景的基本组件15 addMesh(); //添加物体16 addLight(); //添加光照17 addControls(); //添加鼠标控制18 document.getElementById("WebGL-output").appendChild(renderer.domElement);19 window.addEventListener( 'resize', onWindowResize, false ); //窗口变化监听20 }21 function initScene(){ //初始化场景22 scene = new THREE.Scene(); //新建场景23 renderer = new THREE.WebGLRenderer({ antialias: true } );//新建渲染器并关闭默认抗锯齿24 renderer.setClearColor(new THREE.Color(0x000000)); //设置背景颜色25 renderer.setSize(window.innerWidth, window.innerHeight);//设置渲染窗口的大小26 renderer.shadowMap.enable=true; //设置接受阴影27 renderer.shadowMap.type = THREE.PCFSoftShadowMap; //设置阴影类型28 camera = new THREE.PerspectiveCamera(60, window.innerWidth/window.innerHeight, 0.1, 1000);29 camera.position.z =20; //摄像机位置的 z坐标30 camera.position.y =15; //摄像机位置的 y坐标31 camera.add(listener); //添加音频监听32 camera.lookAt(new THREE.Vector3()); //摄像机观察目标点33 }
❑ 第1~12行中的代码声明了程序中的变量,包括音频加载对象、音频加载监听和单击标志位等,注册窗口单击监听。进入界面,单击当前窗口,触发单击事件。接下来创建音频加载对象和音频监听对象,并进行界面的初始化以及隐藏提示信息。
❑ 第13~20行的功能为初始化场景中的基本组件、添加物体,光照和鼠标控制,以及注册窗口变化监听并将渲染结果添加到网页元素中。其中添加光照和鼠标控制的代码与前面案例的相似,在此不再赘述。
❑ 第21~33行为初始化场景,创建摄像机、场景以及渲染器对象,设置摄像机的位置及观察目标的位置,并添加音频监听和设置阴影及阴影类型。在此方法中,最重要的就是给摄像机添加音频监听,这是模拟真实声音效果的前提。
单击界面之后才能进入场景,这是为了应对Google Chrome浏览器禁止声音自动播放策略的,我们只需与网页进行交互,便可以播放声音。
(2)看一下添加物体及加载音频方法的核心部分,包括加载音频,创建位置音频对象,设置音频数据,设置音频音量的大小和向场景中添加乒乓球。此外还有渲染场景的方法,此方法主要控制小球的运动以及在小球弹起时播放声音,
具体代码如下:
1 function addMesh(){ //添加物体及加载音频2 ......//此处省略了向场景中添加乒乓球台模型的代码,读者可自行查阅随书源代码3 audioLoader.load( 'music/ping_pong.mp3', function ( buffer ){ //加载音频4 var ballGeometry = new THREE.SphereGeometry(0.5,20,20); //创建球体5 var ballMaterial = new THREE.MeshLambertMaterial({color:0xffffff});//创建材质6 ball=new THREE.Mesh(ballGeometry, ballMaterial); //创建网格对象7 ball.position.x = -10; //球体的 x坐标8 ball.position.y = 8.2; //球体的 y坐标9 ball.position.z = 0; //球体的 z坐标10 ball.castShadow=true; //球体投射阴影11 var audio = new THREE.PositionalAudio( listener ); //创建位置音频12 audio.setBuffer( buffer ); //设置音频数据13 audio.setVolume(10); //设置音频的音量14 tempy=ball.position.y; //记录当前时刻球体的 y坐标15 ball.userData.flag=false; //自定义播放标志位16 ball.add( audio ); //向球体添加音频17 scene.add(ball); }); //向场景添加球体18 }19 function renderScene() { //渲染场景的方法20 requestAnimationFrame(renderScene); //请求绘制下一帧画面21 render(); //调用实际渲染场景的方法22 }23 function render() { //实际渲染场景的方法24 temp+=0.03; //增加球体运动角度25 tempy=ball.position.y; //记录当前时刻球体的 y坐标26 ball.position.y=8.2+4*Math.abs(Math.sin(temp)); //改变球体的 y坐标27 ball.position.x=10*Math.cos(temp); //改变球体的 x坐标28 var audio = ball.children[ 0 ]; //获取音频对象29 if(ball.position.y<tempy){ //如果球体 y坐标小于记录的球体 y坐标30 ball.userData.flag=true; } //播放标志位为true31 else{ if(ball.userData.flag){ //如果可以播放音频32 audio.play(); //播放音频33 ball.userData.flag=false; //播放标志位为false34 }}35 renderer.render( scene, camera ); //进行场景渲染36 }
❑ 第3~18行的代码为加载音频,创建球体网格对象,设置球体的相关属性,创建位置音频对象,设置音频数据和向球体添加音频以及向场景中添加球体。通过向球体添加音频,可将音频对象和球体关联起来。通过改变播放标志位,可以控制音频播放。
❑ 第19~36行的代码为对场景进行渲染。在实际渲染场景的方法中,在当前球体的y坐标大于改变位置后球体的y坐标值时,物体处于下落状态,播放标志位为true。反之,物体处于上升状态,音频播放一次,播放标志位为false。这可避免重复播放。
相关文章:
Three.js进阶之音频处理与展示
引擎在对音频处理提供了丰富的接口,本文展示两个音频处理示例。 一、声音可视化 Three.js中的声音可视化是以视觉为核心,以音乐为载体,为音乐提供直观的视觉呈现。通过对音乐数据的分析并结合开发需求,能实现酷炫的视觉效果。在…...
4.2 HarmonyOS NEXT分布式AI应用实践:联邦学习、跨设备协作与个性化推荐实战
HarmonyOS NEXT分布式AI应用实践:联邦学习、跨设备协作与个性化推荐实战 在HarmonyOS NEXT的全场景分布式架构下,AI能力突破设备边界,通过联邦学习保护数据隐私、跨设备任务协作释放算力潜能、个性化推荐实现服务主动化。本文结合华为分布式…...

兼容老设备!EtherNet/IP转DeviceNet网关解决储能产线通讯难题
在新能源行业飞速发展的当下,工业自动化水平的高低直接影响着企业的生产效率与产品质量。JH-EIP-DVN疆鸿智能ETHERNET/IP和DEVICENET作为工业领域常用的通信协议,它们之间的转换应用在新能源生产线上发挥着关键作用。本文重点探讨ETHERNETIP从站转DEVICE…...
健康检查:在 .NET 微服务模板中优雅配置 Health Checks
🚀 健康检查:在 .NET 微服务模板中优雅配置 Health Checks 📚 目录 🚀 健康检查:在 .NET 微服务模板中优雅配置 Health Checks一、背景与意义 🔍二、核心配置 🔧2.1 引入必要的 NuGet 依赖 &…...
【Pytorch学习笔记】模型模块08——AlexNet模型详解
AlexNet模型详解:结构、算法与PyTorch实现 一、AlexNet模型结构 AlexNet是2012年ImageNet竞赛冠军模型,由Alex Krizhevsky等人提出,标志着深度学习在计算机视觉领域的突破。 网络结构(5卷积层 3全连接层)ÿ…...

LabVIEW自感现象远程实验平台
LabVIEW开发自感现象远程实验平台,通过整合 NI数据采集设备、菲尼克斯(Phoenix Contact)继电器模块及罗技(Logitech)高清摄像头,实现远程数据采集、仪器控制与实时监控三大核心功能。平台突破传统实验装置局…...
AppTrace 视角下 App 一键拉起:提升应用转化率的高效方案
官网地址:AppTrace - 专业的移动应用推广追踪平台 在大规模开展 App 推广、用户召回、广告投放、邀请传播等活动时,高效的深度链接方案至关重要。它不仅能缩短用户路径,带来无缝、流畅的跳转体验,更核心的是通过参数传递打通 web…...
梯度下降:机器学习优化的核心算法
梯度下降算法原理及其在机器学习中的实践应用 引言 在机器学习领域,优化算法扮演着核心角色。其中梯度下降法作为最基础的优化方法,为神经网络、支持向量机等模型提供了参数优化解决方案。本文将深入解析梯度下降的数学原理,探讨其多种变体实现,并通过Python代码演示具体…...
Vue-6-前端框架Vue之基于Plotly.js绘制曲线
文章目录 1 安装Plotly.js2 折线图2.1 创建一个Vue组件来绘制图表2.1.1 Vue模板部分template2.1.2 Vue脚本部分script2.1.3 Vue样式部分style2.2 使用这个组件APP.vue3 动态更新图表3.1 创建一个Vue组件来绘制图表3.1.1 Vue模板部分template3.1.2 Vue脚本部分script3.1.3 Vue样…...

Python----目标检测(《YOLOv3:AnIncrementalImprovement》和YOLO-V3的原理与网络结构)
一、《YOLOv3:AnIncrementalImprovement》 1.1、基本信息 标题:YOLOv3: An Incremental Improvement 作者:Joseph Redmon, Ali Farhadi 机构:华盛顿大学(University of Washington) 发表时间:2018年 代…...
Redux:不可变数据与纯函数的艺术
Redux:不可变数据与纯函数的艺术 状态管理的困境 随着现代 Web 应用功能的不断扩展,前端开发者面临着日益复杂的状态管理挑战。当应用从简单的表单交互发展到复杂的单页应用时,组件间共享状态的问题变得尤为突出。想象一个电商平台…...

算法篇 八大排序(冒泡 插入 选择 堆 希尔 快排 归并 计数)
目录 引言 1.冒泡排序 思路 代码实现 2.选择排序 思路 代码实现(存在易错点) 3.插入排序 思路 代码实现 4.希尔排序 思路 代码实现 5.堆排序 思路 代码实现 6.快速排序(快排) 一.三路划分 思路 代码实现 二.自…...
技术文档写作全攻略
一、引言 在快速迭代的软件开发中,技术文档早已不只是附属品,而是与代码同等重要的交付物: 帮助新成员 T0 → T1 学习曲线指数下降;降低支持成本,将重复性问答前移到自助文档;为合规审计、知识传承及商业…...
网络安全全景解析
引言 在数字化时代,网络已深度融入社会生产生活的各个领域,成为推动经济发展和社会进步的关键力量。然而,随着网络应用的日益复杂,网络安全问题也呈现出多样化、复杂化的趋势。从个人隐私泄露到企业核心数据被盗,从基础…...

音视频之视频压缩编码的基本原理
系列文章: 1、音视频之视频压缩技术及数字视频综述 2、音视频之视频压缩编码的基本原理 一、预测编码: 1、预测编码的基本概念: 预测法是最简单、实用的视频压缩编码方法,经过压缩编码后传输的并不是像素本身的取样值࿰…...

IDEA 包分层显示设置
方法一(用的IntelliJ IDEA 2024.1.4版本): 找到项目视图设置入口:在左侧Project(项目)面板的顶部,有个三个点...的按钮 ,点击它。 进入树形外观配置:在弹出的菜单中&…...
书籍将正方形矩阵顺时针转动90°(8)0605
题目 给定一个N x N的矩阵matrix,把这个矩阵调整成顺时针转动90后的形式。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 顺时针转动90后为: 13 9 5 1 14 …...
【docker】容器技术如何改变软件开发与部署格局
在当今数字化时代,软件开发与部署的效率和灵活性至关重要。就像古人云:“工欲善其事,必先利其器。”Docker 作为一款强大的容器技术,正如同软件开发领域的一把利器,极大地改变了应用的开发、交付和运行方式。本文将深入…...
C#抽象类深度解析 _ 核心特性与实战指南
—— 面向对象设计的基石 🔍抽象类核心定义 abstract class AbClass { ... } // abstract修饰符声明 不可实例化:new AbClass() 将触发编译错误继承专用:仅能作为其他类的基类存在混合成员组合:可同时包含抽象方法和已实现方法…...
时序数据库IoTDB的UDF Sample算法在数据监控、故障预防的应用
一、数据监控在工业物联网中的重要性 设备数据监控是工业物联网(IoT)中最为广泛应用的领域之一。通过实时监控工厂机械设备的运行状态,企业能够提前发现设备的潜在故障,从而实现预防性维护与可预测性维护。这一做法不仅能有效提升…...
Flask-SQLAlchemy使用小结
链表查询 join方法允许你指定两个或多个表之间的连接条件,并返回一个新的查询对象,该对象包含了连接后的结果。 内连接 from sqlalchemy import join # 使用join函数 query db.session.query(User, Order).join(Order, User.id Order.user_id) res…...

深度学习和神经网络 卷积神经网络CNN
1.什么是卷积神经网络 一种前馈神经网络;受生物学感受野的机制提出专门处理网格结构数据的深度学习模型 核心特点:通过卷积操作自动提取空间局部特征(如纹理、边缘),显著降低参数量 2.CNN的三个结构特征 局部连接&a…...
用 NGINX 构建高效 POP3 代理`ngx_mail_pop3_module`
一、模块定位与作用 协议代理 ngx_mail_pop3_module 让 NGINX 能够充当 POP3 代理:客户端与后端 POP3 服务器之间的所有请求均转发到 NGINX,由 NGINX 负责与后端会话逻辑。认证方式控制 通过 pop3_auth 指令指定允许客户端使用的 POP3 认证方法…...
解决:如何在Windows adb使用dmesg | grep检查内核日志
首先: C:\Users\TF> adb shell 再 rk3568_r:/ $ dmesg | grep -i “goodix” 显示 130|rk3568_r:/ $ dmesg | grep -i “goodix” [ 0.764071] goodix_ts_probe() start111 [ 0.764108] goodix_ts_probe() start222 [ 0.764181] Goodix-TS 1-0014: Linked as a c…...

PlayWright | 初识微软出品的 WEB 应用自动化测试框架
Playwright是微软大厂背书的跨平台 WEB 应用自动化测试框架,支持多开发语言(TypeScript、JavaScript、.Net、Python、Java)及多浏览器(Chromium、WebKit、Firefox),同时支持移动端测试。 安装 playwright …...

Mac电脑_钥匙串操作选项变灰的情况下如何删除?
Mac电脑_钥匙串操作选项变灰的情况下如何删除? 这时候 可以使用相关的终端命令进行操作。 下面附加文章《Mac电脑_钥匙串操作的终端命令》。 《Mac电脑_钥匙串操作的终端命令》 (来源:百度~百度AI 发布时间:2025-06)…...
Git Patch 使用详解:生成、应用与多提交合并导出
在多人协作、代码审查、离线提交或跨仓库迁移的场景中,git patch 是非常实用的技术。本文将系统地介绍如何使用 Git 的补丁机制导出和应用修改内容。 📖 什么是 Git Patch? 严格来说,git patch 并不是一个 Git 命令,而…...

2025前端微服务 - 无界 的实战应用
遇饮酒时须饮酒,得高歌处且高歌 文章目录 什么是前端微服务主流框架概述无界 - 腾讯乾坤 - 阿里Micro-app Vue3项目引用⑴. 项目依赖安装⑵. main.ts 文件配置⑶. 路由配置⑷. 页面设置 隐藏子应用菜单及顶部信息栏子应用样式冲突问题虚拟路由⑴. 路由⑵. 页面 跨域…...
Spring Boot 缓存注解详解:@Cacheable、@CachePut、@CacheEvict(超详细实战版)
💡 前言 在高并发、高性能的系统开发中,缓存是提升接口响应速度和降低数据库压力的重要手段。Spring Boot 提供了强大的缓存抽象层 —— spring-context-support,并结合 JSR-107 标准,提供了多个缓存注解,如ÿ…...

【设计模式-4.8】行为型——中介者模式
说明:本文介绍行为型设计模式之一的中介者模式 定义 中介者模式(Mediator Pattern)又叫作调节者模式或调停者模式。用一个中介对象封装一系列对象交互,中介者使各对象不需要显式地互相作用,从而使其耦合松散…...