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— thematerialsarray is now indexed by material slot (Submesh.material_slot), not by submesh index. Both the GPU and software renderers look upmaterials[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 files —
material_guidsare now stored per material slot (they were per submesh). The sceneversionfield bumps from1to2. - 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.