Quick answer: Set multi_mesh.use_colors = true. On the StandardMaterial3D set vertex_color_use_as_albedo = true. Custom shaders read INSTANCE_COLOR in vertex.
You set per-instance color via set_instance_color. All instances render the same default color. The MultiMesh isn’t storing colors, or the material isn’t reading them.
The Symptom
set_instance_color returns; visuals don’t reflect. set_instance_transform works fine for positions.
The Fix
var mm := MultiMesh.new()
mm.transform_format = MultiMesh.TRANSFORM_3D
mm.use_colors = true # THIS
mm.use_custom_data = false
mm.mesh = mesh
mm.instance_count = 1000
for i in 1000:
mm.set_instance_transform(i, ...)
mm.set_instance_color(i, Color(randf(), randf(), randf()))
$MultiMeshInstance3D.multimesh = mm
And the material:
StandardMaterial3D:
vertex_color_use_as_albedo: true
vertex_color_is_srgb: false # match your color space
Custom Shader
shader_type spatial;
void vertex() {
COLOR = INSTANCE_COLOR;
}
void fragment() {
ALBEDO = COLOR.rgb;
}
Verifying
Spawn 100 instances with random colors. Should render multicolored. If all uniform, use_colors or vertex_color_use_as_albedo is missing.
“use_colors on. Material reads vertex color. Per-instance shows.”
Related Issues
For shader uniform runtime, see shader uniform. For shader uniform array, see uniform array.
Two flags. Per-instance lights up.