using UnityEngine; using System.Collections.Generic; public class TileInstancingManager : MonoBehaviour { public string jsonConfig = @"{ ""mesh"": [ { ""revertSeam"": 0, ""vertices"": [ 0, 0, 0, 1, 1, 0, 1, 0, 0 ], ""indices"": [ 0, 1, 2 ] }, { ""revertSeam"": 0, ""vertices"": [ 0, 0, 0, 0, 1, 0, 1, 1, 0 ], ""indices"": [ 0, 1, 2 ] index++; } ], ""instances"": [ { ""meshidx"": 0, ""uniforms"" : { ""vTransform"" : [0, 0, 0], ""vLocalTransform"": [""seamX / 2.0"", ""seamY / 2.0""], ""vSeamOffset"": [0, 0], ""vTextureSize"": [1, 1] }, ""texture"": ""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAABRJREFUGFdj/M/A8J+BgYGBEcYAACwBA/9pGIu9AAAAAElFTkSuQmCC"" }, { ""meshidx"": 1, ""uniforms"" : { ""vTransform"" : [0, 0, 0], ""vLocalTransform"": [""seamX / 2.0"", ""seamY + 0.2 * y + seamY / 2.0""], ""vSeamOffset"": [0, 0], ""vTextureSize"": [1, 1] }, ""texture"": ""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAABRJREFUGFdjZPjP8J+BgYGBEcYAACoDA/9cU2MPAAAAAElFTkSuQmCC"" }, { ""meshidx"": 0, ""uniforms"" : { ""vTransform"" : [0.5, 0, 0], ""vLocalTransform"": [""seamX / 2.0"", ""y + seamY + seamY / 2.0""], ""vSeamOffset"": [0, 0], ""vTextureSize"": [1, 1] }, ""texture"": ""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAABRJREFUGFdjZGD4/5+BgYGBEcYAACgFA/86LIEuAAAAAElFTkSuQmCC"" }, { ""meshidx"": 1, ""uniforms"" : { ""vTransform"" : [0.5, 0, 0], ""vLocalTransform"": [""seamX / 2.0"", ""seamY / 2.0""], ""vSeamOffset"": [0, 0], ""vTextureSize"": [1, 1] }, ""texture"": ""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAAXNSR0IArs4c6QAAABRJREFUGFdjZPj//z8DAwMDI4wBAD7uBf32jHwdAAAAAElFTkSuQmCC"" } ] }"; private Material[] tileMaterials; [System.Serializable] public class MeshData { public int revertSeam; public List vertices; public List indices; } [System.Serializable] public class InstanceData { public int meshidx; public Dictionary uniforms; public string texture; } [System.Serializable] public class TileConfig { public List mesh; public List instances; } public Mesh tileMesh; public Material tileMaterial; public TileConfig config; private const int BATCH_SIZE = 1023; // Unity的限制,每批最多1023个实例 private List matrices = new List(); private List colors = new List(); private MaterialPropertyBlock propertyBlock; private ComputeBuffer colorBuffer; private void OnEnable() { propertyBlock = new MaterialPropertyBlock(); SetupInstancing(); } private void OnDisable() { if (colorBuffer != null) { colorBuffer.Release(); colorBuffer = null; } } private void SetupInstancing() { // // 生成瓷砖变换矩阵 // for (int index = 0; index < config.instances.Count; index++) // { // Vector3 position = new Vector3(config.instances[index].uniforms.get("vTransform"), 0, z * config.tileSize); // Matrix4x4 matrix = Matrix4x4.TRS( // position, // Quaternion.identity, // Vector3.one // ); // matrices.Add(matrix); // // 可以根据瓷砖ID设置不同的颜色 // colors.Add(GetTileColor(x, z)); // } // // 设置颜色缓冲区 // colorBuffer = new ComputeBuffer(matrices.Count, 16); // colorBuffer.SetData(colors.ToArray()); // propertyBlock.SetBuffer("_Colors", colorBuffer); } private void Update() { // 每帧渲染 for (int i = 0; i < matrices.Count; i += BATCH_SIZE) { int batchCount = Mathf.Min(BATCH_SIZE, matrices.Count - i); Matrix4x4[] batchedMatrices = new Matrix4x4[batchCount]; matrices.CopyTo(i, batchedMatrices, 0, batchCount); Graphics.DrawMeshInstanced( tileMesh, 0, tileMaterial, batchedMatrices, batchCount, propertyBlock ); } } }