Applying shader to entire layer and it's childrens

Vivid

Member
I need help trying to apply a simple transparency shader over a layer and it sub-layers, with no success.
When the player passes a trigger the shader is supposed to slowly fade out the main layer and it's children, this includes instance, assets, tile layers.

Here is the code

Room Create Event
Code:
var lay_ID = layer_get_id("Alpha_Layer");
layer_shader(lay_ID, shd_layeralpha);
shader_handle_ID= shader_get_uniform(shd_layeralpha, lay_ID);
Step Event
Code:
active = place_meeting(x,y,main_player);

//shift the layer alpha
var rate = 0.05;
if active then current_alpha+=rate; else current_alpha-=rate;
current_alpha = clamp(current_alpha, 0, 1);
                
shader_set(shd_layeralpha);
shader_handle_ID = shader_get_uniform(shd_layeralpha, "Alpha_Layer");
shader_set_uniform_f(shader_handle_ID, current_alpha);
shader_reset();
Fragment shader
GML:
//
// Simple passthrough fragment shader
//
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
uniform float Alpha_value;

void main()
{

gl_FragColor = v_vColour * texture2D( gm_BaseTexture,   v_vTexcoord );
    gl_FragColor.a = Alpha_value;
}
 

NightFrost

Member
You are misunderstanding slightly how layer shaders work. During draw event, when comes the layer's turn to draw its content, the shader is activated, and it remains active while all assets on layer are drawn. Once done, the shader resets. Code in some Step event will not do anything, as it is not Draw event, and neither the layer is operating nor is the attached shader active. There is no way to pass uniforms to a layer shader - at least I haven't found a way. What you need to do instead is to attach a script to layer begin with layer_script_begin. The script sets the shader and passes it the uniforms. Then a layer end script (with layer_script_end) resets the shader. As this is just a script it cannot hold and increment/decrement values, but must source them from some instance that does it.
 

ophelius

Member
You are misunderstanding slightly how layer shaders work. During draw event, when comes the layer's turn to draw its content, the shader is activated, and it remains active while all assets on layer are drawn. Once done, the shader resets. Code in some Step event will not do anything, as it is not Draw event, and neither the layer is operating nor is the attached shader active. There is no way to pass uniforms to a layer shader - at least I haven't found a way. What you need to do instead is to attach a script to layer begin with layer_script_begin. The script sets the shader and passes it the uniforms. Then a layer end script (with layer_script_end) resets the shader. As this is just a script it cannot hold and increment/decrement values, but must source them from some instance that does it.
Yes, you can pass uniforms to layer shaders, I do it in my game. I modified my variable/script names for this example, rename everything for your needs

Code:
//Set you layer shaders scripts, this can be in a step event:
layer_script_begin(LayerName, LayerShader_Set);
layer_script_end(LayerName, LayerShader_End);

//LayerShader_Set Script
if(event_type == ev_draw && event_number == 0){
      shader_set(shader);
      shader_params = shader_get_uniform(shader, "uniformvariable");
      shader_set_uniform_f(shader_params, global.uniformvalue);
}

//LayerShader_End Script
if(event_type == ev_draw && event_number == 0) shader_reset();
 

Vivid

Member
Sorry for the late response, after spending a good part of the night fiddling with my code.
I was able to get the shader to work.

Thank you NightFrost, for the help.
 
Yes, you can pass uniforms to layer shaders, I do it in my game. I modified my variable/script names for this example, rename everything for your needs

Code:
//Set you layer shaders scripts, this can be in a step event:
layer_script_begin(LayerName, LayerShader_Set);
layer_script_end(LayerName, LayerShader_End);

//LayerShader_Set Script
if(event_type == ev_draw && event_number == 0){
      shader_set(shader);
      shader_params = shader_get_uniform(shader, "uniformvariable");
      shader_set_uniform_f(shader_params, global.uniformvalue);
}

//LayerShader_End Script
if(event_type == ev_draw && event_number == 0) shader_reset();
Found this post very helpful thanks!
 
Top