Shaders Draw above a shader.

Niels

Member
Hi everyone,

I have a question about shaders and layers.

For my top-down game I want to assign a water distortion shader to a certain instance layer.

The idea is this:
1.instances layer (above water, shouldnt't be affected by shader)

2. instances_below (this layer should be distorted by the watershader)
3. background (just a sea texture)

The shader I build is based upon the follow tutorial by Gaming reverends:

tbh I have no clue on how to set the shader to a certain depth/layer.
 

rIKmAN

Member
Hi everyone,

I have a question about shaders and layers.

For my top-down game I want to assign a water distortion shader to a certain instance layer.

The idea is this:
1.instances layer (above water, shouldnt't be affected by shader)

2. instances_below (this layer should be distorted by the watershader)
3. background (just a sea texture)

The shader I build is based upon the follow tutorial by Gaming reverends:

tbh I have no clue on how to set the shader to a certain depth/layer.
You should be able to use layer_script_begin() / layer_script_end().


The "Extended Example" in the manual actually shows your use case of setting a shader to affect the given layer using these functions too, so you should be able to use that as a template for setting your own shader to the layer you want to be affected by it.

Manual page: https://docs2.yoyogames.com/source/_build/3_scripting/4_gml_reference/rooms/layers/layer_script_begin.html


edit:
There is a bug logged on Mantis regarding using surfaces with the layer script functions, Fritz seems to have posted a workaround which might be worth looking at if you have any problems and are using surfaces yourself:
https://bugs.yoyogames.com/view.php?id=31461
 
Last edited:

Niels

Member
Thx for the reply.
But both layer scripts as well as layer_shader functions are made to be called once (at the creation of the layer), but my shader has a time variable that scrolls the texture distortion. I'm not sure how I can have a object that holds the shader AND use the scripts or layer_shader function.
 

NightFrost

Member

NightFrost

Member
OK that would explain a lot! Except why you would call the scripts in the room create event (like recommended in the manual), the room create event is only called once right?
Not sure what you're referencing. Maybe you're looking at them telling you how to set up layer script? That of course needs to be done only once, and then it gets called every step.
 

Niels

Member
Not sure what you're referencing. Maybe you're looking at them telling you how to set up layer script? That of course needs to be done only once, and then it gets called every step.
Now that we have defined our scripts for setting the shader, we then have to assign them to a specific layer so that the layer knows to call them. This would be done in the room creation code, or in the create event or room start event of some controller object (they do not need to be set every step, but rather once at the start of the room, or when the layer is initially created):
I was aiming at this codeblock which says the script is called at the room create event
 

rIKmAN

Member
Thx for the reply.
But both layer scripts as well as layer_shader functions are made to be called once (at the creation of the layer), but my shader has a time variable that scrolls the texture distortion. I'm not sure how I can have a object that holds the shader AND use the scripts or layer_shader function.
You can pass in your time variable each frame using uniforms, if you look at the example code they do it with colour_to_find and colour_to_set and pass in static values, but you could set your time uinform this way by passing in the variable that counts your time to the shader instead (if I've understood you correctly).

As NightFrost pointed out the scripts need to be setup once in a Create Event which then tells GMS2:

1) The script set in layer_script_begin() should run before this layer is rendered
2) The script set in layer_script_end() should run after this layer is rendered

It doesn't just run once for that frame when you call those functions, you are basically assigning the scripts to be run before/after that layer is rendered for the rest of the program execution.
 

Niels

Member
Thanks for the replies, it's a bit more clear how these things work now!
Will try to make it work tonight
 
Top