- Home /
Generating a 3D Mesh from Audio data
Hi,
I'm creating an audio visualization which will generate a terrain from the audio data that I feed it using the GetSpectrumData. I've tried to do this but all i've managed to do is change the Y position of the mesh. Seen below
What I want is for it to change the vertices in the mesh it self so that it creates a "hill" and "canyon" type of terrain from the music. I've separated the Spectrum data into 8 bands for ease of use as I want to generate different terrain type by using the different frequencies I get from the music.I'll appreciate any help at all, and I also recently started with C# and unity. Code below is from my mesh generation script, I have another script in which the planes are created and the mesh from the meshCreator script is taken and put onto the planes.
public int gridSize = 20;
public Mesh planeMesh;
public Mesh planeMeshBand2;
float[] spectrum = new float[512];
float[] _bands = new float[8];
public int bands;
[HideInInspector]
public AudioSource _audioSource;
[Range(-100,100)]
public float P1;
[Range(-100,100)]
public float P2;
[Range(-100, 100)]
public float P11;
[Range(-100, 100)]
public float P22;
private void Start()
{
_audioSource = GetComponent<AudioSource>();
}
void Update()
{
GetSpectrumData();
MakeBands();
CreateGrid();
CreateGridBand2();
Debug.Log(_bands.Length);
Debug.Log(_audioSource.time);
}
void GetSpectrumData()
{
_audioSource.GetSpectrumData(spectrum, 0, FFTWindow.BlackmanHarris);
}
void MakeBands()
{
int count = 0;
for(int i = 0; i < 8; i++)
{
int sampleCounts = (int)Mathf.Pow(2, i) * 2;
float average = 0;
if(i == 7)
{
sampleCounts += 2;
}
for(int x = 0; x < sampleCounts; x++)
{
average += spectrum[count] * (count + 1);
count++;
}
average /= count;
_bands[i] = average * 10;
}
}
private void CreateGrid()
{
planeMesh = new Mesh();
List<Vector2> uvs = new List<Vector2>();
List<Vector3> vertices = new List<Vector3>();
for (int y = 0; y < gridSize + 1; y++)
{
for (int x = 0; x < gridSize + 1; x++)
{
Vector3 frequency = new Vector3(x, _bands[bands] * 10, y); //Generates planes which the y position is changed.
vertices.Add(new Vector3(x, frequency.y / 2, y));
uvs.Add(new Vector2(x / (float)gridSize, y / (float)gridSize));
}
}
List<int> indices = new List<int>();
for (int y = 0; y < gridSize; y++)
{
for (int x = 0; x < gridSize; x++)
{
indices.Add(y * (gridSize + 1) + x);
indices.Add(y * (gridSize + 1) + x + gridSize + 1);
indices.Add(y * (gridSize + 1) + x + 1);
indices.Add(y * (gridSize + 1) + x + gridSize + 1);
indices.Add(y * (gridSize + 1) + x + gridSize + 2);
indices.Add(y * (gridSize + 1) + x + 1);
}
}
planeMesh.SetVertices(vertices);
planeMesh.SetIndices(indices.ToArray(), MeshTopology.Triangles, 0);
planeMesh.SetUVs(0, uvs);
planeMesh.RecalculateNormals();
GetComponent<MeshFilter>().mesh = planeMesh;
}
Your answer
Follow this Question
Related Questions
Distribute terrain in zones 3 Answers
Get all vertices in gameObject to array. 1 Answer
how to make a planet 1 Answer