Example #1
0
    // UPDATE.
    private void UpdateSystem()
    {
        // SWAP INPUT/OUTPUT.
        mPositionBuffer.Swap();
        mVelocityBuffer.Swap();
        mLifetimeBuffer.Swap();

        // BIND INPUT BUFFERS.
        sComputeShader.SetBuffer(sKernelUpdate, "gPositionIN", mPositionBuffer.GetInputBuffer());
        sComputeShader.SetBuffer(sKernelUpdate, "gVelocityIN", mVelocityBuffer.GetInputBuffer());
        sComputeShader.SetBuffer(sKernelUpdate, "gLifetimeIN", mLifetimeBuffer.GetInputBuffer());

        // BIND OUTPUT BUFFERS.
        sComputeShader.SetBuffer(sKernelUpdate, "gPositionOUT", mPositionBuffer.GetOutputBuffer());
        sComputeShader.SetBuffer(sKernelUpdate, "gVelocityOUT", mVelocityBuffer.GetOutputBuffer());
        sComputeShader.SetBuffer(sKernelUpdate, "gLifetimeOUT", mLifetimeBuffer.GetOutputBuffer());

        sComputeShader.SetBuffer(sKernelUpdate, "gColorOUT", mColorBuffer);
        sComputeShader.SetBuffer(sKernelUpdate, "gHaloOUT", mHaloBuffer);
        sComputeShader.SetBuffer(sKernelUpdate, "gScaleOUT", mScaleBuffer);
        sComputeShader.SetBuffer(sKernelUpdate, "gTransparencyOUT", mTransperancyBuffer);

        // BIND VALUE OF LIFETIME BUFFERS.
        sComputeShader.SetInt("gColorLifetimeCount", mDescriptor.ColorOverLifetime.Length());
        sComputeShader.SetBuffer(sKernelUpdate, "gColorLifetimeBuffer", mColorLifetimePointsBuffer);
        sComputeShader.SetInt("gHaloLifetimeCount", mDescriptor.HaloOverLifetime.Length());
        sComputeShader.SetBuffer(sKernelUpdate, "gHaloLifetimeBuffer", mHaloLifetimePointsBuffer);
        sComputeShader.SetInt("gScaleLifetimeCount", mDescriptor.ScaleOverLifetime.Length());
        sComputeShader.SetBuffer(sKernelUpdate, "gScaleLifetimeBuffer", mScaleLifetimePointsBuffer);
        sComputeShader.SetInt("gTransparencyLifetimeCount", mDescriptor.OpacityOverLifetime.Length());
        sComputeShader.SetBuffer(sKernelUpdate, "gTransparencyLifetimeBuffer", mTransparencyLifetimePointsBuffer);

        // SET META DATA.
        sComputeShader.SetInt("gMaxParticleCount", mMaxParticleCount);
        sComputeShader.SetFloat("gDeltaTime", Time.deltaTime);

        sComputeShader.SetFloats("gConstantAcceleration", new float[] { mDescriptor.ConstantAcceleration.x, mDescriptor.ConstantAcceleration.y, mDescriptor.ConstantAcceleration.z });
        sComputeShader.SetFloat("gConstantDrag", mDescriptor.ConstantDrag);

        // ACCELERATOR.
        Dictionary <GPUParticleAttractor, GPUParticleAttractor> attractorDictionary = GPUParticleAttractor.GetGPUParticleAttractorDictionary();

        if (attractorDictionary == null)
        {
            sComputeShader.SetInt("gAttractorCount", 0);
        }
        else
        {
            Debug.Assert(attractorDictionary.Count < sMaxAttractorCount);

            float[] attractorArray = new float[attractorDictionary.Count * 8];
            int     i     = 0;
            int     count = 0;
            foreach (KeyValuePair <GPUParticleAttractor, GPUParticleAttractor> it in attractorDictionary)
            {
                GPUParticleAttractor attractor = it.Value;

                //Skip if inactive.
                if (!attractor.gameObject.activeInHierarchy)
                {
                    continue;
                }

                float scale = Mathf.Max(Mathf.Max(attractor.transform.localScale.x, attractor.transform.localScale.y), attractor.transform.localScale.z);

                attractorArray[i++] = attractor.transform.position.x;
                attractorArray[i++] = attractor.transform.position.y;
                attractorArray[i++] = attractor.transform.position.z;
                attractorArray[i++] = attractor.Power;
                attractorArray[i++] = scale * attractor.Min;
                attractorArray[i++] = scale * attractor.Max;
                attractorArray[i++] = 0.0f; //Padding
                attractorArray[i++] = 0.0f; //Padding

                count++;
            }
            sGPUParticleAttractorBuffer.SetData(attractorArray);

            sComputeShader.SetInt("gAttractorCount", count);
            sComputeShader.SetBuffer(sKernelUpdate, "gAttractorBuffer", sGPUParticleAttractorBuffer);
        }

        // Vector Fields.
        Dictionary <GPUParticleVectorField, GPUParticleVectorField> vectorFieldDictionary = GPUParticleVectorField.GetGPUParticleAttractorDictionary();

        if (vectorFieldDictionary == null)
        {
            sComputeShader.SetInt("gVectorFieldCount", 0);
        }
        else
        {
            Debug.Assert(vectorFieldDictionary.Count < sMaxVectorFieldCount);

            float[] vectorFieldArray = new float[vectorFieldDictionary.Count * 8];
            int     i     = 0;
            int     count = 0;
            foreach (KeyValuePair <GPUParticleVectorField, GPUParticleVectorField> it in vectorFieldDictionary)
            {
                GPUParticleVectorField vectorField = it.Value;

                //Skip if inactive.
                if (!vectorField.gameObject.activeInHierarchy)
                {
                    continue;
                }

                float   scale  = Mathf.Max(Mathf.Max(vectorField.transform.localScale.x, vectorField.transform.localScale.y), vectorField.transform.localScale.z);
                Vector3 vector = vectorField.RelativeVectorField ? vectorField.VectorRelative : vectorField.Vector;

                vectorFieldArray[i++] = vectorField.transform.position.x;
                vectorFieldArray[i++] = vectorField.transform.position.y;
                vectorFieldArray[i++] = vectorField.transform.position.z;
                vectorFieldArray[i++] = vector.x;
                vectorFieldArray[i++] = vector.y;
                vectorFieldArray[i++] = vector.z;
                vectorFieldArray[i++] = scale * vectorField.Min;
                vectorFieldArray[i++] = scale * vectorField.Max;

                count++;
            }
            sGPUParticleVectorFieldBuffer.SetData(vectorFieldArray);

            sComputeShader.SetInt("gVectorFieldCount", count);
            sComputeShader.SetBuffer(sKernelUpdate, "gVectorFieldBuffer", sGPUParticleVectorFieldBuffer);
        }

        // SPHERE COLLIDER.
        List <GPUParticleSphereCollider> sphereColliderList = GPUParticleSphereCollider.GetGPUParticleSphereColliderList();

        if (sphereColliderList == null)
        {
            sComputeShader.SetInt("gSphereColliderCount", 0);
        }
        else
        {
            Debug.Assert(sphereColliderList.Count < sMaxSphereColliderCount);

            // Reset result buffer.
            int[] resetArray = new int[sphereColliderList.Count];
            for (int i = 0; i < sphereColliderList.Count; ++i)
            {
                resetArray[i] = 0;
            }
            mSphereColliderResultBuffer.SetData(resetArray);

            // Update sphere collider buffer.
            float[] sphereColliderArray = new float[sphereColliderList.Count * 4];
            int     count = 0;
            for (int i = 0, j = 0; i < sphereColliderList.Count; ++i)
            {
                GPUParticleSphereCollider sphereCollider = sphereColliderList[i];

                //Skip if inactive.
                if (!sphereCollider.gameObject.activeInHierarchy)
                {
                    continue;
                }

                float scale = Mathf.Max(Mathf.Max(sphereCollider.transform.localScale.x, sphereCollider.transform.localScale.y), sphereCollider.transform.localScale.z);

                sphereColliderArray[j++] = sphereCollider.transform.position.x;
                sphereColliderArray[j++] = sphereCollider.transform.position.y;
                sphereColliderArray[j++] = sphereCollider.transform.position.z;
                sphereColliderArray[j++] = scale * sphereCollider.Radius;

                count++;
            }

            sGPUParticleSphereColliderBuffer.SetData(sphereColliderArray);

            sComputeShader.SetInt("gSphereColliderCount", count);
            sComputeShader.SetBuffer(sKernelUpdate, "gSphereColliderBuffer", sGPUParticleSphereColliderBuffer);
            sComputeShader.SetBuffer(sKernelUpdate, "gSphereColliderResultBufferWRITE", mSphereColliderResultBuffer);
        }

        // DISPATCH.
        sComputeShader.Dispatch(sKernelUpdate, (int)Mathf.Ceil(mMaxParticleCount / 64.0f), 1, 1);
    }
