Exemple #1
0
    // INIT.
    private void InitSystem()
    {
        if (mDescriptor == null)
        {
            mDescriptor = new GPUParticleDescriptor();
        }

        mDescriptor.Update();

        mMaxParticleCount = (int)Mathf.Ceil(mDescriptor.EmittFrequency * mDescriptor.Lifetime);
        mLastPosition     = transform.position;

        sTotalParticleCount += mMaxParticleCount;

        // BUFFERS.
        mPositionBuffer = new SwapBuffer(2, mMaxParticleCount, sizeof(float) * 4);
        mVelocityBuffer = new SwapBuffer(2, mMaxParticleCount, sizeof(float) * 4);
        mLifetimeBuffer = new SwapBuffer(2, mMaxParticleCount, sizeof(float) * 4);

        mColorBuffer        = new ComputeBuffer(mMaxParticleCount, sizeof(float) * 4);
        mHaloBuffer         = new ComputeBuffer(mMaxParticleCount, sizeof(float) * 4);
        mScaleBuffer        = new ComputeBuffer(mMaxParticleCount, sizeof(float) * 4);
        mTransperancyBuffer = new ComputeBuffer(mMaxParticleCount, sizeof(float) * 4);

        {   // Set lifetime default (negative)value.
            float[] arr = new float[mMaxParticleCount * 4];
            for (int i = 0; i < mMaxParticleCount * 4; ++i)
            {
                arr[i] = -0.01f;
            }
            mLifetimeBuffer.GetInputBuffer().SetData(arr);
            mLifetimeBuffer.GetOutputBuffer().SetData(arr);
        }

        // MESH.
        UpdateMesh();

        //LIFETIME POINT BUFFERS
        // ------- Color ------
        UpdateLifetimeBuffer(out mColorLifetimePointsBuffer, mDescriptor.ColorOverLifetime.Get());

        // ------- Halo -------
        UpdateLifetimeBuffer(out mHaloLifetimePointsBuffer, mDescriptor.HaloOverLifetime.Get());

        // ------ Scale -------
        UpdateLifetimeBuffer(out mScaleLifetimePointsBuffer, mDescriptor.ScaleOverLifetime.Get());

        // ------ Opacity -----
        UpdateLifetimeBuffer(out mTransparencyLifetimePointsBuffer, mDescriptor.OpacityOverLifetime.Get());

        // COLLISION.
        mSphereColliderResultBuffer = new ComputeBuffer(sMaxSphereColliderCount, sizeof(int));
    }
