My 2D Shader Params (Maybe/Somehow) not Kinda Updated

Godot Version

4.4.1

Question

I’m trying to make a cooldown bar using a TextureProgressBar with a custom shader that fills up like water. In my script I call cooldown.set_instance_shader_parameter(“progress”, value) every frame.

But something goes wrong, like this photo:
image

the shader, somehow start from the middle, or I can say it’s not depends on wait_timer, if the cooldown is 10, then it could be 1/4 way to end and the shader just start show up. In the default Timer Inspector, I set it to 3seconds.

shader:

shader_type canvas_item;

instance uniform float max_value = 2.0;
instance uniform float progress = 0.0; // nilai progress aktual
uniform float wave_speed = 1.0;
uniform float wave_amplitude = 0.04;   // tinggi gelombang
uniform float wave_length = 2.5;       // frekuensi gelombang
uniform float edge_softness = 0.02;    // lembut

uniform vec4 fill_color : source_color = vec4(0.1, 0.5, 0.9, 1.0);

void fragment() {
    // y_btm: 0 = bawah, 1 = atas
    float y_btm = 1.0 - UV.y;

    float base = clamp(progress / max_value, 0.0, 1.0);

    float wave_fade = smoothstep(0.0, 0.02, base);

    float wave = sin((UV.x * wave_length + TIME * wave_speed) * TAU) * wave_amplitude * wave_fade;

    float level = clamp(base + wave, 0.0, 1.0);

    float filled = 1.0 - smoothstep(level - edge_softness, level + edge_softness, y_btm);

    COLOR = vec4(fill_color.rgb, filled * fill_color.a );
}

log :

Godot Engine v4.4.1.stable.official.49a5bc7b6 - https://godotengine.org
OpenGL API 3.3.0 NVIDIA 555.99 - Compatibility - Using Device: NVIDIA - NVIDIA GeForce MX110

button spawned
button spawned
button spawned
One casted from Player
ATTACK LAUNCHED !!!

[LOG:pressed]
  timer.wait_time   =6.0
  timer.time_left  =6.0
  cooldown.max_val =6.0
  shader.progress  =3.0
  shader.max_value =3.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =6.0
  cooldown.max_val =6.0
  shader.progress  =0.0
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.98333333333333
  cooldown.max_val =6.0
  shader.progress  =0.01666666666667
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.96666666666667
  cooldown.max_val =6.0
  shader.progress  =0.03333333333333
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.95
  cooldown.max_val =6.0
  shader.progress  =0.05
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.93575333333333
  cooldown.max_val =6.0
  shader.progress  =0.06424666666667
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.92047555555556
  cooldown.max_val =6.0
  shader.progress  =0.07952444444444
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.900321
  cooldown.max_val =6.0
  shader.progress  =0.099679
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.88365433333333
  cooldown.max_val =6.0
  shader.progress  =0.11634566666667
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.86693
  cooldown.max_val =6.0
  shader.progress  =0.13307
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.85026333333333
  cooldown.max_val =6.0
  shader.progress  =0.14973666666667
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.83359666666667
  cooldown.max_val =6.0
  shader.progress  =0.16640333333333
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.81693
  cooldown.max_val =6.0
  shader.progress  =0.18307
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.80026333333333
  cooldown.max_val =6.0
  shader.progress  =0.19973666666667
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.78359666666667
  cooldown.max_val =6.0
  shader.progress  =0.21640333333333
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.76693
  cooldown.max_val =6.0
  shader.progress  =0.23307
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.75026333333333
  cooldown.max_val =6.0
  shader.progress  =0.24973666666667
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.73220777777778
  cooldown.max_val =6.0
  shader.progress  =0.26779222222222
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.71415222222222
  cooldown.max_val =6.0
  shader.progress  =0.28584777777778
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.69609666666667
  cooldown.max_val =6.0
  shader.progress  =0.30390333333333
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =5.67804111111111
  cooldown.max_val =6.0
  shader.progress  =0.32195888888889
  shader.max_value =6.0

