No Surface Material override for ArrayMesh?

Godot Version

4.2

Question

I was trying to create a PackedScene to Instantiate and then procedurally use a Mesh for. I wanted to include the Material (or a Shader actually) in the PackedScene. But I quickly noticed that I am not allowed to set the surface material override for an ArrayMesh:

image

This is completely different in the case of other Meshes:

image

Am I missing something? I want to manipulate the Albedo of the Material later on via script, but get a null reference error.

Or is it just not possible to include the Surface Material Override without an actual Mesh there yet. (In that case I could get rid of the PackedScene and just Instantiate the MeshInstance3D from code without having the export field for the PackedScene).

Edit:

Since there are multiple ways to set a Mesh in Godot, when to use which way btw?

  • Set the Mesh material directly (affects the mesh directly, bad for seperate instances I guess)
  • Set the Surface Material Override
  • Set the Material Override in GeometryInstance3d
  • Set the Material Overlay in GeometryInstance3d (just renders over existing mesh as can be seen when changing Render priority)
1 Like

The surface material override property only shows up in the inspector when there is an actual surface to override.

A fresh dummy ArrayMesh has no surface so it does not show anything.

The surface_material_override is an internal book-keeping of the MeshInstance3D node. It is not part of the Mesh resource. Instead, the node switches the materials for the mesh as a helper feature. It does not change the mesh material directly, it changes the instance material.

The material_override is book-keeping of the inherited GeometryInstance3D but instead of switching the surface material of a single surface it override ALL the surfaces with the same material.

The override hierarchy is geometry > instance > mesh.
Geometry material overrides all instance surface materials.
A surface material overrides the material for the specific mesh surface index.

You can call the functions set and override functions directly on the RenderingServer API without the need for a node and set whatever material you need for your mesh instance.

To replace the Mesh surface material you need to get the mesh RID and surface index and use RenderingServer.mesh_surface_set_material(). This will replace the material for all instances that use the same mesh and have no instance override material set.

To replace the material only for an instance you get the instance RID with MeshInstance3D.get_instance() and the surface index and use RenderingServer.instance_set_surface_override_material().

To replace all surfaces with a single material use RenderingServer.instance_geometry_set_material_override().

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.