// Update is called once per frame
 void Update()
 {
     if (Input.GetKeyUp(KeyCode.Space))
     {
         Vector3[] particles = new Vector3[amount];
         for (int i = 0; i < particles.Length; i++)
         {
             particles[i] = 5 * new Vector3(Random.value, Random.value, Random.value);
         }
         Color[] colors = new Color[amount];
         for (int i = 0; i < colors.Length; i++)
         {
             colors[i] = Random.ColorHSV();
         }
         Vector3[] scales   = new Vector3[amount];
         Vector3   baseSize = 0.01f * Vector3.one;
         for (int i = 0; i < particles.Length; i++)
         {
             scales[i] = 0.05f * (new Vector3(Random.value, Random.value, Random.value)) + baseSize;
         }
         manager.AddPoints(particles, scales: scales, colors: colors);
     }
     if (Input.GetKeyUp(KeyCode.Delete))
     {
         manager.Clear();
     }
 }
    void GenerateGpuParticles(int num_particles)
    {
        Debug.Log("Generating GPU Particles: " + num_particles);

        Vector3[] positions = new Vector3[num_particles];
        //Vector3[] scales = new Vector3[num_particles];
        Color[] colors = new Color[num_particles];

        Vector3 center_offset  = new Vector3(cumulative_row_densities.Length * 0.5f, 0, marginal_cumulative_col.GetLength(1) * 0.5f);
        float   tileRadiusBase = center_offset.magnitude;
        float   tileRadiusSqr1 = (center_offset * 0.25f).sqrMagnitude;
        float   tileRadiusSqr2 = (center_offset * 2).sqrMagnitude;

        cellSize = 3.0f / tileRadiusBase;

        float fudgeFactor1 = tileRadiusBase / 15;
        float fudgeFactor2 = tileRadiusBase / 75;

        for (int i = 0; i < num_particles; i++)
        {
            float rand1 = Random.value, rand2 = Random.value;
            int   row;
            for (row = 1; row < cumulative_row_densities.Length; row++)
            {
                if (cumulative_row_densities[row] > rand1)
                {
                    break;
                }
            }
            row -= 1;

            int col, width = marginal_cumulative_col.GetLength(1);
            for (col = 1; col < width; col++)
            {
                if (marginal_cumulative_col[row, col] > rand2)
                {
                    break;
                }
            }
            col -= 1;

            Vector3 unit_position = new Vector3(row + Random.value, 0, col + Random.value);
            float   y_range_1     = Mathf.Exp(-(unit_position - center_offset).sqrMagnitude / tileRadiusSqr1) * fudgeFactor1;
            float   y_range_2     = Mathf.Exp(-(unit_position - center_offset).sqrMagnitude / tileRadiusSqr2) * fudgeFactor2;
            positions[i] = cellSize * (new Vector3(unit_position.x, sampleGaussian(0, Mathf.Max(y_range_1, y_range_2)), unit_position.z) - center_offset);

            float hue_mean   = h_mean[row, col];
            float hue_std    = h_std[row, col];
            float hue_sample = sampleGaussian(hue_mean, hue_std);

            float sat_mean   = s_mean[row, col];
            float sat_std    = s_std[row, col];
            float sat_sample = sampleGaussian(sat_mean, sat_std);

            float value_mean   = v_mean[row, col];
            float value_std    = v_std[row, col];
            float value_sample = sampleGaussian(value_mean, value_std);

            colors[i] = Color.HSVToRGB(hue_sample, sat_sample, value_sample);
            //colors[i] = Color.white;
            //scales[i] = 0.01f * Vector3.one;
        }

        gpu_particles_manager.AddPoints(positions, colors: colors);
    }