Exemple #2
0
    // MERGE.
    private static void Merge()
    {
        if (sMergedParticleCount < sTotalParticleCount)
        {
            sMergedParticleCount = Mathf.NextPowerOfTwo(sTotalParticleCount);

            // Resize buffers.
            sMergedPositionBuffer.Resize(sMergedParticleCount);
            sMergedVelocityBuffer.Resize(sMergedParticleCount);
            sMergedLifetimeBuffer.Resize(sMergedParticleCount);

            sMergedColorBuffer.Resize(sMergedParticleCount);
            sMergedHaloBuffer.Resize(sMergedParticleCount);
            sMergedScaleBuffer.Resize(sMergedParticleCount);
            sMergedTransperancyBuffer.Resize(sMergedParticleCount);

            sSortElementSwapBuffer.Resize(sMergedParticleCount);
        }

        // CLEAR OLD VALUES.

        // TODO: Might not need to reset all this data!!
        float[] mergedData = new float[sMergedParticleCount * 4];
        for (int i = 0; i < mergedData.GetLength(0); ++i)
        {
            mergedData[i] = -100.0f;
        }

        sMergedLifetimeBuffer.GetInputBuffer().SetData(mergedData);
        sMergedLifetimeBuffer.GetOutputBuffer().SetData(mergedData);

        for (int i = 0; i < mergedData.GetLength(0); ++i)
        {
            mergedData[i] = float.MaxValue;
        }

        sMergedPositionBuffer.GetInputBuffer().SetData(mergedData);
        sMergedPositionBuffer.GetOutputBuffer().SetData(mergedData);

        // SET BUFFERS.
        sComputeShader.SetBuffer(sKernelMergeInitSort, "mergePositionOUT", sMergedPositionBuffer.GetOutputBuffer());
        sComputeShader.SetBuffer(sKernelMergeInitSort, "mergeVelocityOUT", sMergedVelocityBuffer.GetOutputBuffer());
        sComputeShader.SetBuffer(sKernelMergeInitSort, "mergeLifetimeOUT", sMergedLifetimeBuffer.GetOutputBuffer());
        sComputeShader.SetBuffer(sKernelMergeInitSort, "mergeColorOUT", sMergedColorBuffer.GetOutputBuffer());
        sComputeShader.SetBuffer(sKernelMergeInitSort, "mergeHaloOUT", sMergedHaloBuffer.GetOutputBuffer());
        sComputeShader.SetBuffer(sKernelMergeInitSort, "mergeScaleOUT", sMergedScaleBuffer.GetOutputBuffer());
        sComputeShader.SetBuffer(sKernelMergeInitSort, "mergeTransperancyOUT", sMergedTransperancyBuffer.GetOutputBuffer());

        sComputeShader.SetBuffer(sKernelMergeInitSort, "gSortElementBufferOUT", sSortElementSwapBuffer.GetOutputBuffer());


        Vector3 cForward = Camera.main.transform.forward;

        sComputeShader.SetFloats("gCameraForward", new float[] { cForward.x, cForward.y, cForward.z });

        int offset = 0;

        foreach (KeyValuePair <GPUParticleSystem, GPUParticleSystem> it in sGPUParticleSystemDictionary)
        {
            GPUParticleSystem system = it.Value;

            if (!system.gameObject.activeInHierarchy)
            {
                continue;
            }

            sComputeShader.SetInt("gLocalParticleCount", system.mMaxParticleCount);
            sComputeShader.SetInt("gOffsetIndex", offset);

            sComputeShader.SetBuffer(sKernelMergeInitSort, "gLocalSystemPositionIN", system.mPositionBuffer.GetOutputBuffer());
            sComputeShader.SetBuffer(sKernelMergeInitSort, "gLocalSystemVelocityIN", system.mVelocityBuffer.GetOutputBuffer());
            sComputeShader.SetBuffer(sKernelMergeInitSort, "gLocalSystemLifetimeIN", system.mLifetimeBuffer.GetOutputBuffer());
            sComputeShader.SetBuffer(sKernelMergeInitSort, "gLocalSystemColorIN", system.mColorBuffer);
            sComputeShader.SetBuffer(sKernelMergeInitSort, "gLocalSystemHaloIN", system.mHaloBuffer);
            sComputeShader.SetBuffer(sKernelMergeInitSort, "gLocalSystemScaleIN", system.mScaleBuffer);
            sComputeShader.SetBuffer(sKernelMergeInitSort, "gLocalSystemTransperancyIN", system.mTransperancyBuffer);

            sComputeShader.Dispatch(sKernelMergeInitSort, (int)Mathf.Ceil(system.mMaxParticleCount / 64.0f), 1, 1);

            offset += system.mMaxParticleCount;
        }
    }
Exemple #3
0
    // 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;
        }
    }
Exemple #4
0
    /// <summary>
    /// Kills all living particles.
    /// </summary>
    public static void KillAllParticles()
    {
        Debug.Log("KILLALLPARTILCES1");

        if (sGPUParticleSystemDictionary == null)
        {
            return;
        }

        foreach (KeyValuePair <GPUParticleSystem, GPUParticleSystem> it in sGPUParticleSystemDictionary)
        {
            Debug.Log("KILLALLPARTILCES2");

            GPUParticleSystem system = it.Value;

            float[] systemData = new float[system.mMaxParticleCount * 4];
            for (int i = 0; i < systemData.GetLength(0); ++i)
            {
                systemData[i] = -100.0f;
            }

            system.mLifetimeBuffer.GetInputBuffer().SetData(systemData);
            system.mLifetimeBuffer.GetOutputBuffer().SetData(systemData);

            for (int i = 0; i < systemData.GetLength(0); ++i)
            {
                systemData[i] = float.MaxValue;
            }

            system.mPositionBuffer.GetInputBuffer().SetData(systemData);
            system.mPositionBuffer.GetOutputBuffer().SetData(systemData);

            int[] r = new int[sMaxGPUColliderCount];
            for (int i = 0; i < r.GetLength(0); ++i)
            {
                r[i] = 0;
            }
            system.mSphereColliderResultBuffer.SetData(r);
        }

        // TODO: Might not need to reset all this data!!

        float[] mergedData = new float[sMergedParticleCount * 4];
        for (int i = 0; i < mergedData.GetLength(0); ++i)
        {
            mergedData[i] = -100.0f;
        }

        sMergedLifetimeBuffer.GetInputBuffer().SetData(mergedData);
        sMergedLifetimeBuffer.GetOutputBuffer().SetData(mergedData);

        for (int i = 0; i < mergedData.GetLength(0); ++i)
        {
            mergedData[i] = float.MaxValue;
        }

        sMergedPositionBuffer.GetInputBuffer().SetData(mergedData);
        sMergedPositionBuffer.GetOutputBuffer().SetData(mergedData);

        int[] data = new int[sMaxGPUColliderCount];
        for (int i = 0; i < data.GetLength(0); ++i)
        {
            data[i] = 0;
        }
        sGPUColliderResultSwapBuffer.GetInputBuffer().SetData(data);
        sGPUColliderResultSwapBuffer.GetOutputBuffer().SetData(data);
    }