コード例 #1
0
        void PrepareParallelTasks()
        {
            //create a collection of task that will run in parallel on several threads.
            //the number of threads and tasks to perform are not dependent.
            _multiParallelTasks = new MultiThreadedParallelTaskCollection(NUM_OF_SVELTO_THREADS, true);
            //in this case though we just want to perform a task for each thread
            //ParticlesCPUKernel is a task (IEnumerator) that executes the
            //algebra operation on the particles. Each task perform the operation
            //on particlesPerThread particles
#if BENCHMARK
            pc = new ParticleCounter(particlesPerThread - 16);
#else
            _pc = new ParticleCounter(0);
#endif
#if OLD_STYLE
            //calculate the number of particles per thread
            uint particlesPerThread = _particleCount / NUM_OF_SVELTO_THREADS;
            for (int i = 0; i < NUM_OF_SVELTO_THREADS; i++)
            {
                _multiParallelTasks.Add(new ParticlesCPUKernel((int)(particlesPerThread * i), (int)particlesPerThread, this, _pc));
            }
#else
            var particlesCpuKernel = new ParticlesCPUKernel(this);
            _multiParallelTasks.Add(ref particlesCpuKernel, (int)_particleCount);
#endif
        }
        IEnumerator MainThreadOperations(ParticleCounter particleCounter)
        {
            var bounds = new Bounds(_BoundCenter, _BoundSize);

            var syncRunner = new SyncRunner();

            //these will help with synchronization between threads
            WaitForSignalEnumerator _waitForSignal      = new WaitForSignalEnumerator(() => _breakIt);
            WaitForSignalEnumerator _otherwaitForSignal = new WaitForSignalEnumerator();

            //Start the operations on other threads
            OperationsRunningOnOtherThreads(_waitForSignal, _otherwaitForSignal)
            .ThreadSafeRunOnSchedule(StandardSchedulers.multiThreadScheduler);

            //start the mainloop
            while (true)
            {
                _time = Time.time / 10;

                //wait until the other thread tell us that the data is ready to be used.
                //Note that I am stalling the main thread here! This is entirely up to you
                //if you don't want to stall it, as you can see with the other use cases
                _otherwaitForSignal.RunOnSchedule(syncRunner);
#if BENCHMARK
                if (PerformanceCheker.PerformanceProfiler.showingFPSValue > 30.0f)
                {
                    if (particleCounter.particlesLimit >= 16)
                    {
                        particleCounter.particlesLimit -= 16;
                    }

                    PerformanceCheker.PerformanceProfiler.particlesCount = particleCounter.particlesTransformed;
                }

                particleCounter.particlesTransformed = 0;
#endif

                _particleDataBuffer.SetData(_gpuparticleDataArr);

                //render the particles. I use DrawMeshInstancedIndirect but
                //there aren't any compute shaders running. This is so cool!
                Graphics.DrawMeshInstancedIndirect(_pointMesh, 0, _material,
                                                   bounds, _GPUInstancingArgsBuffer);

                //tell to the other thread that now it can perform the operations
                //for the next frame.
                _waitForSignal.Signal();

                //continue the cycle on the next frame
                yield return(null);
            }
        }
コード例 #3
0
ファイル: Emitter.cs プロジェクト: j8307042003/GPUParticle
    void FixedUpdate()
    {
        emitCount += emitRate * Time.deltaTime;

        if (_reset)
        {
            ResetBuffer();
            return;
        }

        SetEmitInfoBuffer();
        DispatchEmitCount();
        if (emitCount > 0)
        {
            DispatchEmitParticle();
        }
        DispatchUpdateParticle();
        Swap <ComputeBuffer>(ref alivelistCB, ref alivelistSecCB); // Swap alive list
        DispatchDrawArg();



        if (_debug)
        {
            ParticleCounter[] particleC = new ParticleCounter[] { new ParticleCounter() };
            uint[]            arg       = new uint[5] {
                0, 0, 0, 0, 0
            };
            uint[] indirectB    = new uint[3];
            uint[] alivelist    = new uint[maxParticle];
            uint[] alivelistSec = new uint[maxParticle];
            alivelistCB.GetData(alivelist);
            alivelistSecCB.GetData(alivelistSec);
            int aliveC    = GetBufferCount(alivelistCB);
            int aliveSecC = GetBufferCount(alivelistSecCB);
            int deadlistC = GetBufferCount(deadlistCB);
            instancingArgCB.GetData(arg);
            particleCounterCB.GetData(particleC);
            updateIndirectCB.GetData(indirectB);
            emitParticleInfoCB.GetData(emitInfoParam);

            int z = 0;
        }

        prevPosition = transform.position;
        emitCount   -= (uint)emitCount;
    }