Example #2
0
    public static GameObject CreateAttractorWand(float power, bool rightHand)
    {
        //The wand is the parent object to all the parts.
        GameObject WandGO = new GameObject("AttractorWand" + count++);

        //The rod
        //We set its transform.
        GameObject RodGO = new GameObject("Rod" + count++);

        RodGO.transform.parent      = WandGO.transform;
        RodGO.transform.localScale += Vector3.up * 8;
        RodGO.transform.localScale *= 0.2f;
        RodGO.transform.position   += Vector3.forward * 0.2f;
        TempVisuals(RodGO, PrimitiveType.Cylinder, Color.black);

        //The tip
        //We set its transform
        GameObject TipGO = new GameObject("Tip" + count++);

        TipGO.transform.parent      = WandGO.transform;
        TipGO.transform.position   += Vector3.up * 2;
        TipGO.transform.localScale *= 0.5f;
        TipGO.transform.position   += Vector3.forward * 0.2f;
        TempVisuals(TipGO, PrimitiveType.Sphere, Color.red);

        WandGO.transform.localScale *= 0.1f;

        //We add the emitter to the tip.
        GPUParticleSystem system = TipGO.AddComponent <GPUParticleSystem>();

        Health.HEALTH_FACTOR = 1.0f;
        GPUParticleDescriptor descriptor = new GPUParticleDescriptor();

        descriptor.EmittFrequency  = 500.0f;
        descriptor.Lifetime        = 5.0f;
        descriptor.InheritVelocity = false;

        GPUParticleDescriptor.LifetimePoints colorPoints = new GPUParticleDescriptor.LifetimePoints();
        colorPoints.Add(new Vector4(0, 1, 0, 0));
        colorPoints.Add(new Vector4(1, 1, 0, 0.1f));
        colorPoints.Add(new Vector4(0, 1, 0, 0.2f));
        colorPoints.Add(new Vector4(1, 0, 0, 0.3f));
        colorPoints.Add(new Vector4(0, 1, 0, 0.4f));
        colorPoints.Add(new Vector4(0, 0, 1, 0.5f));
        colorPoints.Add(new Vector4(1, 0, 1, 0.6f));
        colorPoints.Add(new Vector4(0, 1, 1, 0.7f));
        colorPoints.Add(new Vector4(0, 1, 0, 0.8f));
        colorPoints.Add(new Vector4(1, 1, 1, 0.9f));
        colorPoints.Add(new Vector4(1, 1, 0, 1));
        descriptor.ColorOverLifetime = colorPoints;

        GPUParticleDescriptor.LifetimePoints haloPoints = new GPUParticleDescriptor.LifetimePoints();
        haloPoints.Add(new Vector4(1, 0, 0, 0));
        haloPoints.Add(new Vector4(0, 1, 0, 0.333f));
        haloPoints.Add(new Vector4(0, 0, 1, 0.666f));
        haloPoints.Add(new Vector4(0.5f, 0, 0.5f, 1));
        descriptor.HaloOverLifetime = haloPoints;

        GPUParticleDescriptor.LifetimePoints scalePoints = new GPUParticleDescriptor.LifetimePoints();
        scalePoints.Add(new Vector4(0.005f, 0.005f, 0, 0));
        scalePoints.Add(new Vector4(0.005f, 0.005f, 0, 1));
        descriptor.ScaleOverLifetime = scalePoints;

        GPUParticleDescriptor.LifetimePoints opacityPoints = new GPUParticleDescriptor.LifetimePoints();
        opacityPoints.Add(new Vector4(0.0f, 0, 0, 0));
        opacityPoints.Add(new Vector4(1.0f, 0, 0, 0.1f));
        opacityPoints.Add(new Vector4(1.0f, 0, 0, 0.8f));
        opacityPoints.Add(new Vector4(0.0f, 0, 0, 1.0f));
        descriptor.OpacityOverLifetime = opacityPoints;

        descriptor.EmittMesh = TipGO.GetComponent <MeshFilter>().mesh;

        system.ParticleDescriptor = descriptor;

        //We add an attractor to the tip.
        GPUParticleAttractor attractor = TipGO.AddComponent <GPUParticleAttractor>();

        attractor.Power = 1;

        //We add vector field to the tip.
        GPUParticleVectorField vectorField = TipGO.AddComponent <GPUParticleVectorField>();

        vectorField.Max = 0.3f;

        WandGO.transform.Rotate(90, 0, 0);

        AttractorWand wand = WandGO.AddComponent <AttractorWand>();

        wand.power     = power;
        wand.rightHand = rightHand;

        wand.system      = system;
        wand.attractor   = attractor;
        wand.vectorField = vectorField;

        GameObject hand = new GameObject(rightHand ? "Right" : "Left" + "hand");

        WandGO.transform.parent = hand.transform;

        hand.AddComponent <MirrorHandMovement>().rightHand = rightHand;

        return(hand);
    }