Inheritance: UnityEngine.MonoBehaviour
Example #1
0
     public override void OnEnable()
     {
         m_world = GetComponent<MPGPWorld>();
         m_max_instances = m_world.GetNumMaxParticles();
 
         base.OnEnable();
         ResetGPUResoures();
     }
        public override void OnEnable()
        {
            m_world         = GetComponent <MPGPWorld>();
            m_max_instances = m_world.GetNumMaxParticles();

            base.OnEnable();
            ResetGPUResoures();
        }
        public override void OnEnable()
        {
            m_world         = GetComponent <MPGPWorld>();
            m_max_instances = m_world.GetNumMaxParticles();
            m_tmp_params    = new MPGPTrailParams[1];

            m_max_entities = m_world.GetNumMaxParticles() * 2;

            base.OnEnable();
            ResetGPUResoures();
        }
Example #4
0
        public override void OnEnable()
        {
            m_world         = GetComponent <MPGPWorld>();
            m_max_instances = m_world.GetNumMaxParticles();
            m_cameras       = m_camera == null ? Camera.allCameras : new Camera[] { m_camera };

            if (m_cameras.Length > 0)
            {
                m_hdr = m_cameras[0].hdr;
            }

            base.OnEnable();
            ResetGPUResoures();
        }
 protected void EachTargets(System.Action <MPGPWorld> a)
 {
     if (m_targets.Length == 0)
     {
         MPGPWorld.GetInstances().ForEach(a);
     }
     else
     {
         foreach (var t in m_targets)
         {
             a(t);
         }
     }
 }
