using UnityEngine;
public class ComputeCubes : MonoBehaviour
{
[SerializeField]
private ComputeShader _computeShader;
private ComputeBuffer _buffer;
/// <summary>
/// 生成個数
/// </summary>
private int _cubeCount = 640;
/// <summary>
/// キューブ参照
/// </summary>
private GameObject[] _cubes;
/// <summary>
/// 各キューブの角度を格納配列
/// </summary>
private float[] _angles;
private int _mainKernel = 0;
void Start()
{
_cubes = new GameObject[_cubeCount];
_angles = new float[_cubeCount];
for (int i = 0; i < _cubeCount; i++)
{
var cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
// 配置範囲
float len = 20f;
cube.transform.localPosition =
new Vector3(Random.Range(-len, len), Random.Range(-len, len), Random.Range(-len, len));
_cubes[i] = cube;
}
_buffer = new ComputeBuffer(_cubeCount, sizeof(float));
_mainKernel = _computeShader.FindKernel("CSMain");
_computeShader.SetBuffer(_mainKernel, "Result", _buffer);
}
void Update()
{
// 現在の角度をシェーダにpush
for (int i = 0; i < _cubeCount; i++)
{
_computeShader.SetFloat("eulerAngleX", _angles[i]);
}
// GPU並列処理実行
_computeShader.Dispatch(_mainKernel, 8, 1, 1);
var data = new float[_cubeCount];
// 更新結果を取得
_buffer.GetData(data);
for (int i = 0; i < _cubeCount; i++)
{
float result = data[i];
_angles[i] = result;
_cubes[i].transform.localEulerAngles = new Vector3(_angles[i], 0, 0);
}
}
private void OnDestroy()
{
_buffer.Release();
}
}