概要
大量のテスクチャを表示したい時がある
例えば、ヴァンパイアサバイバーライクな2Dの敵が大量に出現する場合などが考えられる
上記のスライドでは、そのようなゲームを実装する際のパフォーマンスチューニングについてわかりやすく説明している
参考動画が貼られており、自分でも試せそうだと思ったので試してみた
実験
この子をいっぱい表示することにする
動画では3Dだったが、今回はテクスチャを表示する四角のメッシュさえあればいいのでスクリプトで作ってしまう
void CreateMyMesh()
{
_myMesh = new Mesh
{
// 頂点は4つ
// 2---0
// | |
// 3---1
vertices = new Vector3[]
{
new(1, 1, 0),
new(1, -1, 0),
new(-1, 1, 0),
new(-1, -1, 0)
},
subMeshCount = 1,
uv = new Vector2[]
{
new(1, 1),
new(1, 0),
new(0, 1),
new(0, 0),
}
};
_myMesh.SetTriangles(new[] { 0, 1, 3, 0, 3, 2 }, 0);
}
描画には、GraphicsAPIにはDrawMeshなど低レベル高レベル様々なAPIが用意されている
動画ではGraphics.RenderMeshInstanced
を使っており、パターンによってGraphics.RenderMesh
がいいそう
for(var offs = 0; offs < matrices.Length; offs += 1023)
{
var count = Mathf.Min(1023, matrices.Length - offs);
Graphics.RenderMeshInstanced(rparams, _myMesh, 0, matrices, count, offs);
}
ひとまず動画の最終系通りに実装してみる
大量に表示することができた
歩かせたりもしてみる
撮影時は100FPSほどだが、撮影を止めると300FPSぐらい出ていた
プロファイラで見るとUpdate()に0.07msかかっている
試しにRenderMeshを使ってみる
for(var offs = 0; offs < matrices.Length; offs++)
{
Graphics.RenderMesh(rparams, _myMesh, 0, matrices[offs]);
}
動かしてみると...
Updateに0.17msかかっている
確かにRenderMeshInstancedの方がパフォーマンスに良さそう
もっと表示させてみよう
試しに500*500の250000個表示してみる
RenderMesh
RenderMeshInstanced
顕著な差が出た
カメラ外のテクスチャをカリングするようにすればRenderMeshの方が有利になるかもしれない
今度試してみる