This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
0 votes

I have an imported mesh which has multiple surface materials and I would like to create a custom shader for this mesh that uses those surface materials. I essentially want to only override the light() shader processor function, using whatever defaults the surface material would provide in fragment(). However I'm having trouble figuring out how to accomplish this.

Here's the MeshInstance3D: surface material (not sure how to embed. ctrl+g didn't work for me, sorry).

Then I try to add a shader to the material override property on the GeometryInstance3D node, but I don't see any way to get the data from the MeshInstance3D.mesh surface materials. Am I missing something (I tried to find answer online and in the shader reference with no luck)?

The only workaround I can think of for this would be to import the mesh resources as external, convert the existing surface materials to shader materials, and then somehow inject my custom shader code into the generated shader. Then I would add that shader as a surface material override on the MeshInstance3D. That sounds like a mess though so I'd rather avoid that (although maybe that could all be done in an import script?).

Any help is greatly appreciated!

update: I found a ShaderGlobalsOverride node, yet there are no docs :( if anyone has any details on this I'd love to know, otherwise I'll eventually getting around to diving into the engine source code to figure it out...

Godot version v4.0.beta8.mono.official
in Engine by (15 points)
edited by

1 Answer

0 votes

This has been confusing me for a long time.
There are several paths leading to materials in meshinstance
1. MeshInstance.mesh
2.MeshInstance.material
3.GeometryInstance.material_override

Imported materials stored as built-ins, are stored in .mesh file (1), and can be accesed with this property of Mesh Instance. Materials of mesh instance (2) naturally override them, these methods are contained within MeshInstance class, check it in docs ( for example surface_get_material(x,y). Material override is one material overriding every surface at once. In Godot 3.5 there is also material overlay, but it seems broken...

Whatever You plan to do, You won't be able to OVERLAY material with your light code. This will erase effects of fragment and vertex, they will be completely overriden.
I usually collect references to all materials in code, and create new ShaderMaterials with my shader file, swap old materials with new ones, and only set old albedo_colors as my new materials color parameter.

by (8,188 points)

Thanks for the ideas! It's unfortunate there's no simple solution for this but oh well.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.