Question - Code Question about layer_shader()

Discussion in 'GameMaker Studio 2 Community Tech Support' started by TheMagician, May 8, 2017.

  1. TheMagician

    TheMagician Member

    Joined:
    Jun 20, 2016
    Posts:
    57
    I'm trying out some of the new functionality in GMS 2 and came across layer_shader().
    However, it behaves differently than what I expected.

    Here I've set an Instance layer to use a simplistic (and purposefully overused) bloom shader.

    [​IMG]

    What I hoped for was a way to have the layer as a whole be affected by a shader - meaning that the bloom effect would only be applied after all instances have been drawn to the layer. This would be especially useful for fullscreen post-processing effect shaders.

    Is there any way to do that?
     
  2. Nocturne

    Nocturne Friendly Tyrant Forum Staff Admin

    Joined:
    Apr 13, 2016
    Posts:
    6,892
  3. Mike

    Mike nobody important GMC Elder

    Joined:
    Apr 12, 2016
    Posts:
    2,357
    layer shaders are just applied to each item being rendered - not to a "layer surface" (i.e. the final image of a surface being drawn). So if you draw 5 instances (or sprites, or even a whole tilemap), then 5 sprites will be passed through the shader. You should also remember they will be normal sprites, complete with TPage and cropping usage.
     
  4. gnysek

    gnysek Member

    Joined:
    Jun 20, 2016
    Posts:
    1,303
    It doesn't apply shader to layer, but to layer elements (one after one). That's a difference. It's more like wrap-around draw event of those elements.
     
  5. TheMagician

    TheMagician Member

    Joined:
    Jun 20, 2016
    Posts:
    57
    Thanks for your answers!

    @Nocturne: I saw the extended example for layer_script_begin() and _end() and tried it. However, it produces exactly the same end result as layer_shader(). The shader is applied to a each instance individually.

    @Mike: Is there any way to access the "layer surface" that you mention or don't they actually exist and everything is just drawn on top of each other?

    So I guess I'm still open to suggestions how to apply a post-processing effect shader to a complete layer. Right now I'm drawing the complete layer to a surface using layer_script_begin() and _end() using your code, @gnysek. Then I draw the surface with the shader applied. That works - but since the room is low resolution and then being scaled way up I lose a lot of details (see below). So a handle for the "layer surface" would really be the perfect solution.

    [​IMG]
     
  6. Nocturne

    Nocturne Friendly Tyrant Forum Staff Admin

    Joined:
    Apr 13, 2016
    Posts:
    6,892
    Don't make your surface the size of the camera view, but rather the size of the view PORT. Then it should work fine.
     
  7. Mike

    Mike nobody important GMC Elder

    Joined:
    Apr 12, 2016
    Posts:
    2,357
    There is no "layer surface" is what I was trying to say.....
     
  8. TheMagician

    TheMagician Member

    Joined:
    Jun 20, 2016
    Posts:
    57
    @Nocturne: That's exactly what I thought, too - but the surface size made no difference whatsoever. I get the same pixelated effect and the high resolution is lost.

    Room size: 320x240
    Camera_0: 320x240
    Viewport_0: 1280x960 (scaled by a factor of 4)

    Create Event of obj_control:
    Code:
    surf_shader = surface_create(1280,960);
    
    var lay_id = layer_get_id("Instances");
    layer_script_begin(lay_id, layer_surface_set);
    layer_script_end(lay_id, layer_surface_reset);
    Script layer_surface_set():
    Code:
    if (event_type == ev_draw)
    {
        if (event_number == 0)
        {
            surface_set_target(obj_control.surf_shader);      
            draw_clear_alpha(c_black,0);
        }
    }
    Script layer_surface_reset():
    Code:
    if (event_type == ev_draw)
    {
        if (event_number == 0)
        {
            surface_reset_target();
            draw_surface(obj_control.surf_shader,0,0);
        }
    }
    Result:
    [​IMG]

    As you can see there is no difference in the end result - independent of the surface being 320x240 or 1280x960.
    I've also tried draw_surface_streched() to stretch it to 1280x960 but it also gives the same result.
     

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