shader_type canvas_item; // Color of the flash overlay uniform vec4 flash_color : source_color = vec4(1.0, 1.0, 1.0, 1.0); // Overall intensity of the flash (0.0 = none, 1.0 = full) // Set dynamically by FlashEffect.gd each frame uniform float flash_intensity : hint_range(0.0, 1.0) = 0.0; // How the flash blends with the original sprite uniform int blend_mode : hint_enum("Mix", "Additive", "Screen") = 0; // Additional brightness added to the flash color (0.0 = none, 1.0 = double) uniform float brightness_boost : hint_range(0.0, 1.0) = 0.0; void fragment() { vec4 original = texture(TEXTURE, UV); vec3 flash_rgb = flash_color.rgb * (1.0 + brightness_boost); vec3 result; float alpha = original.a; if (original.a == 0.0) { // Skip processing for fully transparent pixels COLOR = original; } else if (blend_mode == 0) { // Mix: Linear interpolation between original and flash color result = mix(original.rgb, flash_rgb, flash_intensity); // Modulate alpha by flash intensity for a flickering transparency effect alpha = mix(original.a, flash_color.a, flash_intensity); } else if (blend_mode == 1) { // Additive: Flash adds light to the original, clamped to avoid HDR blowout result = clamp(original.rgb + flash_rgb * flash_intensity, 0.0, 1.0); // Additive naturally brightens, so boost alpha when flashing alpha = clamp(original.a + flash_color.a * flash_intensity, 0.0, 1.0); } else { // Screen: Brightens without washing out highlights result = original.rgb + (1.0 - original.rgb) * flash_rgb * flash_intensity; alpha = clamp(original.a + (1.0 - original.a) * flash_color.a * flash_intensity, 0.0, 1.0); } COLOR = vec4(result, alpha); }