The “instanced geoemetry” is just GameObjects. On my system (5950X, 64GB RAM, 3070) I get 45 FPS (~24ms).
Original
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class BoxInstancer : MonoBehaviour
{
private GameObject[] boxes;
void Start () {
int count = 32;
Array.Resize(ref boxes,count*count*count);
int n=0;
var box = new GameObject();
box.AddComponent<MeshFilter>();
box.AddComponent<MeshRenderer>();
Vector3[] vertices = {
new Vector3 (-0.5f, -0.5f, -0.5f),
new Vector3 (0.5f, -0.5f, -0.5f),
new Vector3 (0.5f, 0.5f, -0.5f),
new Vector3 (-0.5f, 0.5f, -0.5f),
new Vector3 (-0.5f, 0.5f, 0.5f),
new Vector3 (0.5f, 0.5f, 0.5f),
new Vector3 (0.5f, -0.5f, 0.5f),
new Vector3 (-0.5f, -0.5f, 0.5f),
};
int[] triangles = {
0, 2, 1, //face front
0, 3, 2,
2, 3, 4, //face top
2, 4, 5,
1, 2, 5, //face right
1, 5, 6,
0, 7, 4, //face left
0, 4, 3,
5, 4, 7, //face back
5, 7, 6,
0, 6, 7, //face bottom
0, 1, 6
};
Mesh mesh = box.GetComponent<MeshFilter> ().mesh;
mesh.Clear ();
mesh.vertices = vertices;
mesh.triangles = triangles;
mesh.Optimize ();
mesh.RecalculateNormals ();
n++;
for (int x = 1; x <= count; x++)
{
for (int y = 1; y <= count; y++)
{
for (int z = 1; z <= count; z++)
{
boxes[n] = Instantiate(box);
boxes[n].transform.position = new Vector3((x-(count/2+1))*2, (y-(count/2+1))*2, (z-(count/2+1))*2);
n++;
}
}
}
box.SetActive(false);
}
}
GPT-4o’s first attempt at optimization pushed performance to 144 FPS (~6.5ms).
GPT-4o
using System.Collections.Generic;
using UnityEngine;
public class BoxInstancer : MonoBehaviour
{
private Mesh boxMesh;
private Material boxMaterial;
private List<Matrix4x4> matrices = new List<Matrix4x4>();
private const int count = 32;
void Start()
{
CreateBoxMesh();
boxMaterial = new Material(Shader.Find("Standard"));
boxMaterial.enableInstancing = true;
for (int x = 0; x < count; x++)
{
for (int y = 0; y < count; y++)
{
for (int z = 0; z < count; z++)
{
Vector3 position = new Vector3(
(x - (count / 2f)) * 2,
(y - (count / 2f)) * 2,
(z - (count / 2f)) * 2
);
matrices.Add(Matrix4x4.TRS(position, Quaternion.identity, Vector3.one));
}
}
}
}
void CreateBoxMesh()
{
boxMesh = new Mesh();
Vector3[] vertices = {
new Vector3(-0.5f, -0.5f, -0.5f),
new Vector3(0.5f, -0.5f, -0.5f),
new Vector3(0.5f, 0.5f, -0.5f),
new Vector3(-0.5f, 0.5f, -0.5f),
new Vector3(-0.5f, 0.5f, 0.5f),
new Vector3(0.5f, 0.5f, 0.5f),
new Vector3(0.5f, -0.5f, 0.5f),
new Vector3(-0.5f, -0.5f, 0.5f),
};
int[] triangles = {
0, 2, 1, // face front
0, 3, 2,
2, 3, 4, // face top
2, 4, 5,
1, 2, 5, // face right
1, 5, 6,
0, 7, 4, // face left
0, 4, 3,
5, 4, 7, // face back
5, 7, 6,
0, 6, 7, // face bottom
0, 1, 6
};
boxMesh.vertices = vertices;
boxMesh.triangles = triangles;
boxMesh.RecalculateNormals();
}
void Update()
{
const int instanceCountPerBatch = 1023;
int totalInstances = matrices.Count;
for (int i = 0; i < totalInstances; i += instanceCountPerBatch)
{
int batchSize = Mathf.Min(instanceCountPerBatch, totalInstances - i);
Matrix4x4[] batchMatrices = matrices.GetRange(i, batchSize).ToArray();
Graphics.DrawMeshInstanced(boxMesh, 0, boxMaterial, batchMatrices);
}
}
}
Between that and using a release of Unity that is no longer supported by the Oculus SDK I can only imagine it’s deliberately deceptive though I suppose it’s possible they’re just straight up incompetent.