Example #6
0
        void Update()
        {
            s_current = this;

            if (s_update_count++ == 0)
            {
                MPGPEmitter.UpdateAll();
                MPGPForce.UpdateAll();
                MPGPColliderBase.UpdateAll();
            }

            if (m_writeback_to_cpu)
            {
                m_buf_particles[0].GetData(m_particles);
                m_buf_world_idata.GetData(m_world_idata);

                m_actions.ForEach((a) => { a.Invoke(); });
                m_onetime_actions.ForEach((a) => { a.Invoke(); });
                m_onetime_actions.Clear();

                m_buf_particles[0].SetData(m_particles);
                m_buf_world_idata.SetData(m_world_idata);
            }


            m_world_data[0].num_max_particles = m_max_particles;
            m_world_data[0].SetWorldSize(transform.position, transform.localScale,
                                         (uint)m_world_div_x, (uint)m_world_div_y, (uint)m_world_div_z);
            m_world_data[0].timestep              = Time.deltaTime * m_timescale;
            m_world_data[0].particle_size         = m_particle_radius;
            m_world_data[0].particle_lifetime     = m_lifetime;
            m_world_data[0].num_sphere_colliders  = m_sphere_colliders.Count;
            m_world_data[0].num_capsule_colliders = m_capsule_colliders.Count;
            m_world_data[0].num_box_colliders     = m_box_colliders.Count;
            m_world_data[0].num_bp_colliders      = m_bp_colliders.Count;
            m_world_data[0].num_forces            = m_forces.Count;
            m_world_data[0].damping            = m_damping;
            m_world_data[0].advection          = m_advection;
            m_world_data[0].coord_scaler       = m_coord_scaler;
            m_world_data[0].wall_stiffness     = m_wall_stiffness;
            m_world_data[0].gbuffer_stiffness  = m_gbuffer_stiffness;
            m_world_data[0].gbuffer_thickness  = m_gbuffer_thickness;
            m_world_data[0].pressure_stiffness = m_pressure_stiffness;
            if (m_gbuffer_data != null)
            {
                var cam = m_gbuffer_data.GetCamera();
                m_world_data[0].view_proj     = m_gbuffer_data.GetMatrix_VP();
                m_world_data[0].inv_view_proj = m_gbuffer_data.GetMatrix_InvVP();
                m_world_data[0].rt_size       = new Vector2(cam.pixelWidth, cam.pixelHeight);
            }


            m_sph_params[0].smooth_len         = m_sph_smoothlen;
            m_sph_params[0].particle_mass      = m_sph_particleMass;
            m_sph_params[0].pressure_stiffness = m_sph_pressureStiffness;
            m_sph_params[0].rest_density       = m_sph_restDensity;
            m_sph_params[0].viscosity          = m_sph_viscosity;

            m_buf_sphere_colliders.SetData(m_sphere_colliders.ToArray());   m_sphere_colliders.Clear();
            m_buf_capsule_colliders.SetData(m_capsule_colliders.ToArray()); m_capsule_colliders.Clear();
            m_buf_box_colliders.SetData(m_box_colliders.ToArray());         m_box_colliders.Clear();
            m_buf_bp_colliders.SetData(m_bp_colliders.ToArray());           m_bp_colliders.Clear();
            m_buf_forces.SetData(m_forces.ToArray());                       m_forces.Clear();

            int num_cells = m_world_data[0].world_div_x * m_world_data[0].world_div_y * m_world_data[0].world_div_z;

            m_world_data[0].num_additional_particles = m_particles_to_add.Count;
            m_buf_world_data.SetData(m_world_data);
            MPGPWorldData csWorldData = m_world_data[0];

            m_buf_sph_params.SetData(m_sph_params);


            // add new particles
            if (m_particles_to_add.Count > 0)
            {
                ComputeShader cs     = m_cs_core;
                int           kernel = kAddParticles;
                m_buf_particles_to_add.SetData(m_particles_to_add.ToArray());
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "world_idata", m_buf_world_idata);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "particles_to_add", m_buf_particles_to_add);
                cs.Dispatch(kernel, m_particles_to_add.Count / BLOCK_SIZE + 1, 1, 1);
                m_particles_to_add.Clear();
            }

            {
                // clear cells
                {
                    ComputeShader cs     = m_cs_hashgrid;
                    int           kernel = 0;
                    cs.SetBuffer(kernel, "cells_rw", m_buf_cells);
                    cs.Dispatch(kernel, num_cells / BLOCK_SIZE, 1, 1);
                }
                // generate hashes
                {
                    ComputeShader cs     = m_cs_hashgrid;
                    int           kernel = 1;
                    cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                    cs.SetBuffer(kernel, "world_idata", m_buf_world_idata);
                    cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                    cs.SetBuffer(kernel, "sort_keys_rw", m_buf_sort_data[0]);
                    cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1);
                }
                // sort keys
                {
                    m_bitonic_sort.BitonicSort(m_buf_sort_data[0], m_buf_sort_data[1], (uint)csWorldData.num_max_particles);
                }
                // reorder particles
                {
                    ComputeShader cs     = m_cs_hashgrid;
                    int           kernel = 2;
                    cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                    cs.SetBuffer(kernel, "world_idata", m_buf_world_idata);
                    cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                    cs.SetBuffer(kernel, "particles_rw", m_buf_particles[1]);
                    cs.SetBuffer(kernel, "sort_keys", m_buf_sort_data[0]);
                    cs.SetBuffer(kernel, "cells_rw", m_buf_cells);
                    cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1);
                }
                // copy back
                {
                    ComputeShader cs     = m_cs_hashgrid;
                    int           kernel = 3;
                    cs.SetBuffer(kernel, "particles", m_buf_particles[1]);
                    cs.SetBuffer(kernel, "particles_rw", m_buf_particles[0]);
                    cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1);
                }
            }


            //{
            //	dbgSortData = new GPUSort.KIP[csWorldData.num_max_particles];
            //	cbSortData[0].GetData(dbgSortData);
            //	uint prev = 0;
            //	for (int i = 0; i < dbgSortData.Length; ++i)
            //	{
            //		if (prev > dbgSortData[i].key)
            //		{
            //			Debug.Log("sort bug: "+i);
            //			break;
            //		}
            //		prev = dbgSortData[i].key;
            //	}
            //}
            //dbgCellData = new CellData[num_cells];
            //cbCells.GetData(dbgCellData);
            //for (int i = 0; i < num_cells; ++i )
            //{
            //	if (dbgCellData[i].begin!=0)
            //	{
            //		Debug.Log("dbgCellData:" + dbgCellData[i].begin + "," + dbgCellData[i].end);
            //		break;
            //	}
            //}

            int num_active_blocks = m_max_particles / BLOCK_SIZE;

            // initialize intermediate data
            {
                ComputeShader cs     = m_cs_core;
                int           kernel = kPrepare;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }

            // particle interaction
            if (m_solver == MPGPWorld.Interaction.Impulse)
            {
                ComputeShader cs     = m_cs_core;
                int           kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ?
                                       kProcessInteraction_Impulse : kProcessInteraction_Impulse2D;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }
            else if (m_solver == MPGPWorld.Interaction.SPH)
            {
                ComputeShader cs     = m_cs_core;
                int           kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ?
                                       kProcessInteraction_SPH_Pass1 : kProcessInteraction_SPH_Pass12D;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "sph_params", m_buf_sph_params);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);

                kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ?
                         kProcessInteraction_SPH_Pass2 : kProcessInteraction_SPH_Pass22D;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "sph_params", m_buf_sph_params);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }
            else if (m_solver == MPGPWorld.Interaction.None)
            {
                // do nothing
            }

            // gbuffer collision
            if (m_process_gbuffer_collision && m_gbuffer_data != null)
            {
                var depth  = m_gbuffer_data.GetGBuffer_Depth();
                var normal = m_gbuffer_data.GetGBuffer_Normal();
                if (depth != null && normal != null)
                {
                    ComputeShader cs     = m_cs_core;
                    int           kernel = kProcessGBufferCollision;
                    cs.SetTexture(kernel, "gbuffer_normal", normal);
                    cs.SetTexture(kernel, "gbuffer_depth", depth);
                    cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                    cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                    cs.SetBuffer(kernel, "pimd", m_buf_imd);
                    cs.Dispatch(kernel, num_active_blocks, 1, 1);
                }
                else
                {
                    m_gbuffer_data.m_enable_inv_matrices = true;
                    m_gbuffer_data.m_enable_prev_depth   = true;
                    m_gbuffer_data.m_enable_prev_normal  = true;
                }
            }

            // colliders
            if (m_process_colliders)
            {
                ComputeShader cs     = m_cs_core;
                int           kernel = kProcessColliders;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.SetBuffer(kernel, "sphere_colliders", m_buf_sphere_colliders);
                cs.SetBuffer(kernel, "capsule_colliders", m_buf_capsule_colliders);
                cs.SetBuffer(kernel, "box_colliders", m_buf_box_colliders);
                cs.SetBuffer(kernel, "bp_colliders", m_buf_bp_colliders);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }

            // forces
            if (m_process_forces)
            {
                ComputeShader cs     = m_cs_core;
                int           kernel = kProcessForces;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.SetBuffer(kernel, "forces", m_buf_forces);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }

            // integrate
            {
                ComputeShader cs     = m_cs_core;
                int           kernel = kIntegrate;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }
        }