......
......

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.99105266666667
  cooldown.max_val =6.0
  shader.progress  =3.00894733333333
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.97438600000001
  cooldown.max_val =6.0
  shader.progress  =3.02561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.95771933333334
  cooldown.max_val =6.0
  shader.progress  =3.04228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.94105266666667
  cooldown.max_val =6.0
  shader.progress  =3.05894733333333
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.92438600000001
  cooldown.max_val =6.0
  shader.progress  =3.07561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.90771933333334
  cooldown.max_val =6.0
  shader.progress  =3.09228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.89105266666667
  cooldown.max_val =6.0
  shader.progress  =3.10894733333333
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.87438600000001
  cooldown.max_val =6.0
  shader.progress  =3.12561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.85771933333334
  cooldown.max_val =6.0
  shader.progress  =3.14228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.84105266666668
  cooldown.max_val =6.0
  shader.progress  =3.15894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.82438600000001
  cooldown.max_val =6.0
  shader.progress  =3.17561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.80771933333334
  cooldown.max_val =6.0
  shader.progress  =3.19228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.79105266666668
  cooldown.max_val =6.0
  shader.progress  =3.20894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.77438600000001
  cooldown.max_val =6.0
  shader.progress  =3.22561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.75771933333334
  cooldown.max_val =6.0
  shader.progress  =3.24228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.74105266666668
  cooldown.max_val =6.0
  shader.progress  =3.25894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.72438600000001
  cooldown.max_val =6.0
  shader.progress  =3.27561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.70771933333334
  cooldown.max_val =6.0
  shader.progress  =3.29228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.69105266666668
  cooldown.max_val =6.0
  shader.progress  =3.30894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.67438600000001
  cooldown.max_val =6.0
  shader.progress  =3.32561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.65771933333334
  cooldown.max_val =6.0
  shader.progress  =3.34228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.64105266666668
  cooldown.max_val =6.0
  shader.progress  =3.35894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.62438600000001
  cooldown.max_val =6.0
  shader.progress  =3.37561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.60771933333334
  cooldown.max_val =6.0
  shader.progress  =3.39228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.59105266666668
  cooldown.max_val =6.0
  shader.progress  =3.40894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.57438600000001
  cooldown.max_val =6.0
  shader.progress  =3.42561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.55771933333334
  cooldown.max_val =6.0
  shader.progress  =3.44228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.54105266666668
  cooldown.max_val =6.0
  shader.progress  =3.45894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.52438600000001
  cooldown.max_val =6.0
  shader.progress  =3.47561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.50771933333334
  cooldown.max_val =6.0
  shader.progress  =3.49228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.49105266666668
  cooldown.max_val =6.0
  shader.progress  =3.50894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.47438600000001
  cooldown.max_val =6.0
  shader.progress  =3.52561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.45771933333334
  cooldown.max_val =6.0
  shader.progress  =3.54228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.44105266666668
  cooldown.max_val =6.0
  shader.progress  =3.55894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.42438600000001
  cooldown.max_val =6.0
  shader.progress  =3.57561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.40771933333334
  cooldown.max_val =6.0
  shader.progress  =3.59228066666666
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =2.39105266666668
  cooldown.max_val =6.0
  shader.progress  =3.60894733333332
  shader.max_value =6.0
....
.....

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =0.17438600000001
  cooldown.max_val =6.0
  shader.progress  =5.82561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =0.15771933333335
  cooldown.max_val =6.0
  shader.progress  =5.84228066666665
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =0.14105266666668
  cooldown.max_val =6.0
  shader.progress  =5.85894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =0.12438600000001
  cooldown.max_val =6.0
  shader.progress  =5.87561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =0.10771933333335
  cooldown.max_val =6.0
  shader.progress  =5.89228066666665
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =0.09105266666668
  cooldown.max_val =6.0
  shader.progress  =5.90894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =0.07438600000001
  cooldown.max_val =6.0
  shader.progress  =5.92561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =0.05771933333335
  cooldown.max_val =6.0
  shader.progress  =5.94228066666665
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =0.04105266666668
  cooldown.max_val =6.0
  shader.progress  =5.95894733333332
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =0.02438600000001
  cooldown.max_val =6.0
  shader.progress  =5.97561399999999
  shader.max_value =6.0

[LOG:process]
  timer.wait_time   =6.0
  timer.time_left  =0.00771933333335
  cooldown.max_val =6.0
  shader.progress  =5.99228066666665
  shader.max_value =6.0

[LOG:timeout]
  timer.wait_time   =6.0
  timer.time_left  =5.99105266666668
  cooldown.max_val =6.0
  shader.progress  =5.99228066666665
  shader.max_value =6.0
--- Debugging process stopped ---

skill_button.gd:

