Shaders Outine Shader help

Discussion in 'Programming' started by skeptile, Sep 17, 2017.

  1. skeptile

    skeptile Member

    Joined:
    Aug 10, 2017
    Posts:
    24
    Like many people (based on my Googling), I watched this Shaun Spaulding video but have questions about getting it to work just the way I need it to.

    The problem I have is that I need the outline to consistently draw a one-pixel-wide outline even when a sprite is stretched (its image_xscale and image_yscale change). With the shader in the video, the result on a stretched sprite is something like this:
    [​IMG]
    The outline is the same scale as the sprite.

    What I'm going for is this: (In this image, the outline is drawn by drawing the sprite 5 times: 4 times in black at a slight offset to form the outline, then once for the actual sprite. This method is quite hard on framerate, which is why I'm looking for a shader-based solution)
    [​IMG]

    Any help you can offer is appreciated. Forgive me if I'm missing something; I'm fairly new to shaders and don't fully understand everything about how they work. Alternatively, if you have any non-shader methods of obtaining this result, feel free to share, as long as they're not taxing on framerate.

    Here's the code in the shader:
    Vertex
    Code:
    attribute vec3 in_Position;                  // (x,y,z)
    //attribute vec3 in_Normal;                  // (x,y,z)     unused in this shader.
    attribute vec4 in_Colour;                    // (r,g,b,a)
    attribute vec2 in_TextureCoord;              // (u,v)
    
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;
    
    void main()
    {
        vec4 object_space_pos = vec4( in_Position.x, in_Position.y, in_Position.z, 1.0);
        gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
        
        v_vColour = in_Colour;
        v_vTexcoord = in_TextureCoord;
    }
    and Fragment
    Code:
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;
    uniform float pixelH;
    uniform float pixelW;
    
    void main()
    {
        vec2 offsetx;
        offsetx.x = pixelW;
        vec2 offsety;
        offsety.y = pixelH;
        
        float alpha = texture2D( gm_BaseTexture, v_vTexcoord ).a;
        
        alpha += ceil(texture2D( gm_BaseTexture, v_vTexcoord + offsetx ).a);
        alpha += ceil(texture2D( gm_BaseTexture, v_vTexcoord - offsetx ).a);
        alpha += ceil(texture2D( gm_BaseTexture, v_vTexcoord + offsety ).a);
        alpha += ceil(texture2D( gm_BaseTexture, v_vTexcoord - offsety ).a);
        
        gl_FragColor = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
        gl_FragColor.a = alpha;
    }
     
    Last edited: Sep 17, 2017
  2. CMAllen

    CMAllen Member

    Joined:
    Mar 2, 2017
    Posts:
    856
    Shaun's sampling code does not take image scale into account, so you get a sampling size equal to the size of each individual pixel in the image. You'll need to adjust your sample size to the final scale of the sprite being drawn.
     
  3. skeptile

    skeptile Member

    Joined:
    Aug 10, 2017
    Posts:
    24
    Sorry for my lack of knowledge on the subject, but what is the sampling size, and how can I adjust it?
     
  4. skeptile

    skeptile Member

    Joined:
    Aug 10, 2017
    Posts:
    24
    Never mind, I think I got it!
    I changed this
    Code:
    texelW = texture_get_texel_width(sprite_get_texture(argument0, argument1));
    texelH = texture_get_texel_height(sprite_get_texture(argument0, argument1));
    to this:
    Code:
    texelW = texture_get_texel_width(sprite_get_texture(argument0, argument1))/image_xscale;
    texelH = texture_get_texel_height(sprite_get_texture(argument0, argument1))/image_yscale;
    And that solved my problem!

    However, I just noticed that when I apply the shader, image_alpha is not taken into account. When I draw the same sprite with an alpha of 0.5, it draws at full alpha. Any idea what's causing that?

    EDIT: I managed to fix that, too. Turns out GLSL is a lot easier to intuit than I initially thought!

    One final question, if anybody sees this: is there a way to apply this shader to text?
     
    Last edited: Sep 17, 2017
  5. carbonneau

    carbonneau Member

    Joined:
    May 26, 2017
    Posts:
    7
    The only way i found to apply a shader to text is to draw the text to a surface first and apply the shader to the surface.
     

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