Lerp color becoming black instead of end color

Godot Version

4.3

Question

I am trying to change self_modulate to start at the color red, and gradually shift towards blue as each enemy (spawner) is destroyed. When there are no enemies alive, the last parameter becomes 0. When I set it to 0 in ready, it works as intended. However, when it changes via the signal, instead of becoming more blue, it becomes more black. What’s the problem, and how do I fix it? Code below.

extends TileMapLayer

signal spawner_death

var max_spawners: float = 0.0
var spawners_left: float

var start_color := Color.FIREBRICK
var end_color   := Color.DEEP_SKY_BLUE

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	for child in get_parent().get_children():
		if child.has_method("is_spawner"):
			max_spawners += 1.0
		
	spawners_left = max_spawners
	self_modulate = end_color.lerp(start_color, spawners_left / max_spawners)

func _on_spawner_death() -> void:
	spawners_left -= 1
	self_modulate = end_color.lerp(start_color, spawners_left / max_spawners)

Thank you.

try to debug:

print("weight:" + str(spawners_left / max_spawners))

Docs: Color — Godot Engine (stable) documentation in English

The interpolation factor weight should be between 0.0 and 1.0 (inclusive)

The weight is set to what it should be, so I don’t think that’s the issue.

debugging helps, even if you think everything is correct :slight_smile:

my 'lerp' tests GD-Script
extends Node2D

var max_spawners: float = 0.0
var spawners_left: float

var start_color := Color.FIREBRICK
var end_color   := Color.DEEP_SKY_BLUE

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	
	max_spawners += 1.0
	max_spawners += 1.0
	max_spawners += 1.0
	
	spawners_left = max_spawners
	
	spawners_left -= 1
	spawners_left -= 1
	spawners_left -= 1
	spawners_left -= 1
	
	print("max_spawners: ", max_spawners)
	print("spawners_left: ", spawners_left)
	print("weight: ", str(spawners_left / max_spawners))
	
	self_modulate = end_color.lerp(start_color, spawners_left / max_spawners)
	
	print("end_color: ", end_color)
	print("self_modulate: ", self_modulate)

For example, if spawners_left is negative (“-1”), then a negative weight is calculated. Then some color components can also be negative. If the color is invalid, then often only the black color is displayed.

max_spawners: 3
spawners_left: -1
weight: -0.33333333333333
end_color: (0, 0.749, 1, 1)
self_modulate: (-0.2327, 0.9542, 1.2889, 1)

What happens when max_spawners is 0? Is the dividing by zero erroring out or not being caught?

Seems like your parameters are flipped if you want start_color when 0 and end_color when 1. Modulate can only multiply colors so it can be difficult to brighten an image if your texture is already dark.

self_modulate = start_color.lerp(end_color, spawners_left / max_spawners)