extends TextureButton

@onready var cooldown: TextureProgressBar = $Cooldown
@onready var key: Label = $key
@onready var time_counter: Label = $time_counter
@onready var timer: Timer = $Timer

var skill = null

var change_key := "":
	set(value):
		change_key = value
		key.text = value

		shortcut = Shortcut.new()
		var input_key = InputEventKey.new()
		input_key.keycode = value.unicode_at(0)
		shortcut.events = [input_key]

func _ready():
	print("button spawned")
	change_key = "1"

	# max_value bar = lama timer
	cooldown.max_value = timer.wait_time
	cooldown.modulate.a = 0.0
	
	# kasih parameter awal ke shader
	cooldown.set_instance_shader_parameter("max_value", timer.wait_time)
	cooldown.set_instance_shader_parameter("progress", timer.wait_time - timer.time_left)

	set_process(false)

func _process(_delta):
	time_counter.text = "%3.1f" % timer.time_left
	
	if timer.is_stopped():
		cooldown.set_instance_shader_parameter("progress", 0.0)
	else:
		var p = timer.wait_time - timer.time_left  # nilai 0..wait_time
		cooldown.set_instance_shader_parameter("progress", p)
		cooldown.set_instance_shader_parameter("max_value", timer.wait_time)
	
	# panggil logger tiap frame
	_log_status("process")

func _on_pressed():
	if skill != null :
		skill.exec_skill(owner.find_child("Player"))
		cooldown.modulate.a = 1.0
		timer.start()
		disabled = true
		set_process(true)
		_log_status("pressed")

func _on_timer_timeout():
	disabled = false
	time_counter.text = ""
	set_process(false)
	cooldown.modulate.a = 0.0
	_log_status("timeout")

# ------------------------------
# Fungsi khusus logging lengkap
# ------------------------------
func _log_status(source: String) -> void:
	var shader_p = cooldown.get_instance_shader_parameter("progress")
	var shader_m = cooldown.get_instance_shader_parameter("max_value")
	print("\n[LOG:", source, "]",
		"\n  timer.wait_time   =", timer.wait_time,
		"\n  timer.time_left  =", timer.time_left,
		"\n  cooldown.max_val =", cooldown.max_value,
		"\n  shader.progress  =", shader_p,
		"\n  shader.max_value =", shader_m,
	)

skill.gd:

extends Resource
class_name Skill

var cooldown: float
var texture: Texture2D
var animation_name: String

func _init(target):
	target.cooldown.max_value = cooldown
	target.texture_normal = texture
	target.timer.wait_time = cooldown
 
func exec_skill(target):
	print(animation_name + " casted from " + target.name)

skill1.gd:

extends Skill
class_name FirstSkill

func _init(target):
	cooldown = 6.0
	animation_name = "One"
	texture = preload("res://Assets/Sprites/Icons/skill_icon_12.png")
	
	super._init(target)
	
func exec_skill(target):
	super.exec_skill(target)
	target.launch_attack()

skill_slots.gd:

extends HBoxContainer

var skill_slots: Array

func _ready() -> void:
	skill_slots = get_children()
	for i in get_child_count():
		skill_slots[i].change_key = str(i+1)

	skill_slots[0].skill = FirstSkill.new(skill_slots[0])
	skill_slots[1].skill = SecondSkill.new(skill_slots[1])
	skill_slots[2].skill = ThirdSkill.new(skill_slots[2])



your shader uses progress / max_value but your script sets progress = timer.wait_time - timer.time_left

Cooldown starts: progress = 0 → should fill to max_value  
But your logic:  
progress = wait_time - time_left → starts at 0?  

Inconsistency! Fix:

# In _process:  
var p = timer.time_left  // Counts DOWN from wait_time to 0  
cooldown.set_instance_shader_parameter("progress", p)

Then in shader:

float base = clamp(1.0 - (progress / max_value), 0.0, 1.0);

Also, max_value in shader ≠ cooldown.max_value! You set it in _ready but never update. Move:

func _process(_delta):  
    cooldown.set_instance_shader_parameter("max_value", timer.wait_time)  
    cooldown.set_instance_shader_parameter("progress", timer.time_left)  
1 Like

Nothing change, I already set the the p to timer.time_left in process when timer is not stopped. also changed the shader script. But still, nothing happened, yeah the progress should be start 0, and since the cooldown closer to 0, the progress get closer to max value. This water shader I use to show cooldown skiil, its like when the water fill the panel, then it’s ready to use again.

