void Update() { #if true _particles.Prepare(_kernelUpdate); compute.SetFloat(PROP_TIME_DELTA, Time.deltaTime); compute.Dispatch(_kernelUpdate, _particles.NGroupsX, _particles.NGroupsY, 1); if (splash) { var mousePos = Input.mousePosition; mousePos.z = 10f; var ray = Camera.main.ScreenPointToRay(mousePos); var localDir = transform.InverseTransformDirection(ray.direction); var localPos = transform.InverseTransformPoint(ray.origin); var particles = new GPUParticle[] { new GPUParticle() { life = 5, velocity = speed * localDir, position = localPos } }; _particles.Emit(particles); } #else if (splash) { var particles = new GPUParticle[] { new GPUParticle() { life = 5, position = 10f * Random.insideUnitSphere } }; _particles.Emit(particles); } #endif }
void Emit() { if (particle == null) { particle = GetComponent <GPUParticle>(); } particle.EmitWithTexture(posTex, normTex, colTex); }
// Update is called once per frame void Update() { particleMaterial.SetFloat("Brightness", brightness); frameTime -= Time.deltaTime; if (frameTime > 0) { return; } frameTime = 1.0f / FrameRate; int count = particlesToRender.GetParticles(particles); if (count != 0) { ComputeBuffer particleBuffer = new ComputeBuffer(count, 8 * sizeof(float)); GPUParticle[] gpuParticles = new GPUParticle[count]; for (int i = 0; i < count; i++) { gpuParticles[i].pos = particles[i].position; gpuParticles[i].col = particles[i].GetCurrentColor(particlesToRender); } particleBuffer.SetData(gpuParticles); SimulateShader.SetBuffer(generatePointsKernel, "Particles", particleBuffer); var mat = transform.localToWorldMatrix.transpose; SimulateShader.SetFloats("Object2World", new float[] { mat.m00, mat.m01, mat.m02, mat.m03, mat.m10, mat.m11, mat.m12, mat.m13, mat.m20, mat.m21, mat.m22, mat.m23, mat.m30, mat.m31, mat.m32, mat.m33, }); SimulateShader.SetInt("Resolution", Resolution); pointBuffer.SetCounterValue(0); SimulateShader.SetBuffer(generatePointsKernel, "PointBufferOutput", pointBuffer); SimulateShader.Dispatch(generatePointsKernel, Resolution / 8, Resolution / 8, Resolution / 8); particleBuffer.Release(); OnWillRenderObject(); } }
void InitGPUParticleSystem() { if (!particleComputeShader || !particleMat) { return; } ParticleSize = Marshal.SizeOf(typeof(GPUParticle)); //找到更新函数 gpuUpdateKernelIndex = particleComputeShader.FindKernel(computeShaderEntryPoint); currentParticleCout = ParticleCout; cpuParticleBuffer = null; cpuParticleBuffer = new GPUParticle[currentParticleCout]; gpuThreadGroupNum = Mathf.CeilToInt((float)ParticleCout / WARP_SIZE); gpuParticleBuffer = new ComputeBuffer(ParticleCout, ParticleSize); //初始化粒子buffer for (int i = 0; i < currentParticleCout; i++) { cpuParticleBuffer[i] = new GPUParticle(); cpuParticleBuffer[i].position = Random.insideUnitCircle * 10f; cpuParticleBuffer[i].velocity = Vector2.zero; } //传递CPU初始化数据给GPU buffer gpuParticleBuffer.SetData(cpuParticleBuffer); //给computeshader中的函数设置数据源 particleComputeShader.SetBuffer(gpuUpdateKernelIndex, computeShaderGPUBufferName, gpuParticleBuffer); //给shader设置buffer数据,用来做渲染用 particleMat.SetBuffer(computeShaderGPUBufferName, gpuParticleBuffer); renderCommandBuffer.DrawProcedural(transform.localToWorldMatrix, particleMat, 0, MeshTopology.Points, 1, currentParticleCout); }
public GPUParticle[] Emit(EmitShapeType shape, Vector3 centerPos, float size) { deltaTime += Time.deltaTime * count; int intDelta = (int)deltaTime; deltaTime -= intDelta; if (intDelta == 0) { return(null); } var particles = new GPUParticle[intDelta]; for (int i = 0; i < particles.Length; i++) { particles[i].pos = centerPos + GetPoint(shape, size); particles[i].velocity = velocity; particles[i].lifeTime = lifeTime; } return(particles); }