WebAudio
在查阅MDN的Api的时候,看到是这么介绍:
Web Audio API使用户可以在音频上下文(AudioContext)中进行音频操作,具有模块化路由的特点。在音频节点上操作进行基础的音频, 它们连接在一起构成音频路由图。
所以接下来我试着去test, 尝试获取一首歌曲的音频数据。
获取步骤
- 新建一个audio上下文实例 audioCtx。
- 通过audio上下文创建音频源,这里有两种采样实现方式:
2.1 createMediaElementSource 通过audio对象获取音频文件引入 - source
2.2 createMediaStreamSource 通过stream流文件引入 - 再通过audio上下文创建一个分析器节点( analyserNode )它提供了实时时间频率和时间域的切点,这些数据构成了数据可视化的重要参数
- 接下来把分析器连接到音频源 source.connect(analyserNode)
- 最后把音频源连接至设备声卡 source.connect(destination)
简易流程如图:
捕获音频数据
首先设置分析器快速傅里叶变换来捕获音频数据 其决定了频谱密度。
而frequencyBinCount决定了数据链的长度,这个属性为只读属性,值默认为fftSize的一半。
这样我们可以构建出一个长度为fftSize * 0.5的32位浮点型的高速类型数组。
1 | analyserNode.fftSize = 256; |
定义好了数组,就可以通过 getFloatFrequencyData 这个api来获取即时的音频数据。(当然还有其他获取不同类型数据的api)
此方法的调用通常定义在帧刷新方法中,做实时数据的变化监控和可视化渲染。
例如:
1 | function draw() { |
WebGL
为啥要用WebGL?
跳脱大数组图像渲染的内存消耗瓶颈
在1209年的今天,基本上主流浏览器都可以支持Webgl, 我们赶紧把吃力的遍历渲染的工作交给GPU的专业图像处理器来干。救救可怜的浏览器占用吧!
简单来说就是,使用glsl语言构建片元和顶点着色器这些GPU可以直接运行的图形命令,并通过webgl处理可在浏览器中运行的代码。
pixi.js中的Filter性能
在pixi v4.8.3版本的Filter中定义了fragShader(片元着色器)程序,却在stats插件监控发现帧率巨低。平均只有20多fps。
这个问题同时也存在基于pixi渲染的phaser游戏框架中,官方提供的一些filter示例也有不同程度的卡顿,希望在pixi v5的版本里的shader能得到优化。
初始化WebGL
在这里就不详细介绍概念了,首先先构建webGl的上下文并传递着色器程序。
- 定义一个canvas对象,尺寸设置为全屏。
1 | const scene = document.getElementById('scene'); |
- 获取webgl上下文
1 | gl = scene.getContext('webgl'); |
- 初始化着色器
3.1 定义创建shader对象方法
1 | function loadShader (gl, type, sourceStr) { |
3.2 定义创建program对象方法
1 | function createProgram (gl, vshader, fshader) { |
3.3 定义初始化着色器方法
1 | function initShaders (gl, vshader, fshader) { |
- 顶点着色器的定义
在这里,demo想要展示一个平面的画布并在上面进行webgl像素渲染。这时候需要通过顶点着色器去构造一个画布,即为一个矩形。
这里设置顶点着色器的代码非常简单,至于代码详细大家可以参考glsl的语法。
1 | const shaderPointer = ` |
这里设置了顶点着色器的顶点坐标和尺寸,然后这里的a_Position只是一个定义了一个vec4类型的参数。下面需要通过js代码将对应的数据传递进去。
因为在这之前,我们执行了initShader方法,从而让我们可以轻松的获取到glsl里相关的顶点属性参数。
const aPosition = gl.getAttribLocation(gl.program, ‘a_Position’);
但是我们需要的是一个矩形图像,而不是一个点,这样一来我们需要传递4个坐标参数来实现。
所以我们需要引入一个缓冲区对象的概念来进行参数传递。
1 | // 创建缓冲区对象 |
如图:
在实践了如上的一些基本代码后,我们就可以创建出矩形图形。
- 片元着色器
在之前我们刚通过顶点shader定义了一个矩形。那么片元着色器解释起来可能比较复杂,大家可以理解为其在光栅化后很类似于像素,但又不是像素。
我们可以在顶点着色器所定义的多个三角形组合的图形中,进行特定的渲染效果。
这是一段片元着色器代码,可能比较复杂,主要是实现多种正弦,余弦的几何图像变换。
1 | const shaderFrag = ` |
同时我们通过js获取相关参数并传递数据:
1 | // 设置片元渲染的范围,数值可以使用像素点数量。 |
- 获取音频数据并刷新帧时更新渲染
1 | function draw () { |
最后我们一起看看效果吧!!!
因为不同机型的webgl支持不同,支持最大uniform的数目也不相同。可能会出现too many uniform的报错。
实测pc和ios7p以上设备都可以正常运行
uniform的相关报错问题会在之后的研究中去解决。