Skip to content

Instantly share code, notes, and snippets.

@supertask
Created January 10, 2025 10:39
Show Gist options
  • Save supertask/809f01b7bdddbdf1db9131d735823fe1 to your computer and use it in GitHub Desktop.
Save supertask/809f01b7bdddbdf1db9131d735823fe1 to your computer and use it in GitHub Desktop.
GpuInstancingStressTest
using System.Collections.Generic;
using UnityEngine;
public class GpuInstancingStressTest : MonoBehaviour
{
[SerializeField]
private Mesh _mesh;
[SerializeField]
private Material _material;
// インスタンシング対象の最大個数
[SerializeField]
private int _maxInstances = 500000;
// 1フレームで追加されるインスタンス数
[SerializeField]
private int _incrementPerFrame = 10000;
// メッシュの配置範囲
[SerializeField]
private float _range = 100f;
private List<Matrix4x4> _matrices = new List<Matrix4x4>();
private int _currentInstanceCount = 0;
// 動的な GPU バッファ(DrawMeshInstancedIndirect 用じゃなくとも可)
// ここでは使い回さずに都度作る → 無駄な再アロケーションを多発させるため
private ComputeBuffer _matrixBuffer;
private void Start()
{
// 初回にとりあえずバッファ生成
_matrixBuffer = new ComputeBuffer(_maxInstances, sizeof(float) * 16);
}
private void Update()
{
// 1フレームごとにインスタンスを増やす(負荷を加速的に上げる)
_currentInstanceCount = Mathf.Min(_currentInstanceCount + _incrementPerFrame, _maxInstances);
// 既存リストをクリアして再度行列を詰め直す
_matrices.Clear();
for (int i = 0; i < _currentInstanceCount; i++)
{
Vector3 pos = new Vector3(
Random.Range(-_range, _range),
Random.Range(-_range, _range),
Random.Range(-_range, _range)
);
Quaternion rot = Random.rotationUniform;
Vector3 scale = Vector3.one * Random.Range(0.5f, 1.5f);
// ローカル to ワールド行列を生成
Matrix4x4 matrix = Matrix4x4.TRS(pos, rot, scale);
_matrices.Add(matrix);
}
// バッファを破棄して再確保する(悪手)
// ※ 本来なら1回確保したバッファを使い回したり、リングバッファを使うのが一般的
if (_matrixBuffer != null)
{
_matrixBuffer.Release();
_matrixBuffer = null;
}
// 動的再確保 → 頻繁なリソース作成・破棄 → ドライバに負荷
_matrixBuffer = new ComputeBuffer(_currentInstanceCount, sizeof(float) * 16);
_matrixBuffer.SetData(_matrices);
// DrawMeshInstancedProcedural や DrawMeshInstancedIndirect などで描画しても負荷をかけられる
// ここでは簡易的に DrawMeshInstanced でも可
// ただし DrawMeshInstanced はバッファを受け取らないので、行列リストを引数に渡す
Graphics.DrawMeshInstanced(
_mesh,
0,
_material,
_matrices
);
}
private void OnDestroy()
{
if (_matrixBuffer != null)
{
_matrixBuffer.Release();
_matrixBuffer = null;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment