NodeWorld

Dessin par instances

Depuis SDK 0.2.1

Un InstancedMesh dessine des copies d'un même mesh avec un même matériau, à chaque frame, sans un seul GameObject : herbe, foules, débris, étoiles. Tu donnes une matrice par copie (où elle est, comment elle tourne, sa taille), et si tu veux une couleur, un flottant ou un vecteur par copie. Le jeu les dessine avec Graphics.RenderMeshInstanced, par paquets de 1023, en lisant les matrices directement dans la mémoire du monde.

Les copies n'ont pas de collision : pour toucher quelque chose, utilise des objets normaux. Le dessin par instances n'existe que sur les appareils des joueurs.

Dessiner

csharp
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, matériau, capacité, sous-mesh) : matrices contient capacité matrices, toutes à l'origine tant que tu ne les places pas.
  • count ne dessine que les premières copies (au plus capacité) ; visible les cache toutes.
  • Change matrices et les tableaux par copie quand tu veux, depuis n'importe quel thread : chaque frame dessine ce qu'ils contiennent.
  • shadowCastingMode, receiveShadows, layer, mesh (ou SetMesh(mesh, sousMesh)) et material peuvent changer à tout moment.
  • Dispose() (ou Object.Destroy) arrête le dessin. Il s'arrête avec son monde.

Le matériau

Le jeu active GPU instancing sur le matériau. Une propriété par copie (AddColorProperty("_BaseColor"), AddFloatProperty, AddVectorProperty) n'est lue que par un shader qui la déclare comme propriété instanciée (UNITY_INSTANCING_BUFFER) ; avec un autre shader, toutes les copies prennent la valeur du matériau.