Unity音量可視化——粒子隨聲浪跳動


本文涉及的源碼包含在安卓Unity渲染互通的 Demo 里,直接打開 Unity 工程的 Test 場景就行,不用管安卓工程。

腳本控制粒子

起初是看到這么一篇博客 Shader特效—— 音符跳動,效果如下圖:

具體的shader代碼就不貼在這里了,他的博客里都有。
處理音頻的關鍵代碼如下(修改過):

private int m_NumSamples = 256;
private float[] m_Samples;
private float sum, rms;

private void Start()
{
    audioSource = GetComponent<AudioSource>();
    audioSource.clip = Microphone.Start(null, true, 10, 44100);
    m_Samples = new float[m_NumSamples];
}

private void Update()
{
    audioSource.GetOutputData(m_Samples, 0);
    sum = m_Samples[m_NumSamples - 1] * m_Samples[m_NumSamples - 1];
    rms = Mathf.Sqrt(sum/* / m_NumSamples*/);
    float intensity = rms;
    Debug.Log(intensity);
    if (intensity > bootIntensity)
    {
        //change in shader
        material.SetFloat("_Intensity", intensity);
    }
    else
    {
        material.SetFloat("_Intensity", 0);
    }
}

只要目前的 intensity 超過了預設的 bootIntensity ,就允許 shader 做出反應,實現上圖小球抖動的效果。那么能不能套用到粒子效果上呢,查了一下API果然不難做到。

這里用一個球狀發射的粒子模塊來做示例:

我希望粒子隨着音樂發射,音量越大數量越多,於是乎我們需要在腳本內通過檢測音量來改變 Emission 模塊的 Rate over Time 值,當然這里只是舉個例子,還有更漂亮的實現。至於 Bursts 值可有可無,只是一個點綴。(當然 Burst 也可通過腳本控制)

一開始我盲寫,果然有 rateOverTime 這個值,但是不允許我直接更改。

查了下 API-ParticleSystem.EmissionModule 后發現不能直接用腳本賦值,而是需要實例化之后賦值:

var emission = m_ParticleSystem.emission;
emission.rateOverTime = 100f;

那么事情就好辦了,復用上面的腳本代碼就可以控制粒子了:

private void Update()
{
    var emission = m_ParticleSystem.emission;
    audioSource.GetOutputData(m_Samples, 0);
    sum = m_Samples[m_NumSamples - 1] * m_Samples[m_NumSamples - 1];
    rms = Mathf.Sqrt(sum/* / m_NumSamples*/);
    float intensity = rms;
    Debug.Log(intensity);
    if (intensity > bootIntensity)
    {
        emission.rateOverTime = 10f * (1 + intensity * 1000);
    }
    else
    {
        emission.rateOverTime = 10f;
    }
}

別忘了給他加上一個 AudioSource 組件,將音頻文件拖入 AudioClip 即可

接入Mic

Unity給的接口很方便,基本不用怎么改,首先把上面 AudioClip 的音源文件清了,我們會在腳本中獲取麥克風輸入信息作為音源,具體代碼如下:

private void Start()
{
    audioSource = GetComponent<AudioSource>();
    BeginListener(0);
    //audioSource.clip = Microphone.Start(null, true, 10, 44100);
    m_Samples = new float[m_NumSamples];
}

......

public void BeginListener(int index)
{
    int min = 0;
    int max = 0;

    Microphone.GetDeviceCaps(Microphone.devices[index], out min, out max);

    audioSource.clip = Microphone.Start(Microphone.devices[index], true, 2, max);

    while (!(Microphone.GetPosition(Microphone.devices[index]) > 1))
    {
        // Wait until the recording has started
    }

    audioSource.loop = true;
    audioSource.Play();
}

運行,對着Mic吼的效果如下:

不建議在辦公室吼,吹氣也可以達到這樣的效果。。。

本人不太熟悉粒子系統,有興趣的朋友可以自己實現更多更酷的特效,感謝閱讀


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM