How to use elapsed time in a shadder ?
Asked Answered
M

6

0

I am trying to make a shadder where I input a time in secs and it make the texture invisible by this time, but I could not understand how to use the TIME for this since I could not find any doc about what TIME is, I know it is the iTime, but how can I set an starttimer, reset, stop etc ( I know I cant stop a shadder, but I wander how can I make it stops changing the texture after the time runs out )

This is what I got so far, it use TIME, but by sin :

shader_type canvas_item;

uniform float fade_speed;

void fragment() {
	vec2 texture_resolution = 1.0 / TEXTURE_PIXEL_SIZE;
	vec2 pixel_within_texture = floor(UV * texture_resolution);
	vec4 texture_color = texture(TEXTURE, UV);

    float inv_value = sin(TIME * fade_speed) * 0.5 + 0.5;
    inv_value = clamp(inv_value, 0.0, 1.0);

	vec4 final_color = vec4(texture_color.r, texture_color.g, texture_color.b, inv_value); 

	COLOR = final_color;

}

How can I make it runs, starting from alpha 1, for a few seconds and stop changing the texture when alpha is 0 ?

Marienbad answered 22/10, 2023 at 23:26 Comment(0)
S
0

Marienbad

COLOR.a = smoothstep(end_time, start_time, TIME);
Shultz answered 22/10, 2023 at 23:44 Comment(0)
M
0

Shultz What is end_time and start_time ? Seconds ?

Marienbad answered 23/10, 2023 at 4:26 Comment(0)
S
0

Marienbad What is end_time and start_time ? Seconds ?

They are just numbers that clamp and interpolate the value of TIME. So it's same units as TIME, if you wish to look at it that way.

In shaders, TIME is just time (in seconds) that passed since startup. It's endlessly increasing and you can't affect it in any way. You get it as an input and it's totally up to your creativity how will you interpret or use that value.

Shultz answered 23/10, 2023 at 4:38 Comment(0)
M
0

For doing things only within a set window of time in a shader, you can do different approaches but they all involve passing at least one extra uniform to the shader.

You could add uniform float start_time; and uniform float end_time, and set them when you want to run the shader. You'd set them in your material based on Time.get_ticks_msec() * 1000.0

You could have only one of them and just use a constant float to add to or subtract from it, if you know exactly how long you want it to be.

You could replace start_time and end_time with 0.0 and 1.0, and replace TIME with a uniform variable named delta or something. Now your shader doesn't care about time at all and you can handle the time calculation in your gdscript _process or with a Timer or whatever you want. You could even create an animation to directly control the variable.

Manamanacle answered 23/10, 2023 at 7:13 Comment(0)
S
0

Yeah, if you need to arbitrarily trigger shader timing on some event, you'll need to use a custom time uniform and drive it from the "outside". You can animate an uniform like any other property, via animation players, tweens or manually in _process().

However in that case you're delegating the work to the CPU, which is clumsy (and slower) but sometimes there's no other solution. So if you can manage to achieve what you want by interpreting TIME, do it like that, otherwise animate an uniform.

You can do a lot by using TIME in clever ways though.

Shultz answered 23/10, 2023 at 11:39 Comment(0)
M
0

Shultz I tested and it actually works ! Thanks.

shader_type canvas_item;

// https://mcmap.net/q/1771/godot-how-to-use-elapsed-time-in-a-shadder
uniform float start_time_secs=0;
uniform float end_time_secs=5;

void fragment() {
	vec2 texture_resolution = 1.0 / TEXTURE_PIXEL_SIZE;
	vec2 pixel_within_texture = floor(UV * texture_resolution);
	vec4 texture_color = texture(TEXTURE, UV);

	float newalpha = smoothstep(end_time_secs, start_time_secs, TIME);

	vec4 final_color = vec4(texture_color.r, texture_color.g, texture_color.b, newalpha); 

	COLOR = final_color;
}
Marienbad answered 23/10, 2023 at 14:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.