SOLVED Is it possible to set the blend mode of a tile layer?

GonerBits

Member
In my game, I'd like to have an effect where there's a forest and there are gaps in the canopy that lets light fall through the leaves. It would help immensely if I could just create a tile layer that uses the "add" blend mode to light up the floor.

Here is an example using a tileset that I made to manually create light spots. (as in, the shadows are part of the tiles themselves) This takes forever to put together, and wouldn't be very feasible for an entire area of a game.
1621908065686.png

Using a tileset with light colors and low opacity is much quicker, but it ends up washing the outline colors out (see below):
1621908179228.png

Meanwhile, manually drawing an overlaid sprite with the "add" blend mode (see below) produces more vibrant colors, but it would require making an overlay map for every room (which is also not very plausible).
1621908444146.png

I've been looking around, and I haven't been able to find much of anything regarding this issue... if there's a way to draw a tile layer in a different blend mode, that would be a life-saver. If not, then is there another way I can achieve the desired effect?
Thanks so much.
 

Alabard

Member
You can use the layer_script_begin and layer_script_end functions, they will set a script function to be used before and after a layer is rendered, respectively.

You can get the details by looking at the manual entries for such functions, but for what you want to make simply create a function that sets the blend mode to additive and another one that sets it back to normal:

GML:
/// @function layer_blend_add();
function layer_blend_add(){
if event_type == ev_draw
   if event_number == 0
      gpu_set_blendmode(bm_add);
}

/// @function layer_blend_normal();
function layer_blend_normal(){
if event_type == ev_draw
   if event_number == 0
      gpu_set_blendmode(bm_normal);
}
And then, using the id of the layer you want to use the blend mode in, set the layer_script_begin/end functions with the new functions you just made:
GML:
var layer_id = layer_get_id("Tiles");
layer_script_begin(layer_id, layer_blend_add);
layer_script_end(layer_id, layer_blend_normal);
By the way, this last code doesn't need to be run every step, you can add it to the room creation code, or the create event of some object.
 

GonerBits

Member
You can use the layer_script_begin and layer_script_end functions, they will set a script function to be used before and after a layer is rendered, respectively.

You can get the details by looking at the manual entries for such functions, but for what you want to make simply create a function that sets the blend mode to additive and another one that sets it back to normal:

GML:
/// @function layer_blend_add();
function layer_blend_add(){
if event_type == ev_draw
   if event_number == 0
      gpu_set_blendmode(bm_add);
}

/// @function layer_blend_normal();
function layer_blend_normal(){
if event_type == ev_draw
   if event_number == 0
      gpu_set_blendmode(bm_normal);
}
And then, using the id of the layer you want to use the blend mode in, set the layer_script_begin/end functions with the new functions you just made:
GML:
var layer_id = layer_get_id("Tiles");
layer_script_begin(layer_id, layer_blend_add);
layer_script_end(layer_id, layer_blend_normal);
By the way, this last code doesn't need to be run every step, you can add it to the room creation code, or the create event of some object.
Thank you!! This is a huge help, exactly what I was missing.
 
Top