Why the colors rendered are different from original texture?

Godot Version

4.3

Question

My code is very simple, just creating a Multimesh and its instances in script, then render with different textures by Shader. Textures are directly imported from PNG files, haven't tweak anything else. I set "render_mode unshaded" in Shader, so they aren't affected by lights. ( Also there is no light node in the scene, only one Multimesh) These textures are rendered exactly as same as the original image in Unity, but in Godot, the result colors are different, seems values of all channels are higher than the original, please tell me why? ( GDScript and Shader code are attached )


this is the GDScript:

func _ready() -> void:
  var material = ShaderMaterial.new()
  var mesh = QuadMesh.new()
  var multimesh = MultiMesh.new()
  var multimesh_instance = MultiMeshInstance3D.new()
  
  var textureArray = Texture2DArray.new()
  var image_paths = [
  "res://Texture/grass_seamless.png",
  "res://Texture/rock_seamless.png",
  "res://Texture/soil_seamless.png",
  ]
  var images = []
  for path in image_paths:
  var image = Image.new()
  image.load(path)
  images.append(image)
  textureArray.create_from_images(images)

  material.set_shader_parameter("texture_array", textureArray)
  material.shader = load("res://Shader/board.gdshader")
  multimesh_instance.material_override = material
  multimesh.mesh = mesh
  multimesh.transform_format = MultiMesh.TRANSFORM_3D
  multimesh.use_custom_data = true
  multimesh.instance_count = 32

  for i in range(multimesh.instance_count):
    var transform = Transform3D()
    transform.origin = Vector3(0, 0, i * 1.5)
    multimesh.set_instance_transform(i, transform)
    var dataColor = Color( i % 3, 0, 0, 0)
    multimesh.set_instance_custom_data(i, dataColor)

    multimesh_instance.multimesh = multimesh
    multimesh_instance.name = "multimeshTest"
    add_child( multimesh_instance)
    #multimesh_instance.owner = get_tree().current_scene
    pass

Here is the shader:

shader_type spatial;
render_mode unshaded;

uniform sampler2DArray texture_array;
varying vec4 instanceData;
void vertex()
{
  instanceData = INSTANCE_CUSTOM;
}
void fragment() {
  vec2 uv = UV;
  vec4 tex_color = texture(texture_array, vec3(uv.x, uv.y, instanceData.r));
  ALPHA = tex_color.a;
  ALBEDO = tex_color.rgb;
}

You may need to apply the uniform hint source_color

uniform sampler2DArray texture_array: source_color;
1 Like

Thank you, you are correct!
BTW, I found an alternate solution: calling srgb_to_linear() of a Image after it’s loaded.