前回 15 x 15 x 15 の計3375個の三角柱を生成したとき、その時のインスタンス作成処理に 0.3秒ほど要していました。
ここから先、画面を埋め尽くすほどのブロックの数を表示しようというのに、もう既に諦めなければならないほど低速です。
この処理を高速化するため、インスタンスの数を減らして、メッシュを統合する方法をとってみます。
これも昔行った手法です。
simplestar-tech.hatenablog.com
メッシュ作成の結果、見た目は同じでも
インスタンス生成時の負荷は 11.84 ms (頂点バッファ確保と計算が主な仕事)
メッシュ作成時の負荷は 4.72 ms (一気に 5000 頂点分の設定のため多少時間を要する)
でした。
もともとの三角柱ごとにインスタンスを作る方法は、インスタンス生成時に 267.92 ms 要していました。
もともとの三角柱ごとにインスタンスを作る方法は、メッシュ作成時に 58.73 ms 要していました。
もともとの三角柱ごとにインスタンスを作る方法は、このチャンク(16 x 16 x 16 の三角柱の塊り)一つ作る場合でもフレームレートが維持できませんでしたが
メッシュを結合してインスタンスを統合することで、メッシュ作成処理の負荷が抑えられ、フレームレートをなんとか維持できる処理に変わりました。
以降の記事では、この 16 x 16 x 16 のチャンクをしばらく利用します。
具体的なコードは以下、よろしければ参考にしてください。(主に自分用)
using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(MeshRenderer))] [RequireComponent(typeof(MeshFilter))] public class Prism : MonoBehaviour { [SerializeField] private Material _mat; const float root3 = 1.732051f; private Mesh _mesh; private MeshFilter _filter; const int SIDE = 16; private Vector3[] _vertices; private Vector3[] _normals; private Vector2[] _uvs; private int[] _triangles; // Use this for initialization void Start() { _vertices = new Vector3[SIDE * SIDE * (SIDE / 2) * vertIndices.Length]; _normals = new Vector3[_vertices.Length]; _uvs = new Vector2[_vertices.Length]; _triangles = new int[_vertices.Length]; for (int x = 0; x < SIDE; x++) { for (int y = 0; y < SIDE; y++) { for (int z = 0; z < SIDE; z += 2) { for (int i = 0; i < vertIndices.Length; i++) { int vertIndex = (x * SIDE * (SIDE / 2) + y * (SIDE / 2) + z / 2) * vertIndices.Length + i; ref Vector3 vert = ref _vertices[vertIndex]; ref Vector3 normal = ref _normals[vertIndex]; ref Vector2 uv = ref _uvs[vertIndex]; vert = positions[vertIndices[i]]; vert.x += x * 2; vert.y += y; vert.z += z * root3; normal = normals[i]; uv = uvs[i]; _triangles[vertIndex] = vertIndex; } } } } _mesh = new Mesh(); _filter = GetComponent<MeshFilter>(); var renderer = GetComponent<MeshRenderer>(); renderer.material = _mat; } // Update is called once per frame void Update() { if (Input.GetKeyDown(KeyCode.Space)) { CreateMesh(); } } private void CreateMesh() { _mesh.vertices = _vertices; _mesh.triangles = _triangles; _mesh.uv = _uvs; _mesh.normals = _normals; _filter.sharedMesh = _mesh; } static Vector3[] positions = new Vector3[] { // top new Vector3 (0f, 1f, 0f), new Vector3 (1f, 1f, -root3), new Vector3 (-1f, 1f, -root3), // bottom new Vector3 (0f, 0f, 0f), new Vector3 (-1f, 0f, -root3), new Vector3 (1f, 0f, -root3), }; static int[] vertIndices = new int[] { 0, 1, 2, 3, 4, 5, 0, 2, 4, 4, 3, 0, 2, 1, 5, 5, 4, 2, 1, 0, 3, 3, 5, 1 }; static Vector3[] vertices = new Vector3[vertIndices.Length]; static Vector2[] uvs = new Vector2[] { // top new Vector2 (.25f, 0.5f), new Vector2 (0.5f, 0.0f), new Vector2 (0.0f, 0.0f), // bottom new Vector2 (.75f, 0.0f), new Vector2 (0.5f, 0.5f), new Vector2 (1.0f, 0.5f), // side R new Vector2 (0.0f, 1.0f), new Vector2 (.33f, 1.0f), new Vector2 (.33f, 0.5f), new Vector2 (.33f, 0.5f), new Vector2 (0.0f, 0.5f), new Vector2 (0.0f, 1.0f), // side G new Vector2 (.33f, 1.0f), new Vector2 (.66f, 1.0f), new Vector2 (.66f, 0.5f), new Vector2 (.66f, 0.5f), new Vector2 (.33f, 0.5f), new Vector2 (.33f, 1.0f), // side B new Vector2 (.66f, 1.0f), new Vector2 (1.0f, 1.0f), new Vector2 (1.0f, 0.5f), new Vector2 (1.0f, 0.5f), new Vector2 (.66f, 0.5f), new Vector2 (.66f, 1.0f) }; static Vector3[] normals = new Vector3[] { // top new Vector3 (0f, 1f, 0f), new Vector3 (0f, 1f, 0f), new Vector3 (0f, 1f, 0f), // bottom new Vector3 (0f,-1f, 0f), new Vector3 (0f,-1f, 0f), new Vector3 (0f,-1f, 0f), // side R new Vector3 (-0.8660254f, 0f, 0.5f), new Vector3 (-0.8660254f, 0f, 0.5f), new Vector3 (-0.8660254f, 0f, 0.5f), new Vector3 (-0.8660254f, 0f, 0.5f), new Vector3 (-0.8660254f, 0f, 0.5f), new Vector3 (-0.8660254f, 0f, 0.5f), // side G new Vector3 (0f, 0f,-1f), new Vector3 (0f, 0f,-1f), new Vector3 (0f, 0f,-1f), new Vector3 (0f, 0f,-1f), new Vector3 (0f, 0f,-1f), new Vector3 (0f, 0f,-1f), // side B new Vector3 (0.8660254f, 0f, 0.5f), new Vector3 (0.8660254f, 0f, 0.5f), new Vector3 (0.8660254f, 0f, 0.5f), new Vector3 (0.8660254f, 0f, 0.5f), new Vector3 (0.8660254f, 0f, 0.5f), new Vector3 (0.8660254f, 0f, 0.5f), }; }