private void UpdateMesh() { // Return early if mesh is null. if (mDescriptor.EmittMesh == null) { return; } // Return early if mesh is loaded. if (sEmittMeshInfoDictionary.ContainsKey(mDescriptor.EmittMesh)) { return; } Vector3[] vertices = mDescriptor.EmittMesh.vertices; int[] indices = mDescriptor.EmittMesh.triangles; // Create new emitt mesh info from mesh. EmittMeshInfo emittMeshInfo = new EmittMeshInfo(); emittMeshInfo.mVertexCount = vertices.GetLength(0); emittMeshInfo.mVertexBuffer = new ComputeBuffer(vertices.GetLength(0), sizeof(float) * 3); emittMeshInfo.mVertexBuffer.SetData(vertices); emittMeshInfo.mIndexCount = indices.GetLength(0); emittMeshInfo.mIndexBuffer = new ComputeBuffer(indices.GetLength(0), sizeof(int)); emittMeshInfo.mIndexBuffer.SetData(indices); // Add to dictionary. sEmittMeshInfoDictionary[mDescriptor.EmittMesh] = emittMeshInfo; }
// EMITT UPDATE. private void EmittUpdate() { // Update timer. mEmittTimer += Time.deltaTime; int emittCount = (int)(mDescriptor.EmittFrequency * mEmittTimer); if (emittCount == 0) { return; } mEmittTimer -= emittCount * 1.0f / mDescriptor.EmittFrequency; Vector3 emitterVelocity = transform.position - mLastPosition; int particlesToEmitt = emittCount; int batchCount = (int)Mathf.Ceil(emittCount / 64.0f); for (int batchID = 0; batchID < batchCount; ++batchID) { int emittCountThisBatch = particlesToEmitt > 64 ? 64 : particlesToEmitt; //Debug.Log(emittCountThisBatch); particlesToEmitt -= 64; sComputeShader.SetInt("gEmittCountThisBatch", emittCountThisBatch); // BIND PARTICLE BUFFERS. sComputeShader.SetBuffer(sKernelEmitt, "gPositionBuffer", mPositionBuffer.GetOutputBuffer()); sComputeShader.SetBuffer(sKernelEmitt, "gVelocityBuffer", mVelocityBuffer.GetOutputBuffer()); sComputeShader.SetBuffer(sKernelEmitt, "gLifetimeBuffer", mLifetimeBuffer.GetOutputBuffer()); // Inherit velocity from emitter if true. Vector3 velocity = (emitterVelocity / Time.deltaTime) * (mDescriptor.InheritVelocity ? 1 : 0) + mDescriptor.InitialVelocity; // EMITT INFO. sComputeShader.SetInt("gEmittStartIndex", mEmittIndex); sComputeShader.SetInt("gEmittMaxCount", mMaxParticleCount); sComputeShader.SetFloats("gPosition", new float[] { transform.position.x, transform.position.y, transform.position.z }); sComputeShader.SetFloats("gVelocity", new float[] { velocity.x, velocity.y, velocity.z }); sComputeShader.SetFloats("gLifetime", new float[] { mDescriptor.Lifetime }); // EMITT MESH. if (mDescriptor.EmittMesh == null) { // Set count to 0. sComputeShader.SetInt("gEmittMeshVertexCount", 0); sComputeShader.SetInt("gEmittMeshIndexCount", 0); sComputeShader.SetInt("gEmittMeshRandomIndex", 0); } else { Debug.Assert(sEmittMeshInfoDictionary.ContainsKey(mDescriptor.EmittMesh)); EmittMeshInfo emittMeshInfo = sEmittMeshInfoDictionary[mDescriptor.EmittMesh]; // Set index and vertex buffer. sComputeShader.SetBuffer(sKernelEmitt, "gEmittMeshVertexBuffer", emittMeshInfo.mVertexBuffer); sComputeShader.SetBuffer(sKernelEmitt, "gEmittMeshIndexBuffer", emittMeshInfo.mIndexBuffer); sComputeShader.SetInt("gEmittMeshVertexCount", emittMeshInfo.mVertexCount); sComputeShader.SetInt("gEmittMeshIndexCount", emittMeshInfo.mIndexCount); int[] randomIndexArray = new int[64]; for (int j = 0; j < randomIndexArray.GetLength(0); ++j) { randomIndexArray[j] = Random.Range(0, emittMeshInfo.mIndexCount - 1); } sRandomIndexBuffer.SetData(randomIndexArray); sComputeShader.SetBuffer(sKernelEmitt, "gEmittMeshRandomIndexBuffer", sRandomIndexBuffer); sComputeShader.SetFloats("gEmittMeshScale", new float[] { transform.localScale.x, transform.localScale.y, transform.localScale.z }); } // DISPATCH. sComputeShader.Dispatch(sKernelEmitt, 1, 1, 1); // Increment emitt index. mEmittIndex = (mEmittIndex + emittCountThisBatch) % mMaxParticleCount; } }