示例#1
0
    private void ComputeGridHash()
    {
        // Clear cells
        int kernel    = 0;
        int numBlocks = (int)ComputeGroupSize(simulationParameters[0].numCells, BLOCK_SIZE);

        computeGridShader.SetBuffer(kernel, "cells_rw", bufCells);
        computeGridShader.Dispatch(kernel, numBlocks, 1, 1);

        // Compute (hash, index)
        kernel    = 1;
        numBlocks = (int)ComputeGroupSize((uint)simulationParameters[0].maxParticles, BLOCK_SIZE);
        computeGridShader.SetBuffer(kernel, "parameters", bufSimulationParameters);
        computeGridShader.SetBuffer(kernel, "pos_press", bufPosPress[0]);
        computeGridShader.SetBuffer(kernel, "vel_rho", bufVelRho[0]);
        computeGridShader.SetBuffer(kernel, "force_vol", bufForceVol[0]);
        computeGridShader.SetBuffer(kernel, "tgrm", bufTGRM[0]);
        computeGridShader.SetBuffer(kernel, "sort_data_rw", bufSortData[0]);
        computeGridShader.Dispatch(kernel, numBlocks, 1, 1);

        // Sort (hash-index) using bitonic sort
        int roundUpPowerOf2 = (int)Mathf.Pow(2, Mathf.Ceil(Mathf.Log(simulationParameters[0].maxParticles) / Mathf.Log(2.0f)));

        bitonicSort.BitonicSort(bufSortData[0], bufSortData[1], (uint)roundUpPowerOf2);

        // Reorder particle data and compute cell data
        kernel    = 2;
        numBlocks = (int)ComputeGroupSize((uint)simulationParameters[0].numParticles, BLOCK_SIZE);
        computeGridShader.SetBuffer(kernel, "parameters", bufSimulationParameters);
        computeGridShader.SetBuffer(kernel, "pos_press", bufPosPress[0]);
        computeGridShader.SetBuffer(kernel, "vel_rho", bufVelRho[0]);
        computeGridShader.SetBuffer(kernel, "force_vol", bufForceVol[0]);
        computeGridShader.SetBuffer(kernel, "tgrm", bufTGRM[0]);
        computeGridShader.SetBuffer(kernel, "pos_press_rw", bufPosPress[1]);
        computeGridShader.SetBuffer(kernel, "vel_rho_rw", bufVelRho[1]);
        computeGridShader.SetBuffer(kernel, "force_vol_rw", bufForceVol[1]);
        computeGridShader.SetBuffer(kernel, "tgrm_rw", bufTGRM[1]);
        computeGridShader.SetBuffer(kernel, "sort_data", bufSortData[0]);
        computeGridShader.SetBuffer(kernel, "cells_rw", bufCells);
        computeGridShader.Dispatch(kernel, numBlocks, 1, 1);
    }
示例#2
0
    void Update()
    {
        if (s_update_count++ == 0)
        {
            GPUParticleEmitter.UpdateAll();
            GPUParticleForce.UpdateAll();
            GPUParticleColliderBase.UpdateAll();
        }

        m_world_data[0].timestep              = Time.deltaTime * 0.6f;
        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_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].pressure_stiffness = m_pressure_stiffness;
        m_world_data[0].wall_stiffness     = m_wall_stiffness;

        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_forces.SetData(m_forces.ToArray());                       m_forces.Clear();

        IVector3 world_div = m_world_data[0].world_div;
        int      num_cells = world_div.x * world_div.y * world_div.z;

        m_world_data[0].num_additional_particles = m_particles_to_add.Count;
        m_buf_world_data.SetData(m_world_data);
        CSWorldData 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);
                GPUParticleUtils.Swap(ref m_buf_particles[0], ref m_buf_particles[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 == GPUParticleWorld.Interaction.Impulse)
        {
            ComputeShader cs     = m_cs_core;
            int           kernel = m_dimension == GPUParticleWorld.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 == GPUParticleWorld.Interaction.SPH)
        {
            ComputeShader cs     = m_cs_core;
            int           kernel = m_dimension == GPUParticleWorld.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 == GPUParticleWorld.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 == GPUParticleWorld.Interaction.None)
        {
            // do nothing
        }

        //// gbuffer collision
        //if (m_process_gbuffer_collision)
        //{
        //    ComputeShader cs = m_cs_core;
        //    int kernel = kProcessGBufferCollision;
        //    cs.SetTexture(kernel, "gbuffer_normal", rtNormalBufferCopy);
        //    cs.SetTexture(kernel, "gbuffer_position", rtPositionBufferCopy);
        //    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);
        //}

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