Skip to content

Instantly share code, notes, and snippets.

@cabbibo
Created February 16, 2018 20:55
Show Gist options
  • Save cabbibo/6875ec00198c06c7e73df51ec538c88e to your computer and use it in GitHub Desktop.
Save cabbibo/6875ec00198c06c7e73df51ec538c88e to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class HexParticles : MonoBehaviour {
public AudioListenerTexture alt;
public RandomVertBuffer vertBuffer;
public ComputeBuffer transferBuffer;
public ComputeShader computeShader;
public ComputeShader transferShader;
public Material material;
public Material pointMat;
public float zPos;
public float hue;
public bool showMesh = true;
private int numThreads = 128;
private int numGroups;
private int _kernel;
private int _kernelTransfer;
private int transferStructSize = 3 + 3 + 2;
private int vertCount;
public int Set = 0;
private int numSides=6;
private int totalHexVerts;
private MeshRenderer[] meshes;
// Use this for initialization
void Start () {
if( vertBuffer == null ){ vertBuffer = this.GetComponent<RandomVertBuffer>(); }
vertCount = vertBuffer.vertCount;
_kernel = computeShader.FindKernel("CSMain");
_kernelTransfer = transferShader.FindKernel("CSMain");
totalHexVerts = vertCount * 7;
createTransferBuffer();
InitMesh();
numGroups = (vertCount+(numThreads-1))/numThreads;
SetBegin();
}
void InitMesh () {
// here we need to create a mesh with the right amount of triangles and vertices
int[] srcTriangles;
Vector3[] srcVertices;
GetHexInfo( out srcTriangles , out srcVertices );
// if there is more than one mesh needed we will have to create a new game object for that!
int numberOfMeshFilters = Mathf.CeilToInt (totalHexVerts / 65534f);
int numberOfMeshesForEachMeshFilter = Mathf.FloorToInt (65534f / 7);
int numberOfMeshesAdded = 0;
meshes = new MeshRenderer[ numberOfMeshFilters ];
// Creating each mesh filter!
for (int f = 0; f < numberOfMeshFilters; f++) {
List<Vector3> vertices = new List<Vector3> ();
List<int> triangles = new List<int> ();
GameObject go = f == 0 ? gameObject : new GameObject (name + "-" + f);
// Gets the offset for the vertices of secondary meshes!
int transferOffset = numberOfMeshesAdded * srcVertices.Length;
for (int m = 0; m < numberOfMeshesForEachMeshFilter && numberOfMeshesAdded < vertCount; m++) {
vertices.AddRange (srcVertices);
for (int t = 0; t < srcTriangles.Length; t++) {
//print(srcTriangles[t] + srcVertices.Length * m);
triangles.Add( srcTriangles[t] + srcVertices.Length * m);
}
numberOfMeshesAdded++;
}
// create mesh, filter and renderer
Mesh mesh = new Mesh ();
mesh.SetVertices (vertices);
mesh.SetTriangles (triangles, 0);
mesh.bounds = new Bounds (Vector3.zero, Vector3.one * 1000f);
mesh.UploadMeshData (true);
go.transform.parent = transform;
go.transform.localPosition = Vector3.zero;
go.AddComponent<MeshFilter> ().sharedMesh = mesh;
MaterialPropertyBlock mpb = new MaterialPropertyBlock ();
mpb.SetFloat ("_transferOffset", transferOffset);
MeshRenderer renderer = go.AddComponent<MeshRenderer> ();
renderer.sharedMaterial = material;
renderer.SetPropertyBlock (mpb);
meshes[f] = renderer;
}
material.SetFloat ("_Hue", hue);
material.SetBuffer ("_transferBuffer", transferBuffer);
}
void GetHexInfo( out int[] tris , out Vector3[] verts ){
verts = new Vector3[numSides+1];
tris = new int[numSides*3];
int index = 0;
for( int i = 0; i < numSides; i++ ){
tris[index++] = 0;
tris[index++] = ((i+0)%numSides)+1;
tris[index++] = ((i+1)%numSides)+1;
}
}
void createTransferBuffer(){
transferBuffer = new ComputeBuffer( totalHexVerts , transferStructSize * sizeof(float) );
float[] values = new float[ transferStructSize * totalHexVerts ];
transferBuffer.SetData( values );
}
void OnRenderObject(){
// if( showMesh == true){
pointMat.SetPass(0);
pointMat.SetInt("_Count", vertCount );
pointMat.SetBuffer("_vertBuffer", vertBuffer._buffer );
//Graphics.DrawProcedural(MeshTopology.Triangles, vertCount *3 );
}
void SetBindPoses(){
}
void SetBegin(){
Set = 1;
Dispatch();
Set = 0;
}
void Dispatch(){
if( vertBuffer._buffer != null && transferBuffer != null ){
material.SetBuffer ("_transferBuffer", transferBuffer);
material.SetTexture( "_AudioMap" , alt.AudioTexture );
//print( vertBuffer.vertCount );
computeShader.SetInt( "_Reset" , Set );
computeShader.SetFloat( "_ZPos" , zPos );
computeShader.SetFloat( "_DeltaTime" , Time.deltaTime );
computeShader.SetFloat( "_Time" , Time.time );
computeShader.SetInt( "_NumVerts" , vertBuffer.vertCount );
computeShader.SetBuffer(_kernel, "audioBuffer", alt._buffer );
computeShader.SetBuffer( _kernel , "vertBuffer" , vertBuffer._buffer );
computeShader.Dispatch( _kernel, numGroups,1,1 );
transferShader.SetInt( "_NumVerts" , vertCount );
transferShader.SetFloat( "_Time" , Time.time );
transferShader.SetBuffer(_kernelTransfer, "audioBuffer", alt._buffer );
transferShader.SetBuffer( _kernelTransfer , "vertBuffer" , vertBuffer._buffer );
transferShader.SetBuffer( _kernelTransfer , "transferBuffer" , transferBuffer );
transferShader.Dispatch( _kernelTransfer, numGroups,1,1 );
}
}
// Update is called once per frame
void LateUpdate () {
Dispatch();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment