v3.0.0

Turian 3.0.0 changes how a mesh renderer binds materials: by material slot, not by submesh index. A mesh renderer now draws materials[submesh.material_slot], so a model with thousands of submeshes sharing a handful of materials needs only that handful of slots. This is what lets a whole scene flattened into one mesh — hundreds of materials — render completely instead of stopping at the first 32.

What changed

  • MeshRendererComponent — the materials array is now indexed by material slot (Submesh.material_slot), not by submesh index. Both the GPU and software renderers look up materials[submesh.material_slot].
  • Material cap — the per-renderer limit rose from 32 to 160 (MAX_MATERIALS). Meshes with more than 32 materials now bind and render every one.
  • GPU submeshes — no longer capped at 32; all of a mesh's submeshes are drawn each frame.
  • Scene filesmaterial_guids are now stored per material slot (they were per submesh). The scene version field bumps from 1 to 2.
  • Cooked mesh format (TMSH) is unchanged — no recook is required. Only the scene/component format changed.

Who is affected

Any project with scenes that assign materials to multi-material models, and any game code that reads or writes MeshRendererComponent.materials / material_count assuming the old positional (per-submesh) binding.

Upgrade steps

1. Update to 3.0.0

Download the 3.0.0 SDK. SDKs are self-contained, so you can keep the 2.x SDK installed side by side while you migrate (see the release policy).

2. Migrate your scene files

Old scenes keep loading — a v1 scene's material bindings are rebuilt in memory and a warning is logged. To persist the conversion across the whole project in one pass, run the migrator on a project whose assets have been imported at least once (opening it in Studio, or turian-cli import, does this — the migrator needs each model's cooked artifact to rebuild materials by slot):

turian-cli migrate path/to/project

The command scans every scene, rewrites the ones still on the old format, and reports what it touched. Commit the resulting diff. (Opening a scene in Studio migrates it on load and marks it dirty, so a save persists it too — the CLI is just the batch version.)

Manual per-submesh overrides are reset. The 2.x per-submesh format cannot be mapped onto material slots unambiguously, so migration rebuilds each model renderer's table from the model's slot defaults and logs a warning. If you had hand-assigned a non-default material to a specific submesh, re-assign it by slot in the Inspector after migrating. Projects that used the auto-assigned materials (the common case) need no further action.

3. Update game code

If your code assigned or read renderer materials by submesh index:

// 2.x — materials[i] bound submesh i
renderer.materials[submesh_index] = my_material_ref;

// 3.0.0 — materials[slot] bound by the submesh's material_slot
renderer.materials[material_slot] = my_material_ref;
renderer.material_count = slot_count; // number of unique material slots

Single-material meshes are unaffected: materials[0] still applies to the whole mesh (a mesh with no submesh table draws entirely with slot 0). An unset or out-of-range slot falls back to the default material. The Inspector now shows one row per material slot.

4. Check large / flattened models

Models with more than 32 submeshes or materials were clipped by 2.x — only the first 32 submeshes drew. After migrating they render completely: expect previously-missing geometry to appear, each surface with its own slot material.

Do not downgrade afterwards

Scenes saved by 3.0.0 store per-slot material_guids and version: 2; 2.x reads those entries as per-submesh and binds the wrong materials. Migrate a project once, forward only; if you need to experiment first, do it on a branch.


← All docs Edit this page