Shaders Simple Color Replacement Shader

Discussion in 'Programming' started by AzureCube, Oct 10, 2019.

  1. AzureCube

    AzureCube Member

    Joined:
    Aug 16, 2019
    Posts:
    6
    Hello,

    I am currently using GMS 1.4.9999 and I wish to create a simple shader that replaces every black pixel in a sprite with white and then converts the sprite to grayscale. By searching the Internet, I have found a functional grayscale shader (code included below). However, I have not figured out how to convert all black pixels to white.

    Does anyone know a simple way of testing the color of a pixel and, only if it is a certain value, changing that pixel to a different color?

    Grayscale shader code (/3.5 to darken from default value):

    Fragment shader:
    varying vec2 vTc;
    void main() {
    vec4 irgba=texture2D(gm_BaseTexture,vTc);
    float luminance=dot(irgba.rgb,vec3(0.2125,0.7154,0.0721));
    gl_FragColor=vec4(luminance/3.5,luminance/3.5,luminance/3.5,irgba.a);
    }

    Vertex shader:
    attribute vec4 in_Position;
    attribute vec2 in_TextureCoord;
    varying vec2 vTc;
    void main() {
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position;
    vTc = in_TextureCoord;
    }
     
  2. SoVes

    SoVes Member

    Joined:
    May 17, 2017
    Posts:
    148
    Depends on how exact you want it to be, but you can just compare it
    Code:
    If (color.rgb == vec3(0.0)){
    color.rbg = ve3(1.0);
    }
     
    ZombieSquirrel likes this.
  3. Xor

    Xor @XorDev

    Joined:
    Jun 20, 2016
    Posts:
    72
    Hello.

    I would use ternary to check if the gray value is below a black threshold and set it to white.
    Here's an example fragment shader:
    Code:
    varying vec2 vTc;
    
    void main()
    {
        //Sample texture.
        vec4 tex = texture2D(gm_BaseTexture,vTc);
    
        //Calculate grayscale luminance value (https://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems)
        float gray = dot(tex,vec4(.299,.587,.114,0));
        //Black is considered anything darker than this value:
        const float black = .01;
        //If gray is greater than black then do nothing, otherwise set gray to 1.0 (white).
        gray = (gray>black) ? gray : 1.;
        //You can divide gray by 3.5 here if you want the white result to be unaffected.
       
        //Darken the grayscale result.
        gl_FragColor = vec4(vec3(gray/3.5),tex.a);
    }
    
    I hope this helps!

    -Xor
     
    Yal likes this.
  4. AzureCube

    AzureCube Member

    Joined:
    Aug 16, 2019
    Posts:
    6
    Hello,
    Thank you both for your help. The color replacement effect now works properly. However, the shader does not take into account the alpha at which the sprite is being drawn ( image_alpha or draw_set_alpha() ).
    How might that be implemented?

    Shader Code:
    Fragment Shader:
    varying vec2 vTc;
    void main()
    {
    vec4 irgba=texture2D(gm_BaseTexture,vTc);
    float luminance=dot(irgba.rgb,vec3(0.2125,0.7154,0.0721));
    gl_FragColor=vec4(luminance/4.5,luminance/4.5,luminance/4.5,irgba.a);
    if (gl_FragColor.rgb == vec3(0.0))
    {
    gl_FragColor=vec4(1.0,1.0,1.0,irgba.a);
    }
    }

    Vertex Shader:
    attribute vec4 in_Position;
    attribute vec2 in_TextureCoord;
    varying vec2 vTc;
    void main() {
    gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * in_Position;
    vTc = in_TextureCoord;
    }
     
  5. flyingsaucerinvasion

    flyingsaucerinvasion Member

    Joined:
    Jun 20, 2016
    Posts:
    2,169
    If you want image_alpha or draw_set_alpha to have any effect, then just getting the alpha value out of the texture alone is not enough.

    You'll want to add an in_Colour vec4 attribute to the vertex shader. Then, you'll need to pass at least the alpha component of that attribute as a varying variable to the fragment shader. The final alpha should be irgba.a * that_varying_variable (if a float, or that_varying_variable.a if a vec4 rgba).
     
    Xor likes this.
  6. AzureCube

    AzureCube Member

    Joined:
    Aug 16, 2019
    Posts:
    6
    Thank you, that worked perfectly
     

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