// 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); }
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); }