|  |  |  |  | using UnityEngine; | 
					
						
							|  |  |  |  | namespace FluidDynamics | 
					
						
							|  |  |  |  | { | 
					
						
							|  |  |  |  |     [AddComponentMenu("Fluid Dynamics/Fluid Simulator")] | 
					
						
							|  |  |  |  |     public class Main_Fluid_Simulation : MonoBehaviour | 
					
						
							|  |  |  |  |     { | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         #region Variables | 
					
						
							|  |  |  |  |         [HideInInspector] | 
					
						
							|  |  |  |  |         public ComputeShader m_simulationShader; | 
					
						
							|  |  |  |  |         [HideInInspector] | 
					
						
							|  |  |  |  |         public ComputeShader m_particleAreaShader; | 
					
						
							|  |  |  |  |         public bool m_simulate = true; | 
					
						
							|  |  |  |  |         [HideInInspector] | 
					
						
							|  |  |  |  |         public float m_speed = 500f; | 
					
						
							|  |  |  |  |         public float Speed { get { return m_speed; } set { m_speed = value; } } | 
					
						
							|  |  |  |  |         [HideInInspector] | 
					
						
							|  |  |  |  |         public int m_iterations = 50; | 
					
						
							|  |  |  |  |         public int Iterations { get { return m_iterations; } set { m_iterations = value; } } | 
					
						
							|  |  |  |  |         [HideInInspector] | 
					
						
							|  |  |  |  |         public float m_velocityDissipation = 1f; | 
					
						
							|  |  |  |  |         public float VelocityDissipation { get { return m_velocityDissipation; } set { m_velocityDissipation = value; } } | 
					
						
							|  |  |  |  |         [HideInInspector] | 
					
						
							|  |  |  |  |         public float m_vorticityScale = 0f; | 
					
						
							|  |  |  |  |         public float Vorticity { get { return m_vorticityScale; } set { m_vorticityScale = value; } } | 
					
						
							|  |  |  |  |         [HideInInspector] | 
					
						
							|  |  |  |  |         public float m_viscosity = 0f; | 
					
						
							|  |  |  |  |         public float Viscosity { get { return m_viscosity; } set { m_viscosity = value; } } | 
					
						
							|  |  |  |  |         [HideInInspector] | 
					
						
							|  |  |  |  |         public int m_nResolution = 512; | 
					
						
							|  |  |  |  |         [HideInInspector] | 
					
						
							|  |  |  |  |         public bool m_cacheVelocity = false; | 
					
						
							|  |  |  |  |         public int Resolution { get { return m_nResolution; } set { m_nResolution = value; } } | 
					
						
							|  |  |  |  |         public ComputeBuffer VelocityBuffer { get { return m_velocityBuffer[VELOCITY_READ]; } } | 
					
						
							|  |  |  |  |         public ComputeBuffer DivergenceBuffer { get { return m_divergenceBuffer; } } | 
					
						
							|  |  |  |  |         public ComputeBuffer PressureBuffer { get { return m_pressure[PRESSURE_READ]; } } | 
					
						
							|  |  |  |  |         public ComputeBuffer ObstaclesBuffer { get { return m_obstaclesBuffer; } } | 
					
						
							|  |  |  |  |         private ComputeBuffer m_obstaclesBuffer; | 
					
						
							|  |  |  |  |         private ComputeBuffer[] m_velocityBuffer; | 
					
						
							|  |  |  |  |         private ComputeBuffer m_divergenceBuffer; | 
					
						
							|  |  |  |  |         private ComputeBuffer[] m_pressure; | 
					
						
							|  |  |  |  |         private ComputeBuffer m_vorticityBuffer; | 
					
						
							|  |  |  |  |         private Vector2[] m_currentVelocity; | 
					
						
							|  |  |  |  |         private int m_nNumCells; | 
					
						
							|  |  |  |  |         private int m_nNumGroupsX; | 
					
						
							|  |  |  |  |         private int m_nNumGroupsY; | 
					
						
							|  |  |  |  |         private int m_nWidth = 512; | 
					
						
							|  |  |  |  |         private int m_nHeight = 512; | 
					
						
							|  |  |  |  |         private int m_addVelocityKernel = 0; | 
					
						
							|  |  |  |  |         private int m_initBoundariesKernel = 0; | 
					
						
							|  |  |  |  |         private int m_advectVelocityKernel = 0; | 
					
						
							|  |  |  |  |         private int m_divergenceKernel = 0; | 
					
						
							|  |  |  |  |         private int m_poissonKernel = 0; | 
					
						
							|  |  |  |  |         private int m_substractGradientKernel = 0; | 
					
						
							|  |  |  |  |         private int m_calcVorticityKernel = 0; | 
					
						
							|  |  |  |  |         private int m_applyVorticityKernel = 0; | 
					
						
							|  |  |  |  |         private int m_viscosityKernel = 0; | 
					
						
							|  |  |  |  |         private int m_addObstacleCircleKernel = 0; | 
					
						
							|  |  |  |  |         private int m_addObstacleTriangleKernel = 0; | 
					
						
							|  |  |  |  |         private int m_clearBufferKernel = 0; | 
					
						
							|  |  |  |  |         private int VELOCITY_READ = 0; | 
					
						
							|  |  |  |  |         private int VELOCITY_WRITE = 1; | 
					
						
							|  |  |  |  |         private int PRESSURE_READ = 0; | 
					
						
							|  |  |  |  |         private int PRESSURE_WRITE = 1; | 
					
						
							|  |  |  |  |         #endregion | 
					
						
							|  |  |  |  |         // | 
					
						
							|  |  |  |  |         #region Variables2 | 
					
						
							|  |  |  |  |         [Tooltip("If m_ExposeParticles is true the value of the particles will be cached in memory for use by other systems")] | 
					
						
							|  |  |  |  |         public bool m_CacheParticles = false; | 
					
						
							|  |  |  |  |         public Gradient m_colourGradient; | 
					
						
							|  |  |  |  |         public bool m_updateGradient = false; | 
					
						
							|  |  |  |  |         [HideInInspector] | 
					
						
							|  |  |  |  |         public float m_densityDissipation = 1f; | 
					
						
							|  |  |  |  |         public float Dissipation { get { return m_densityDissipation; } set { m_densityDissipation = value; } } | 
					
						
							|  |  |  |  |         public ComputeBuffer ParticlesBuffer { get { return m_particlesBuffer[READ]; } } | 
					
						
							|  |  |  |  |         private ComputeBuffer m_colourRamp; | 
					
						
							|  |  |  |  |         private int m_addParticlesKernel = 0; | 
					
						
							|  |  |  |  |         private int m_advectKernel = 0; | 
					
						
							|  |  |  |  |         [HideInInspector] | 
					
						
							|  |  |  |  |         public int m_nParticlesResolution = 128; | 
					
						
							|  |  |  |  |         public int ParticlesResolution | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             get | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 return m_nParticlesResolution; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             set | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 if (value != m_nParticlesResolution) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_nParticlesResolution = value; | 
					
						
							|  |  |  |  |                     if (Application.isPlaying && m_particlesBuffer[0] != null && m_particlesBuffer[1] != null) | 
					
						
							|  |  |  |  |                     { | 
					
						
							|  |  |  |  |                         int nOldHeight = m_nParticlesHeight; | 
					
						
							|  |  |  |  |                         int nOldWidth = m_nParticlesWidth; | 
					
						
							|  |  |  |  |                         float[] oldParticleData = new float[nOldWidth * nOldHeight]; | 
					
						
							|  |  |  |  |                         m_particlesBuffer[READ].GetData(oldParticleData); | 
					
						
							|  |  |  |  |                         m_particlesBuffer[0].Dispose(); | 
					
						
							|  |  |  |  |                         m_particlesBuffer[1].Dispose(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                         CalculateSize(); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                         float[] newParticleData = new float[m_nParticlesWidth * m_nParticlesHeight]; | 
					
						
							|  |  |  |  |                         for (int i = 0; i < m_nParticlesHeight; ++i) | 
					
						
							|  |  |  |  |                         { | 
					
						
							|  |  |  |  |                             for (int j = 0; j < m_nParticlesWidth; ++j) | 
					
						
							|  |  |  |  |                             { | 
					
						
							|  |  |  |  |                                 float normX = (float)j / (float)m_nParticlesWidth; | 
					
						
							|  |  |  |  |                                 float normY = (float)i / (float)m_nParticlesHeight; | 
					
						
							|  |  |  |  |                                 int x = (int)(normX * (float)nOldWidth); | 
					
						
							|  |  |  |  |                                 int y = (int)(normY * (float)nOldHeight); | 
					
						
							|  |  |  |  |                                 newParticleData[i * m_nParticlesWidth + j] = oldParticleData[y * nOldWidth + x]; | 
					
						
							|  |  |  |  |                             } | 
					
						
							|  |  |  |  |                         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                         m_particlesBuffer = new ComputeBuffer[2]; | 
					
						
							|  |  |  |  |                         for (int i = 0; i < 2; ++i) | 
					
						
							|  |  |  |  |                         { | 
					
						
							|  |  |  |  |                             m_particlesBuffer[i] = new ComputeBuffer(m_nParticlesWidth * m_nParticlesHeight, 4, ComputeBufferType.Default); | 
					
						
							|  |  |  |  |                         } | 
					
						
							|  |  |  |  |                         m_particlesBuffer[READ].SetData(newParticleData); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         private int m_nColourRampSize = 256; | 
					
						
							|  |  |  |  |         private ComputeBuffer[] m_particlesBuffer; | 
					
						
							|  |  |  |  |         private int m_nParticlesNumGroupsX; | 
					
						
							|  |  |  |  |         private int m_nParticlesNumGroupsY; | 
					
						
							|  |  |  |  |         private int m_nParticlesWidth = 512; | 
					
						
							|  |  |  |  |         private int m_nParticlesHeight = 512; | 
					
						
							|  |  |  |  |         private int READ = 0; | 
					
						
							|  |  |  |  |         private int WRITE = 1; | 
					
						
							|  |  |  |  |         private float[] m_currentParticles; | 
					
						
							|  |  |  |  |         private Renderer m_tempRend; | 
					
						
							|  |  |  |  |         #endregion | 
					
						
							|  |  |  |  |         // | 
					
						
							|  |  |  |  |         #region Variables3 | 
					
						
							|  |  |  |  |         static readonly int _Size = Shader.PropertyToID("_Size"); | 
					
						
							|  |  |  |  |         static readonly int _VelocityIn = Shader.PropertyToID("_VelocityIn"); | 
					
						
							|  |  |  |  |         static readonly int _VelocityOut = Shader.PropertyToID("_VelocityOut"); | 
					
						
							|  |  |  |  |         static readonly int _Obstacles = Shader.PropertyToID("_Obstacles"); | 
					
						
							|  |  |  |  |         static readonly int _Divergence = Shader.PropertyToID("_Divergence"); | 
					
						
							|  |  |  |  |         static readonly int _PressureIn = Shader.PropertyToID("_PressureIn"); | 
					
						
							|  |  |  |  |         static readonly int _PressureOut = Shader.PropertyToID("_PressureOut"); | 
					
						
							|  |  |  |  |         static readonly int _Vorticity = Shader.PropertyToID("_Vorticity"); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         static readonly int _ElapsedTime = Shader.PropertyToID("_ElapsedTime"); | 
					
						
							|  |  |  |  |         static readonly int _Speed = Shader.PropertyToID("_Speed"); | 
					
						
							|  |  |  |  |         static readonly int _Radius = Shader.PropertyToID("_Radius"); | 
					
						
							|  |  |  |  |         static readonly int _Position = Shader.PropertyToID("_Position"); | 
					
						
							|  |  |  |  |         static readonly int _Value = Shader.PropertyToID("_Value"); | 
					
						
							|  |  |  |  |         static readonly int _VorticityScale = Shader.PropertyToID("_VorticityScale"); | 
					
						
							|  |  |  |  |         static readonly int _Static = Shader.PropertyToID("_Static"); | 
					
						
							|  |  |  |  |         static readonly int _P1 = Shader.PropertyToID("_P1"); | 
					
						
							|  |  |  |  |         static readonly int _P2 = Shader.PropertyToID("_P2"); | 
					
						
							|  |  |  |  |         static readonly int _P3 = Shader.PropertyToID("_P3"); | 
					
						
							|  |  |  |  |         static readonly int _ParticlesIn = Shader.PropertyToID("_ParticlesIn"); | 
					
						
							|  |  |  |  |         static readonly int _ParticlesOut = Shader.PropertyToID("_ParticlesOut"); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         static readonly int _ParticleSize = Shader.PropertyToID("_ParticleSize"); | 
					
						
							|  |  |  |  |         static readonly int _Velocity = Shader.PropertyToID("_Velocity"); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         static readonly int _VelocitySize = Shader.PropertyToID("_VelocitySize"); | 
					
						
							|  |  |  |  |         static readonly int _Dissipation = Shader.PropertyToID("_Dissipation"); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         static readonly int _Buffer = Shader.PropertyToID("_Buffer"); | 
					
						
							|  |  |  |  |         static readonly int _Particles = Shader.PropertyToID("_Particles"); | 
					
						
							|  |  |  |  |         static readonly int _ColourRamp = Shader.PropertyToID("_ColourRamp"); | 
					
						
							|  |  |  |  |         static readonly int _Alpha = Shader.PropertyToID("_Alpha"); | 
					
						
							|  |  |  |  |         static readonly int _rBeta = Shader.PropertyToID("_rBeta"); | 
					
						
							|  |  |  |  |         #endregion | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         private void Start() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             m_simulationShader = (ComputeShader)Instantiate(Resources.Load("FLUID_DYNAMICS_SIMULATION")); | 
					
						
							|  |  |  |  |             m_particleAreaShader = (ComputeShader)Instantiate(Resources.Load("FLUID_DYNAMICS_PARTICLES")); | 
					
						
							|  |  |  |  |             m_tempRend = GetComponent<Renderer>(); | 
					
						
							|  |  |  |  |             if (SystemInfo.supportsComputeShaders) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_nNumCells = m_nWidth * m_nHeight; | 
					
						
							|  |  |  |  |                 m_addVelocityKernel = m_simulationShader.FindKernel("AddVelocity"); | 
					
						
							|  |  |  |  |                 m_initBoundariesKernel = m_simulationShader.FindKernel("InitBoundaries"); | 
					
						
							|  |  |  |  |                 m_advectVelocityKernel = m_simulationShader.FindKernel("AdvectVelocity"); | 
					
						
							|  |  |  |  |                 m_divergenceKernel = m_simulationShader.FindKernel("Divergence"); | 
					
						
							|  |  |  |  |                 m_clearBufferKernel = m_simulationShader.FindKernel("ClearBuffer"); | 
					
						
							|  |  |  |  |                 m_poissonKernel = m_simulationShader.FindKernel("Poisson"); | 
					
						
							|  |  |  |  |                 m_substractGradientKernel = m_simulationShader.FindKernel("SubstractGradient"); | 
					
						
							|  |  |  |  |                 m_calcVorticityKernel = m_simulationShader.FindKernel("CalcVorticity"); | 
					
						
							|  |  |  |  |                 m_applyVorticityKernel = m_simulationShader.FindKernel("ApplyVorticity"); | 
					
						
							|  |  |  |  |                 m_viscosityKernel = m_simulationShader.FindKernel("Viscosity"); | 
					
						
							|  |  |  |  |                 m_addObstacleCircleKernel = m_simulationShader.FindKernel("AddCircleObstacle"); | 
					
						
							|  |  |  |  |                 m_addObstacleTriangleKernel = m_simulationShader.FindKernel("AddTriangleObstacle"); | 
					
						
							|  |  |  |  |                 CalculateSize(); | 
					
						
							|  |  |  |  |                 LinkToFluidSimulation(); | 
					
						
							|  |  |  |  |                 m_advectKernel = m_particleAreaShader.FindKernel("Advect"); | 
					
						
							|  |  |  |  |                 m_addParticlesKernel = m_particleAreaShader.FindKernel("AddParticles"); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             else | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_simulate = false; | 
					
						
							|  |  |  |  |                 Debug.LogError("Seems like your target Hardware does not support Compute Shaders. 'Fluid Dynamics' needs support for Compute Shaders to work."); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         private void Update() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             if (m_simulate) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 UpdateParameters(); | 
					
						
							|  |  |  |  |                 CreateBuffersIfNeeded(); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_initBoundariesKernel, _VelocityIn, m_velocityBuffer[VELOCITY_READ]); | 
					
						
							|  |  |  |  |                 m_simulationShader.Dispatch(m_initBoundariesKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_advectVelocityKernel, _Obstacles, m_obstaclesBuffer); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_advectVelocityKernel, _VelocityIn, m_velocityBuffer[VELOCITY_READ]); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_advectVelocityKernel, _VelocityOut, m_velocityBuffer[VELOCITY_WRITE]); | 
					
						
							|  |  |  |  |                 m_simulationShader.Dispatch(m_advectVelocityKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |                 FlipVelocityBuffers(); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_calcVorticityKernel, _VelocityIn, m_velocityBuffer[VELOCITY_READ]); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_calcVorticityKernel, _Vorticity, m_vorticityBuffer); | 
					
						
							|  |  |  |  |                 m_simulationShader.Dispatch(m_calcVorticityKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_applyVorticityKernel, _VelocityIn, m_velocityBuffer[VELOCITY_READ]); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_applyVorticityKernel, _Vorticity, m_vorticityBuffer); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_applyVorticityKernel, _VelocityOut, m_velocityBuffer[VELOCITY_WRITE]); | 
					
						
							|  |  |  |  |                 m_simulationShader.Dispatch(m_applyVorticityKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |                 FlipVelocityBuffers(); | 
					
						
							|  |  |  |  |                 if (m_viscosity > 0.0f) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     for (int i = 0; i < m_iterations; ++i) | 
					
						
							|  |  |  |  |                     { | 
					
						
							|  |  |  |  |                         m_simulationShader.SetBuffer(m_viscosityKernel, _VelocityIn, m_velocityBuffer[VELOCITY_READ]); | 
					
						
							|  |  |  |  |                         m_simulationShader.SetBuffer(m_viscosityKernel, _VelocityOut, m_velocityBuffer[VELOCITY_WRITE]); | 
					
						
							|  |  |  |  |                         m_simulationShader.Dispatch(m_viscosityKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |                         FlipVelocityBuffers(); | 
					
						
							|  |  |  |  |                     } | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_divergenceKernel, _VelocityIn, m_velocityBuffer[VELOCITY_READ]); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_divergenceKernel, _Obstacles, m_obstaclesBuffer); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_divergenceKernel, _Divergence, m_divergenceBuffer); | 
					
						
							|  |  |  |  |                 m_simulationShader.Dispatch(m_divergenceKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_clearBufferKernel, _Buffer, m_pressure[PRESSURE_READ]); | 
					
						
							|  |  |  |  |                 m_simulationShader.Dispatch(m_clearBufferKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_poissonKernel, _Divergence, m_divergenceBuffer); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_poissonKernel, _Obstacles, m_obstaclesBuffer); | 
					
						
							|  |  |  |  |                 for (int i = 0; i < m_iterations; ++i) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_simulationShader.SetBuffer(m_poissonKernel, _PressureIn, m_pressure[PRESSURE_READ]); | 
					
						
							|  |  |  |  |                     m_simulationShader.SetBuffer(m_poissonKernel, _PressureOut, m_pressure[PRESSURE_WRITE]); | 
					
						
							|  |  |  |  |                     m_simulationShader.Dispatch(m_poissonKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |                     FlipPressureBuffers(); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_substractGradientKernel, _PressureIn, m_pressure[PRESSURE_READ]); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_substractGradientKernel, _VelocityIn, m_velocityBuffer[VELOCITY_READ]); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_substractGradientKernel, _VelocityOut, m_velocityBuffer[VELOCITY_WRITE]); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_substractGradientKernel, _Obstacles, m_obstaclesBuffer); | 
					
						
							|  |  |  |  |                 m_simulationShader.Dispatch(m_substractGradientKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |                 FlipVelocityBuffers(); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_clearBufferKernel, _Buffer, m_obstaclesBuffer); | 
					
						
							|  |  |  |  |                 m_simulationShader.Dispatch(m_clearBufferKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |                 if (m_cacheVelocity) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_velocityBuffer[VELOCITY_READ].GetData(m_currentVelocity); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_particlesBuffer == null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 //Debug.Log( null ); | 
					
						
							|  |  |  |  |                 m_particlesBuffer = new ComputeBuffer[2]; | 
					
						
							|  |  |  |  |                 for (int i = 0; i < 2; ++i) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_particlesBuffer[i] = new ComputeBuffer(m_nParticlesWidth * m_nParticlesHeight, 4, ComputeBufferType.Default); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             m_particleAreaShader.SetFloat(_Dissipation, m_densityDissipation); | 
					
						
							|  |  |  |  |             m_particleAreaShader.SetFloat(_ElapsedTime, Time.deltaTime); | 
					
						
							|  |  |  |  |             m_particleAreaShader.SetFloat(_Speed, GetSimulationSpeed()); | 
					
						
							|  |  |  |  |             m_particleAreaShader.SetBuffer(m_advectKernel, _Obstacles, ObstaclesBuffer); | 
					
						
							|  |  |  |  |             m_particleAreaShader.SetBuffer(m_advectKernel, _Velocity, VelocityBuffer); | 
					
						
							|  |  |  |  |             m_particleAreaShader.SetBuffer(m_advectKernel, _ParticlesIn, m_particlesBuffer[READ]); | 
					
						
							|  |  |  |  |             m_particleAreaShader.SetBuffer(m_advectKernel, _ParticlesOut, m_particlesBuffer[WRITE]); | 
					
						
							|  |  |  |  |             m_particleAreaShader.Dispatch(m_advectKernel, m_nParticlesNumGroupsX, m_nParticlesNumGroupsY, 1); | 
					
						
							|  |  |  |  |             FlipBuffers(); | 
					
						
							|  |  |  |  |             if (m_colourRamp == null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_colourRamp = new ComputeBuffer(m_nColourRampSize, 16, ComputeBufferType.Default); | 
					
						
							|  |  |  |  |                 UpdateGradient(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_updateGradient) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 UpdateGradient(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             m_tempRend.material.SetBuffer(_Particles, m_particlesBuffer[READ]); | 
					
						
							|  |  |  |  |             m_tempRend.material.SetBuffer(_ColourRamp, m_colourRamp); | 
					
						
							|  |  |  |  |             m_tempRend.material.SetVector(_Size, new Vector2(m_nParticlesWidth, m_nParticlesHeight)); | 
					
						
							|  |  |  |  |             if (m_CacheParticles) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_particlesBuffer[READ].GetData(m_currentParticles); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         private void OnDisable() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             if (m_velocityBuffer != null && m_velocityBuffer.Length == 2) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 if (m_velocityBuffer[0] != null) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_velocityBuffer[0].Dispose(); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |                 if (m_velocityBuffer[1] != null) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_velocityBuffer[1].Dispose(); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_divergenceBuffer != null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_divergenceBuffer.Dispose(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_pressure != null && m_pressure.Length == 2) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 if (m_pressure[0] != null) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_pressure[0].Dispose(); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |                 if (m_pressure[1] != null) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_pressure[1].Dispose(); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_obstaclesBuffer != null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_obstaclesBuffer.Dispose(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_vorticityBuffer != null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_vorticityBuffer.Dispose(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_colourRamp != null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_colourRamp.Dispose(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_particlesBuffer != null && m_particlesBuffer.Length == 2) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 if (m_particlesBuffer[0] != null) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_particlesBuffer[0].Dispose(); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |                 if (m_particlesBuffer[1] != null) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_particlesBuffer[1].Dispose(); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |         public void SetSize(int nWidth, int nHeight) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             uint groupSizeX = 8; | 
					
						
							|  |  |  |  |             uint groupSizeY = 8; | 
					
						
							|  |  |  |  |             uint groupSizeZ = 8; | 
					
						
							|  |  |  |  |             m_simulationShader.GetKernelThreadGroupSizes(0, out groupSizeX, out groupSizeY, out groupSizeZ); | 
					
						
							|  |  |  |  |             m_nWidth = nWidth; | 
					
						
							|  |  |  |  |             m_nHeight = nHeight; | 
					
						
							|  |  |  |  |             m_nNumCells = m_nWidth * m_nHeight; | 
					
						
							|  |  |  |  |             m_nNumGroupsX = Mathf.CeilToInt((float)m_nWidth / (float)groupSizeX); | 
					
						
							|  |  |  |  |             m_nNumGroupsY = Mathf.CeilToInt((float)m_nHeight / (float)groupSizeX); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public int GetWidth() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return m_nWidth; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public int GetHeight() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return m_nHeight; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public void AddVelocity(Vector2 position, Vector2 velocity, float fRadius) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             if (m_simulationShader != null && m_velocityBuffer != null && m_velocityBuffer.Length >= 2) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 float[] pos = { position.x, position.y }; | 
					
						
							|  |  |  |  |                 m_simulationShader.SetFloats(_Position, pos); | 
					
						
							|  |  |  |  |                 float[] val = { velocity.x, velocity.y }; | 
					
						
							|  |  |  |  |                 m_simulationShader.SetFloats(_Value, val); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetFloat(_Radius, fRadius); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetInts(_Size, new int[] { m_nWidth, m_nHeight }); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_addVelocityKernel, _VelocityIn, m_velocityBuffer[VELOCITY_READ]); | 
					
						
							|  |  |  |  |                 m_simulationShader.SetBuffer(m_addVelocityKernel, _VelocityOut, m_velocityBuffer[VELOCITY_WRITE]); | 
					
						
							|  |  |  |  |                 m_simulationShader.Dispatch(m_addVelocityKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |                 FlipVelocityBuffers(); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public void AddObstacleCircle(Vector2 position, float fRadius, bool bStatic) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             float[] pos = { position.x, position.y }; | 
					
						
							|  |  |  |  |             m_simulationShader.SetFloats(_Position, pos); | 
					
						
							|  |  |  |  |             m_simulationShader.SetFloat(_Radius, fRadius); | 
					
						
							|  |  |  |  |             m_simulationShader.SetInt(_Static, bStatic ? 1 : 0); | 
					
						
							|  |  |  |  |             m_simulationShader.SetBuffer(m_addObstacleCircleKernel, _Obstacles, m_obstaclesBuffer); | 
					
						
							|  |  |  |  |             m_simulationShader.Dispatch(m_addObstacleCircleKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public void AddObstacleTriangle(Vector2 p1, Vector2 p2, Vector2 p3, bool bStatic = false) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             float[] pos1 = { p1.x, p1.y }; | 
					
						
							|  |  |  |  |             float[] pos2 = { p2.x, p2.y }; | 
					
						
							|  |  |  |  |             float[] pos3 = { p3.x, p3.y }; | 
					
						
							|  |  |  |  |             m_simulationShader.SetFloats(_P1, pos1); | 
					
						
							|  |  |  |  |             m_simulationShader.SetFloats(_P2, pos2); | 
					
						
							|  |  |  |  |             m_simulationShader.SetFloats(_P3, pos3); | 
					
						
							|  |  |  |  |             m_simulationShader.SetInt(_Static, bStatic ? 1 : 0); | 
					
						
							|  |  |  |  |             m_simulationShader.SetBuffer(m_addObstacleTriangleKernel, _Obstacles, m_obstaclesBuffer); | 
					
						
							|  |  |  |  |             m_simulationShader.Dispatch(m_addObstacleTriangleKernel, m_nNumGroupsX, m_nNumGroupsY, 1); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public Vector2 GetVelocity(int x, int y) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return m_currentVelocity[y * m_nWidth + x] * m_speed; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public void InitShaders() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             CreateBuffersIfNeeded(); | 
					
						
							|  |  |  |  |             UpdateParameters(); | 
					
						
							|  |  |  |  |             int[] size = new int[] { m_nWidth, m_nHeight }; | 
					
						
							|  |  |  |  |             m_simulationShader.SetInts(_Size, size); | 
					
						
							|  |  |  |  |             m_currentVelocity = new Vector2[m_nNumCells]; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public float GetSimulationSpeed() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return m_speed; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         private void CreateBuffersIfNeeded() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             if (m_velocityBuffer == null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_velocityBuffer = new ComputeBuffer[2]; | 
					
						
							|  |  |  |  |                 for (int i = 0; i < 2; ++i) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_velocityBuffer[i] = new ComputeBuffer(m_nNumCells, 8, ComputeBufferType.Default); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_divergenceBuffer == null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_divergenceBuffer = new ComputeBuffer(m_nNumCells, 4, ComputeBufferType.Default); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_pressure == null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_pressure = new ComputeBuffer[2]; | 
					
						
							|  |  |  |  |                 for (int i = 0; i < 2; ++i) | 
					
						
							|  |  |  |  |                 { | 
					
						
							|  |  |  |  |                     m_pressure[i] = new ComputeBuffer(m_nNumCells, 4, ComputeBufferType.Default); | 
					
						
							|  |  |  |  |                 } | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_obstaclesBuffer == null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_obstaclesBuffer = new ComputeBuffer(m_nNumCells, 8, ComputeBufferType.Default); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             if (m_vorticityBuffer == null) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 m_vorticityBuffer = new ComputeBuffer(m_nNumCells, 4, ComputeBufferType.Default); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         private void UpdateParameters() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             m_simulationShader.SetFloat(_Dissipation, m_velocityDissipation); | 
					
						
							|  |  |  |  |             m_simulationShader.SetFloat(_ElapsedTime, Time.deltaTime); | 
					
						
							|  |  |  |  |             m_simulationShader.SetFloat(_Speed, m_speed); | 
					
						
							|  |  |  |  |             m_simulationShader.SetFloat(_VorticityScale, m_vorticityScale); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             float centreFactor = 1.0f / (m_viscosity); | 
					
						
							|  |  |  |  |             float stencilFactor = 1.0f / (4.0f + centreFactor); | 
					
						
							|  |  |  |  |             m_simulationShader.SetFloat(_Alpha, centreFactor); | 
					
						
							|  |  |  |  |             m_simulationShader.SetFloat(_rBeta, stencilFactor); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         private void FlipVelocityBuffers() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             int aux = VELOCITY_READ; | 
					
						
							|  |  |  |  |             VELOCITY_READ = VELOCITY_WRITE; | 
					
						
							|  |  |  |  |             VELOCITY_WRITE = aux; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         private void FlipPressureBuffers() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             int aux = PRESSURE_READ; | 
					
						
							|  |  |  |  |             PRESSURE_READ = PRESSURE_WRITE; | 
					
						
							|  |  |  |  |             PRESSURE_WRITE = aux; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public float GetParticles(int x, int y) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return m_currentParticles[y * m_nParticlesWidth + x]; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         private void CalculateSize() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             float x = gameObject.transform.lossyScale.x; | 
					
						
							|  |  |  |  |             float y = gameObject.transform.lossyScale.z; | 
					
						
							|  |  |  |  |             if (x > y) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 float fHeight = (y / x) * m_nParticlesResolution; | 
					
						
							|  |  |  |  |                 m_nParticlesWidth = m_nParticlesResolution; | 
					
						
							|  |  |  |  |                 m_nParticlesHeight = (int)fHeight; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             else | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 float fWidth = (x / y) * m_nParticlesResolution; | 
					
						
							|  |  |  |  |                 m_nParticlesWidth = (int)fWidth; | 
					
						
							|  |  |  |  |                 m_nParticlesHeight = m_nParticlesResolution; | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             SetSizeInShaders(); | 
					
						
							|  |  |  |  |             uint groupSizeX = 8; | 
					
						
							|  |  |  |  |             uint groupSizeY = 8; | 
					
						
							|  |  |  |  |             uint groupSizeZ = 8; | 
					
						
							|  |  |  |  |             m_particleAreaShader.GetKernelThreadGroupSizes(0, out groupSizeX, out groupSizeY, out groupSizeZ); | 
					
						
							|  |  |  |  |             m_nParticlesNumGroupsX = Mathf.CeilToInt((float)m_nParticlesWidth / (float)groupSizeX); | 
					
						
							|  |  |  |  |             m_nParticlesNumGroupsY = Mathf.CeilToInt((float)m_nParticlesHeight / (float)groupSizeX); | 
					
						
							|  |  |  |  |             m_currentParticles = new float[m_nParticlesWidth * m_nParticlesHeight]; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         private void LinkToFluidSimulation() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             float fResolutionRatio = Resolution / (float)m_nParticlesResolution; | 
					
						
							|  |  |  |  |             SetSize((int)(m_nParticlesWidth * fResolutionRatio), (int)(m_nParticlesHeight * fResolutionRatio)); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |             InitShaders(); | 
					
						
							|  |  |  |  |             m_particleAreaShader.SetInts(_VelocitySize, new int[] { GetWidth(), GetHeight() }); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         private void FlipBuffers() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             int aux = READ; | 
					
						
							|  |  |  |  |             READ = WRITE; | 
					
						
							|  |  |  |  |             WRITE = aux; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public Vector2 GetRenderScale() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return transform.lossyScale; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public Vector2 GetRenderSize() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return m_tempRend.bounds.size; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public int GetParticlesWidth() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return m_nParticlesWidth; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public int GetParticlesHeight() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             return m_nParticlesHeight; | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         private void UpdateGradient() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             Vector4[] colourData = new Vector4[m_nColourRampSize]; | 
					
						
							|  |  |  |  |             for (int i = 0; i < m_nColourRampSize; ++i) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 colourData[i] = m_colourGradient.Evaluate(i / 255.0f); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |             m_colourRamp.SetData(colourData); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         void SetSizeInShaders() | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             m_particleAreaShader.SetInts(_ParticleSize, new int[] { m_nParticlesWidth, m_nParticlesHeight }); | 
					
						
							|  |  |  |  |             m_tempRend.material.SetVector(_Size, new Vector2(m_nParticlesWidth, m_nParticlesHeight)); | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |         public void AddParticles(Vector2 position, float fRadius, float fStrength) | 
					
						
							|  |  |  |  |         { | 
					
						
							|  |  |  |  |             if (m_particleAreaShader != null && m_particlesBuffer != null && m_particlesBuffer.Length >= 2) | 
					
						
							|  |  |  |  |             { | 
					
						
							|  |  |  |  |                 float[] pos = { position.x, position.y }; | 
					
						
							|  |  |  |  |                 m_particleAreaShader.SetFloats(_Position, pos); | 
					
						
							|  |  |  |  |                 m_particleAreaShader.SetFloat(_Value, fStrength); | 
					
						
							|  |  |  |  |                 m_particleAreaShader.SetFloat(_Radius, fRadius); | 
					
						
							|  |  |  |  |                 m_particleAreaShader.SetInts(_Size, new int[] { m_nParticlesWidth, m_nParticlesHeight }); | 
					
						
							|  |  |  |  |                 m_particleAreaShader.SetBuffer(m_addParticlesKernel, _ParticlesIn, m_particlesBuffer[READ]); | 
					
						
							|  |  |  |  |                 m_particleAreaShader.SetBuffer(m_addParticlesKernel, _ParticlesOut, m_particlesBuffer[WRITE]); | 
					
						
							|  |  |  |  |                 m_particleAreaShader.Dispatch(m_addParticlesKernel, m_nParticlesNumGroupsX, m_nParticlesNumGroupsY, 1); | 
					
						
							|  |  |  |  |                 FlipBuffers(); | 
					
						
							|  |  |  |  |                 m_tempRend.material.SetBuffer("_Particles", m_particlesBuffer[READ]); | 
					
						
							|  |  |  |  |             } | 
					
						
							|  |  |  |  |         } | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | } |