Drawing by instances
An InstancedMesh draws copies of one mesh with one material, every frame, without a single GameObject: grass, crowds, debris, stars. You give a matrix per copy (where it is, how it turns, its size), and optionally a color, a float or a vector per copy. The game draws them with Graphics.RenderMeshInstanced, in packets of 1023, reading the matrices straight from the memory of the world.
The copies have no collision: to touch something, use ordinary objects. Instanced drawing exists on the players' devices only.
Draw
public class Meadow : FluxScript
{
public Mesh blade;
public Material material;
private InstancedMesh _grass;
protected override void Start()
{
_grass = InstancedMesh.Create(blade, material, 10000);
var colors = _grass.AddColorProperty("_BaseColor");
for (var i = 0; i < 10000; i++)
{
_grass.matrices[i] = Matrix4x4.TRS(new Vector3(i % 100 * 0.3f, 0, i / 100 * 0.3f), Quaternion.identity, Vector3.one);
colors[i] = Color.Lerp(new Color(0.2f, 0.5f, 0.1f, 1f), new Color(0.5f, 0.8f, 0.2f, 1f), Random.value);
}
_grass.shadowCastingMode = ShadowCastingMode.Off;
}
protected override void OnDestroy() => _grass.Dispose();
}InstancedMesh.Create(mesh, material, capacity, submesh):matricesholdscapacitymatrices, all at the origin until you place them.countdraws the first copies only (at mostcapacity);visiblehides them all.- Change
matricesand the per-copy arrays whenever you like, from any thread: each frame draws what they hold. shadowCastingMode,receiveShadows,layer,mesh(orSetMesh(mesh, submesh)) andmaterialcan change at any time.Dispose()(orObject.Destroy) stops the drawing. It stops with its world.
The material
The game turns GPU instancing on for the material. A per-copy property (AddColorProperty("_BaseColor"), AddFloatProperty, AddVectorProperty) is read only by a shader that declares it as an instanced property (UNITY_INSTANCING_BUFFER); with another shader, every copy has the material's own value.
