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.