Example #7
0
     public override void OnEnable()
     {
         m_world = GetComponent<MPGPWorld>();
         m_max_instances = m_world.GetNumMaxParticles();
         m_tmp_params = new MPGPTrailParams[1];
 
         m_max_entities = m_world.GetNumMaxParticles() * 2;
 
         base.OnEnable();
         ResetGPUResoures();
     }
Example #8
0
        void Update()
        {
            s_current = this;

            if (s_update_count++ == 0)
            {
                MPGPEmitter.UpdateAll();
                MPGPForce.UpdateAll();
                MPGPColliderBase.UpdateAll();
            }
    
            if (m_writeback_to_cpu)
            {
                m_buf_particles[0].GetData(m_particles);
                m_buf_world_idata.GetData(m_world_idata);
    
                m_actions.ForEach((a) => { a.Invoke(); });
                m_onetime_actions.ForEach((a) => { a.Invoke(); });
                m_onetime_actions.Clear();
    
                m_buf_particles[0].SetData(m_particles);
                m_buf_world_idata.SetData(m_world_idata);
            }
    
    
            m_world_data[0].num_max_particles = m_max_particles;
            m_world_data[0].SetWorldSize(transform.position, transform.localScale,
                (uint)m_world_div_x, (uint)m_world_div_y, (uint)m_world_div_z);
            m_world_data[0].timestep = Time.deltaTime * m_timescale;
            m_world_data[0].particle_size = m_particle_radius;
            m_world_data[0].particle_lifetime = m_lifetime;
            m_world_data[0].num_sphere_colliders = m_sphere_colliders.Count;
            m_world_data[0].num_capsule_colliders = m_capsule_colliders.Count;
            m_world_data[0].num_box_colliders = m_box_colliders.Count;
            m_world_data[0].num_bp_colliders = m_bp_colliders.Count;
            m_world_data[0].num_forces = m_forces.Count;
            m_world_data[0].damping = m_damping;
            m_world_data[0].advection = m_advection;
            m_world_data[0].coord_scaler = m_coord_scaler;
            m_world_data[0].wall_stiffness = m_wall_stiffness;
            m_world_data[0].gbuffer_stiffness = m_gbuffer_stiffness;
            m_world_data[0].gbuffer_thickness = m_gbuffer_thickness;
            m_world_data[0].pressure_stiffness = m_pressure_stiffness;
            if( m_gbuffer_data != null)
            {
                var cam = m_gbuffer_data.GetCamera();
                m_world_data[0].view_proj = m_gbuffer_data.GetMatrix_VP();
                m_world_data[0].inv_view_proj = m_gbuffer_data.GetMatrix_InvVP();
                m_world_data[0].rt_size = new Vector2(cam.pixelWidth, cam.pixelHeight);
            }
    
    
            m_sph_params[0].smooth_len = m_sph_smoothlen;
            m_sph_params[0].particle_mass = m_sph_particleMass;
            m_sph_params[0].pressure_stiffness = m_sph_pressureStiffness;
            m_sph_params[0].rest_density = m_sph_restDensity;
            m_sph_params[0].viscosity = m_sph_viscosity;
    
            m_buf_sphere_colliders.SetData(m_sphere_colliders.ToArray());   m_sphere_colliders.Clear();
            m_buf_capsule_colliders.SetData(m_capsule_colliders.ToArray()); m_capsule_colliders.Clear();
            m_buf_box_colliders.SetData(m_box_colliders.ToArray());         m_box_colliders.Clear();
            m_buf_bp_colliders.SetData(m_bp_colliders.ToArray());           m_bp_colliders.Clear();
            m_buf_forces.SetData(m_forces.ToArray());                       m_forces.Clear();
    
            int num_cells = m_world_data[0].world_div_x * m_world_data[0].world_div_y * m_world_data[0].world_div_z;
    
            m_world_data[0].num_additional_particles = m_particles_to_add.Count;
            m_buf_world_data.SetData(m_world_data);
            MPGPWorldData csWorldData = m_world_data[0];
            m_buf_sph_params.SetData(m_sph_params);
    
    
            // add new particles
            if (m_particles_to_add.Count > 0)
            {
                ComputeShader cs = m_cs_core;
                int kernel = kAddParticles;
                m_buf_particles_to_add.SetData(m_particles_to_add.ToArray());
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "world_idata", m_buf_world_idata);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "particles_to_add", m_buf_particles_to_add);
                cs.Dispatch(kernel, m_particles_to_add.Count / BLOCK_SIZE + 1, 1, 1);
                m_particles_to_add.Clear();
            }
    
            {
                // clear cells
                {
                    ComputeShader cs = m_cs_hashgrid;
                    int kernel = 0;
                    cs.SetBuffer(kernel, "cells_rw", m_buf_cells);
                    cs.Dispatch(kernel, num_cells / BLOCK_SIZE, 1, 1);
                }
                // generate hashes
                {
                    ComputeShader cs = m_cs_hashgrid;
                    int kernel = 1;
                    cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                    cs.SetBuffer(kernel, "world_idata", m_buf_world_idata);
                    cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                    cs.SetBuffer(kernel, "sort_keys_rw", m_buf_sort_data[0]);
                    cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1);
                }
                // sort keys
                {
                    m_bitonic_sort.BitonicSort(m_buf_sort_data[0], m_buf_sort_data[1], (uint)csWorldData.num_max_particles);
                }
                // reorder particles
                {
                    ComputeShader cs = m_cs_hashgrid;
                    int kernel = 2;
                    cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                    cs.SetBuffer(kernel, "world_idata", m_buf_world_idata);
                    cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                    cs.SetBuffer(kernel, "particles_rw", m_buf_particles[1]);
                    cs.SetBuffer(kernel, "sort_keys", m_buf_sort_data[0]);
                    cs.SetBuffer(kernel, "cells_rw", m_buf_cells);
                    cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1);
                }
                // copy back
                {
                    ComputeShader cs = m_cs_hashgrid;
                    int kernel = 3;
                    cs.SetBuffer(kernel, "particles", m_buf_particles[1]);
                    cs.SetBuffer(kernel, "particles_rw", m_buf_particles[0]);
                    cs.Dispatch(kernel, m_max_particles / BLOCK_SIZE, 1, 1);
                }
            }
    
    
            //{
            //	dbgSortData = new GPUSort.KIP[csWorldData.num_max_particles];
            //	cbSortData[0].GetData(dbgSortData);
            //	uint prev = 0;
            //	for (int i = 0; i < dbgSortData.Length; ++i)
            //	{
            //		if (prev > dbgSortData[i].key)
            //		{
            //			Debug.Log("sort bug: "+i);
            //			break;
            //		}
            //		prev = dbgSortData[i].key;
            //	}
            //}
            //dbgCellData = new CellData[num_cells];
            //cbCells.GetData(dbgCellData);
            //for (int i = 0; i < num_cells; ++i )
            //{
            //	if (dbgCellData[i].begin!=0)
            //	{
            //		Debug.Log("dbgCellData:" + dbgCellData[i].begin + "," + dbgCellData[i].end);
            //		break;
            //	}
            //}
    
            int num_active_blocks = m_max_particles / BLOCK_SIZE;
    
            // initialize intermediate data
            {
                ComputeShader cs = m_cs_core;
                int kernel = kPrepare;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }
    
            // particle interaction
            if (m_solver == MPGPWorld.Interaction.Impulse)
            {
                ComputeShader cs = m_cs_core;
                int kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ?
                    kProcessInteraction_Impulse : kProcessInteraction_Impulse2D;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }
            else if (m_solver == MPGPWorld.Interaction.SPH)
            {
                ComputeShader cs = m_cs_core;
                int kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ?
                    kProcessInteraction_SPH_Pass1 : kProcessInteraction_SPH_Pass12D;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "sph_params", m_buf_sph_params);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
    
                kernel = m_dimension == MPGPWorld.Dimension.Dimendion3D ?
                    kProcessInteraction_SPH_Pass2 : kProcessInteraction_SPH_Pass22D;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "sph_params", m_buf_sph_params);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }
            else if (m_solver == MPGPWorld.Interaction.None)
            {
                // do nothing
            }
    
            // gbuffer collision
            if (m_process_gbuffer_collision && m_gbuffer_data!=null)
            {
                var depth = m_gbuffer_data.GetGBuffer_Depth();
                var normal = m_gbuffer_data.GetGBuffer_Normal();
                if(depth!=null && normal!=null)
                {
                    ComputeShader cs = m_cs_core;
                    int kernel = kProcessGBufferCollision;
                    cs.SetTexture(kernel, "gbuffer_normal", normal);
                    cs.SetTexture(kernel, "gbuffer_depth", depth);
                    cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                    cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                    cs.SetBuffer(kernel, "pimd", m_buf_imd);
                    cs.Dispatch(kernel, num_active_blocks, 1, 1);
                }
                else
                {
                    m_gbuffer_data.m_enable_inv_matrices = true;
                    m_gbuffer_data.m_enable_prev_depth = true;
                    m_gbuffer_data.m_enable_prev_normal = true;
                }
            }
    
            // colliders
            if (m_process_colliders)
            {
                ComputeShader cs = m_cs_core;
                int kernel = kProcessColliders;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.SetBuffer(kernel, "sphere_colliders", m_buf_sphere_colliders);
                cs.SetBuffer(kernel, "capsule_colliders", m_buf_capsule_colliders);
                cs.SetBuffer(kernel, "box_colliders", m_buf_box_colliders);
                cs.SetBuffer(kernel, "bp_colliders", m_buf_bp_colliders);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }
    
            // forces
            if (m_process_forces)
            {
                ComputeShader cs = m_cs_core;
                int kernel = kProcessForces;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.SetBuffer(kernel, "cells", m_buf_cells);
                cs.SetBuffer(kernel, "forces", m_buf_forces);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }
    
            // integrate
            {
                ComputeShader cs = m_cs_core;
                int kernel = kIntegrate;
                cs.SetBuffer(kernel, "world_data", m_buf_world_data);
                cs.SetBuffer(kernel, "particles", m_buf_particles[0]);
                cs.SetBuffer(kernel, "pimd", m_buf_imd);
                cs.Dispatch(kernel, num_active_blocks, 1, 1);
            }
        }
        public override void OnEnable()
        {
            m_world = GetComponent<MPGPWorld>();
            m_max_instances = m_world.GetNumMaxParticles();
            m_cameras = m_camera == null ? Camera.allCameras : new Camera[] { m_camera };

            if(m_cameras.Length > 0)
            {
                m_hdr = m_cameras[0].hdr;
            }

            base.OnEnable();
            ResetGPUResoures();
        }