(SOLVED) shader layer excluding GUI layer

Discussion in 'Programming' started by ZombieSquirrel, Oct 8, 2019.

  1. ZombieSquirrel

    ZombieSquirrel Member

    Joined:
    Oct 18, 2018
    Posts:
    98
    Hi everyone.
    I'm trying to build a lighting system using shaders.

    I have multiple tile layers, and a couple of instance layers per room.
    I also have a system instance layer at depth 0 just to have some layer
    where my system instances need to go and be nicely grouped together.
    This last layer contains some of my important system things, like pause menu's, mouse sprites, user interface, inventory sprites, etc...

    What I want to do is have every layer and every non-gui-instance be affected by a
    lighting shader.
    I do not want whatever is drawn on the GUI layer to be affected.
    For example, I have an inventory object that draws the player inventory using
    its draw GUI event. I also have a pausesystem instance that draws a pause menu in its
    draw GUI event when the game is paused, there's things like healthbars, and so on.

    Naturally, I don't want whatever is drawn as GUI to be affected by the lighting shader.

    I can do it however, using a very tedious strategy:
    Per room, have a layer_shader do the shader magic per layer.
    Then, in each instance, have its draw event go through the same shader.

    This works, but it doesn't allow me do to point--lighting i think. For example, have a torch on a
    wall light up the entire surrounding area surrounding area, instances included.

    What I'd want to do, and what I'm asking here,
    is if it is at all possible to send everything through a shader, but not things that are rendered on the GUI layer, or things that are drawn using draw GUI events. Instead of treating each layer and each instance separately, have it all be treated as one thing to change, while keeping all the GUI stuff unaffected.

    I'm sure this has something to do with surfaces, but I'm afraid my scaled camera will be a real chore to fix that.

    Still, is this doable? Send everything indiscriminately through a shader, but not anything draw GUI event related?

    The reason I'm asking is because I can't seem to find a way to "grab" the GUI layer, like I do with any other layer using layer_shader(layer_id) for example.

    I'm also a noob when it comes to surfaces, so I know i will need to learn that probably.
     
  2. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,185
    The alternative to layer shaders is to set shader, draw every layer that needs lighting and then reset shader.
    Code:
    shader_set();
    
    // draw layers that are affected by lighting
    
    shader_reset();
    
    // draw layers unaffected
    
    I have no idea how layers work, but to handle the timing you could make use of layer_script_begin, in which you choose the first layer and set the shader.
    Then in the last layer that is affected you can reset the shader using layer_script_end.

    If you have gaps (unaffected layers between affected layers) I see no way to achieve this without having the shader set and reset multiple times.
    Even a surface wouldn't help then.
     
  3. ZombieSquirrel

    ZombieSquirrel Member

    Joined:
    Oct 18, 2018
    Posts:
    98
    is it possible however, to build a surface from literally everything in the game except the gui layer? I'm already keeping point light sources in mind, and i'd rather do something that needs to change only 1 surface instead of having to change each individual tile layer, instance,... in a room.
     
  4. Simon Gust

    Simon Gust Member

    Joined:
    Nov 15, 2016
    Posts:
    3,185
    Read up on the application_surface. before entering the GUI draw phase, the application_surface will hold everything drawn in that frame and can be affected by a shader.
    As long as you reset the shader before the GUI layer begins to draw you should be fine.

    You are required to take over control of the automatic drawing of the application surface.
    https://docs2.yoyogames.com/source/...surfaces/application_surface_draw_enable.html

    You can draw the application surface in the post draw event.
    https://docs2.yoyogames.com/index.h...nce/drawing/surfaces/application_surface.html
     
  5. ZombieSquirrel

    ZombieSquirrel Member

    Joined:
    Oct 18, 2018
    Posts:
    98
    Quick and easy to follow answer. I tried it and it works!
    I now use my camera object's post-draw event to disable application surface drawing, then use draw_surface_ext to draw it back scaled, and send it through my shader.
    All my GUI elements are intact!

    Thanks :)
     
    ParodyKnaveBob likes this.
  6. ZombieSquirrel

    ZombieSquirrel Member

    Joined:
    Oct 18, 2018
    Posts:
    98
    Extra comment: REALLY thank you. Pointing me to that simple solution just opened up the world of shaders to me.
    Now i'm going to... I don't know :D Maybe make a deep day and night system or something :D
     
    Simon Gust likes this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice