Godot Version
v4.6.1.stable.official.14d19694e
Question
Hi guys! I’m very new to Godot and programming in general. I’m trying to create a shader that lets me gradually tint my player sprite (or the entire screen, I’m not sure which will look better) red, upon entering the killzone. I tried searching for a solution but I couldn’t find a way to weave it into my code, probably due to my poor understanding of it all.
So basically what I want to happen is:
- Player enters the killzone
- The player sprite color starts shifting red over time
- When the player respawns, everything is back to normal
Here’s the shader code:
shader_type canvas_item;
uniform vec4 color : source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform float tint_factor : hint_range(0.0, 1.0, 0.001);
uniform float fade : hint_range(0.0, 1.0, 1.0);
void vertex() {
// Called for every vertex the material is visible on.
}
void fragment() {
vec4 main_texture = texture(TEXTURE, UV);
vec4 final_output = main_texture;
float original_modulation = 1.0 - tint_factor;
final_output.rgb = mix(main_texture.rgb * original_modulation, color.rgb * tint_factor, tint_factor);
final_output.a *= fade;
COLOR = final_output;
}
And here’s the code for the killzone:
extends Area2D
@onready var label: Label = $Label
@onready var timer: Timer = $Timer
@onready var player: Player = $"../Player"
var player_in_area : Player
func _ready():
label.hide()
func _process(_float):
if timer.is_paused() == false and player_in_area != null:
label.global_position = player_in_area.global_position + Vector2(-6, -100)
label.text = str(int(timer.time_left) + 1)
func _on_timer_timeout():
get_tree().reload_current_scene()
func _on_body_entered(body: Node2D) -> void:
if body is Player:
GlobalScript.shooting_enabled = false
player_in_area = body
label.show()
timer.wait_time = 3
timer.one_shot = true
timer.start()
func _on_body_exited(body: Node2D) -> void:
if body is Player:
GlobalScript.shooting_enabled = true
player_in_area = null
label.hide()
timer.stop()
GlobalScript.bullet_count = 20
Preferably, the code for color shift would be contained in the killzone script, so that it’s reusable for different characters I’m planning to add in the future.
Let me know if you need anything else to help.
Cheers!
Uhm. Can’t you simply set the modulate-property of the parent node of all the things you want to redden?
I know most gamedevs are in love with shaders, but to me it always feels like a form of premature optimization.. 
When I started looking for info on how to do this, most people were talking bout shaders, so I just assumed it’s the way to go.
Sure, I can go with modulate! Could you tell me how I can code it in, so that the change is gradual? As you can see, none of the functioons in killzone are using delta, so I’m not sure how I’d make it a color shift, not a color swap.
Should I make a new function for that? and if so, how do I make it start upon entering the killzone?
Thanks in advance! 
Actually, there’s a node for this if you want to do the whole screen. No need for shaders, or a huge hierarchy. It’s called CanvasModulate.
extends Node2D
@export var rage_color: Color = Color.WHITE
@onready var canvas_modulate: CanvasModulate = $CanvasModulate
func snap_to_red() -> void:
canvas_modulate.color = rage_color
func ramp_to_red(time: float) -> void:
var tween: Tween = create_tween()
tween.tween_property(canvas_modulate, "color", rage_color, time)
func reset_color() -> void:
canvas_modulate.color = Color.WHITE
Create one, attach this to your level, and then you can make the whole screen go red. Just select a color for the export variable and play around with alpha, shades etc, even while the game is running. (I assigned it white by default so that if you forget to set it your whole screen won’t go to black.)
If you want to change just the player, you can do the same thing, just use its modulate property instead.
As I understand, this script is attached to the main sccene node, right? Or is it in this CanvasModulate node with an onready var of itself?
hope this question makes sense lol
Also, how do I make it go off after the player enters the killzone? I hope it’s not too much to ask but please, be as explicit as you can. I’m really not that smart…
Attached to the main scene node. The @onready var in this case indicates that the CanvasModulate node is a child of the Node2D this is attached to. You can organize it however you want though.
You call snap_to_red() or ramp_to_red() with the amount of time in seconds you want the change to occur over. When you want to reset it, call reset_color().
You would trigger it by using an Area2D that calls the code or sends a signal when the player enters.
If this is not making sense to you, I recommend you follow this tutorial and learn the basics of how Godot works: Your first 2D game — Godot Engine (stable) documentation in English