Sync shader `TIME` variable with gdscript

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By SIsilicon

I have created an ocean shader! Unfortunately its a shader. So I need a function outside so that the user can sample the wave displacement at a point something like-

func get_displace(point):
    var new_pos = Vector3(point.x, 0.0, point.y)
    #Calculate the wave at the specified point at the specified TIME.
    return new_pos

So is there someway to get a value in gscript that reflects off of the TIME shader variable.

Did you ever figure out how to do this? I tried myself but ended up going the other way, making uniform float elapsed = 0.0 and feeding it a value in _process. I’m honestly not sure if this a good idea or not but it’s worked for my case.

paco | 2018-11-16 08:59

Yeah I ended up using that solution as well.

SIsilicon | 2018-11-16 11:43

Could one of you guys please show the code that feeds the shader’s uniform a value from _process?

Ole | 2019-06-05 05:13

:bust_in_silhouette: Reply From: SIsilicon

I know that this question’s over a year old, but I thought I ought to at least give an answer. I eventually just fed a custom time variable into the shader for every time _process is called.

var time = 0
func _process(delta):
    shader_mat.set_uniform_value("time", time)
    time += delta

I don’t see anything wrong answering an old question, other people can still find the solution, it shouldn’t be necessarily targeted towards the original poster.

Xrayez | 2019-08-15 21:30

:bust_in_silhouette: Reply From: Xenm

Hello! I know this is an old post, but its been some time that I’ve scratched my head a lot on this. And I found a pretty good solution!

It looks like the TIME variable on shader are taken from the project global TIME. I have not found anywhere wich I can access this variable, but it seems that its exactly the same as OS.get_ticks_msec() wich is the time in milliseconds since the execution.

I don’t know if this also suffers from rollover, so be carefull, a nice way to fix this is like this

var fix_time  = OS.get_ticks_msec() - floor(OS.get_ticks_msec()/3600)*3600

So whenever you need to “sync” the shader with the script time:

Sprite.material.set_shader_param("outside_time", fix_time)

and on the shader you will need

uniform float outise_time;

This way you can pass this time on specific times, and compare both times inside the shader.

So you can get something like

float elapsed_time = TIME-outside_time;

This way you know how time has passed since you “synched” the shader. Wich is already good enough. This was really HARD solution to find, just because there is not much documentation about shaders and specially this TIME variable.

So, have fun now! Everyone that is reading this haha