Created
January 10, 2025 10:39
-
-
Save supertask/809f01b7bdddbdf1db9131d735823fe1 to your computer and use it in GitHub Desktop.
GpuInstancingStressTest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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