Your current setup:

progress = time_left → starts at 6.0 → decreases  
shader uses: 1.0 - (progress / max_value)  
At start: 1 - (6/6) = 0 → EMPTY  
At end: 1 - (0/6) = 1 → FULL  

Fix shader: remove the 1.0 - part:

float base = clamp(progress / max_value, 0.0, 1.0); 

Then:

Start: 6/6 = 1.0 → FULL
End: 0/6 = 0.0 → EMPTY
Matches draining water. Also, ensure:

progress shader param = timer.time_left
max_value shader param = timer.wait_time
No other variables needed. Retest?

Did a little workaround and its working, here’s how :

shader:

shader_type canvas_item;

instance uniform float max_value;
instance uniform float progress = 0.0;
uniform float wave_speed = 1.0;
uniform float wave_amplitude = 0.04;   
uniform float wave_length = 2.5;       
uniform float edge_softness = 0.02;    

uniform vec4 fill_color : source_color = vec4(0.1, 0.5, 0.9, 1.0);

void fragment() {
    float y_btm = 1.0 - UV.y;

    float base = 1.0 - clamp(progress / max_value, 0.0, 1.0);

    // prrogres ? gelombang : none
    float wave_fade = smoothstep(0.0, 0.05, base);

    // animasi
    float wave = sin((UV.x * wave_length + TIME * wave_speed) * TAU) 
                 * wave_amplitude * wave_fade;

    float level = clamp(base + wave, 0.0, 1.0);

    // transisi
    float filled = 1.0 - smoothstep(level - edge_softness, level + edge_softness, y_btm);

    COLOR = mix(vec4(0.0), fill_color, filled);
}

skill_button.gd:

extends TextureButton

@onready var cooldown: TextureProgressBar = $Cooldown
@onready var key: Label = $key
@onready var time_counter: Label = $time_counter
@onready var timer: Timer = $Timer

var skill = null

var change_key := "":
	set(value):
		change_key = value
		key.text = value

		shortcut = Shortcut.new()
		var input_key = InputEventKey.new()
		input_key.keycode = value.unicode_at(0)
		shortcut.events = [input_key]

func _ready():
	print("button spawned")
	change_key = "1"

	# max_value bar = lama timer
	#cooldown.max_value = timer.wait_time
	cooldown.modulate.a = 0.0
	
	# kasih parameter awal ke shader
	cooldown.set_instance_shader_parameter("max_value", timer.wait_time)
	cooldown.set_instance_shader_parameter("progress",  timer.time_left)

	set_process(false)

func _process(_delta):
	time_counter.text = "%3.1f" % timer.time_left
	#cooldown.value = timer.time_left
	if timer.is_stopped():
		cooldown.set_instance_shader_parameter("progress", 0.0)
	else:
		var p = timer.time_left  # nilai 0..wait_time
		cooldown.set_instance_shader_parameter("progress", p)
		cooldown.set_instance_shader_parameter("max_value", timer.wait_time)
	
	## panggil logger tiap frame
	_log_status("process")

func _on_pressed():
	#if skill != null:
		#skill.exec_skill(owner.find_child("Player"))
		cooldown.modulate.a = 1.0
		timer.start()
		disabled = true
		set_process(true)

		# reset progress ke 0
		cooldown.set_instance_shader_parameter("max_value", timer.wait_time)
		cooldown.set_instance_shader_parameter("progress", 0.0)

		#_log_status("pressed")

func _on_timer_timeout():
	disabled = false
	time_counter.text = ""
	set_process(false)
	#cooldown.value = 0
	cooldown.modulate.a = 0.0
	#_log_status("timeout")

# ------------------------------
# Fungsi khusus logging lengkap
# ------------------------------
func _log_status(source: String) -> void:
	var shader_p = cooldown.get_instance_shader_parameter("progress")
	var shader_m = cooldown.get_instance_shader_parameter("max_value")
	print("\n[LOG:", source, "]",
		"\n  timer.wait_time   =", timer.wait_time,
		"\n  timer.time_left  =", timer.time_left,
		"\n  cooldown.max_val =", cooldown.max_value,
		"\n  shader.progress  =", shader_p,
		"\n  shader.max_value =", shader_m,
	)

Thanks to @thomas for your time and response too.