Materials become pure white with no shading when modified through code | Godot C#

58 Views Asked by At

I have a PackedScene that I am instantiating through code. All that that scene has is a single MeshInstance3D with a default StandardMaterial3D.

From the code, after instantiating I try and modify the AlbedoColor of the MeshInstance3D. However, no matter what I seem to do, the material comes in as pure white with no shading.

enter image description here

If I manually add a material either to the MeshInstance3D directly or through either the Surface Material Override or Geometry.MaterialOvrride in the inspector, everything works as expected and materials have proper shading. However, as soon as I add or modify a material through code, it immediately breaks and looks like the image above. I've tried various approaches through code, all outlined below:

Direct access to mesh material

var orb = _orbResource.Instantiate<Orb>();
if (orb.Mesh.SurfaceGetMaterial(0) is StandardMaterial3D material)
{
    material.AlbedoColor = _color;
    orb.Mesh.SurfaceSetMaterial(0, material);
}

Direct access to Override Material

var orb = _orbResource.Instantiate<Orb>();
if (orb.MaterialOverride is not StandardMaterial3D material)
{
    throw new NullReferenceException("The orb did not have a material override");
}

material.AlbedoColor = _color;
        
orb.MaterialOverride = material;

New Override Material

var orb = _orbResource.Instantiate<Orb>();
var material = new StandardMaterial3D();
material.AlbedoColor = _color;
        
orb.MaterialOverride = material;

I've tried various combinations of the above. It doesn't change even if I directly set the material again after modifying it. No matter what though, if I modify the AlbedoColor, it always turns to full white with no shading. I've authenticated the colors as well. I'm seriously at a loss as to what could be happening but I feel like it's something simple I just overlooked.

I'm new to Godot so it's probably some engine-specific thing I missed.

Edit 1

As @Theraot mentioned, I tried to do the same thing in a new project and it resulted in the same issue. Take a look at the image below.

enter image description here

All of these balls are MeshInstance3Ds with their own unique sphere mesh instance. The sphere on the bottom center is the one I am modifying via code. No matter how I do it, it always ends up unlit and pure white. The mesh on the left has a material directly on the mesh. The sphere on the right has no material. And the sphere on the top has a material override. They all work just fine unless I modify them via code. Strange.

My lighting setup is a box around the spheres with a point light.

It's also important to say that I can create and assign materials and they seem to work fine. However, as soon as I modify any property, they break.

2

There are 2 best solutions below

0
On BEST ANSWER

So as suspected, the answer was something super simple. I was assigning colors incorrectly. When creating a color, the correct way to do so is like var color = new Color(0.1f, 1f, 0.45f, 0.2f);, where everything is in the range 0f - 1f. I, however, was trying to do something like var color = new Color(100, 24, 255, 40); which is incorrect. So, when the value was being assigned it was WAY out of range of valid colors which resulted in the weird effect. Not sure what I was thinking, but I'm glad I figured it out.

2
On

you can try cloning material for each orb

var orb = (Orb)_orbResource.Instance();
var meshInstance = (MeshInstance3D)orb.GetNode("MeshInstance");
var material = (StandardMaterial3D)meshInstance.GetSurfaceMaterial(0).Duplicate();
material.AlbedoColor = _color;
meshInstance.SurfaceSetMaterial(0, material);

also in your aproach of New override mateiral I would suggest using getnode() so you make sure you are adding the material to the hierarchy OBJ(Node)

var orb = (Orb)_orbResource.Instance();
var material = new StandardMaterial3D();
material.AlbedoColor = _color;
var meshInstance = (MeshInstance3D)orb.GetNode("MeshInstance");
meshInstance.SurfaceSetMaterial(0, material);

Please make sure your node is MeshInstance or whatever your orb's MeshInstance3D is named in the scene