Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 2 FirstFirst 12
Results 11 to 19 of 19

Thread: simple CGA shader

  1. #11
    Junior Member Newbie
    Join Date
    Aug 2016
    Posts
    13
    thank you so much
    the shader works pretty well

    I have just another question about it:

    how to leave all the alpha information??
    (take every pixel that have an alpha < 1 and set it to 0)
    (or <= 0.5 and set it to 0 and > 0.5 and set it to 1) //maybe this a better choice, I don't know

    searching for answers I found also this:
    https://www.shadertoy.com/view/4dXXzl#

    I really like it also if it force the pixel with the dithering that I don't like so much

    I noticed here there is no vertex and fragment separation, so I want to ask you, why??

    is it shadertoy a good tool to excercise myself with glsl??
    how it works??
    what do you think about??

    and if you think it is not a good way to learn, what do you use??
    how to write shaders and see the result to excercise myself and better study from the manual??

    thank you so much

  2. #12
    Junior Member Regular Contributor
    Join Date
    May 2016
    Posts
    112
    You said you are using GameMaker? Is this 3D or 2D? I don't think Game Maker does 3D.

    So, you probably don't want a vertex shader. You're probably intending to do straight pixel shading. (Called a fragment shader in GLSL.) If it's 3D I can tell you what you need to do. With 2D, not as much.

    However, all a fragment/pixel shader does is determine the color of the pixel. The pixel color data probably is coming in as 4 floating point values from 0 to 1. that's 0% to 100% of each color. Those are RGBA values, which stands for the 3 primary colors that make up all the colors we can see: red, green, and blue. A is for Alpha which is not a color but the transparency, which you probably have figured out.

    So, your pixel shader can take whatever data it receives to make decisions on what to do, but it's output is always just the color of it's pixel and the alpha value (because blending for transparency happens after this stage and the more transparent it is the more you will see what is behind it). You can alter the alpha value in your shader. So for example, if the texture has an alpha value of .73 for that pixel, you could change anything less than 1.0 to be 0.0. That would change the .73 value to .0 and be fully transparent instead of the potentially 73% transparent in the texture.

    Controlling the alpha value in the texture itself requires going into Photoshop, or whatever program you use, and setting it. First, to do that, it has to have an alpha channel, which may or may not be the case.

  3. #13
    Junior Member Newbie
    Join Date
    Aug 2016
    Posts
    13
    Yes I use Game Maker which gives me a good and easy way to write shaders with vertex and fragment shader
    and yes game maker allows 3D, but I'm focusing on 2D (using 3D in game maker is really possible but also really hard if you are not a good programmer, if you are you can achieve also a good level of realism)

    https://www.youtube.com/watch?v=SsjSNThqiY4

    I found also shadertoy on the web which gives me an exemple from other people to learn writing shaders

    and a tutorial online to use opengl on the web canvas but it's very complicated

    anyway, I make games and for now game maker is a great tool for me, when I will study vertex shader probably I will pass to unity and unreal which I already know how to use, there are also great courses about writing shaders in maya

    for what about photoshop I know very well how to change alpha values

    my problem is very different:
    for sure about sprites that I use inside the game I will use an image editor as photoshop

    I'm also going to use particle effects in game maker, and you can set almost everything, but the particles have a birth, life and death
    game maker manage them using antialiasing and alpha, it is not mean to be used for old retrostyle pixel games (if you want to give them next gen mechanics)
    I cannot use a prerendered particle effects, because it have to randomize

    so I have anyway to force the alpha by shader

  4. #14
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,925
    Quote Originally Posted by Heavybrush View Post
    so I have anyway to force the alpha by shader
    You can force the alpha to 0 or 1 with e.g.
    Code :
    gl_FragColor = vec4(rgb, rgba.a < 0.5 ? 0.0 : 1.0);
    Or you can explicitly discard fragments which would have zero alpha with e.g.:
    Code :
    if (rgba.a < 0.5)
        discard;
    gl_FragColor = vec4(rgb, 1.0);
    If depth buffering is enabled, the former will still update the depth buffer while the latter won't. But that probably isn't an issue for 2D with Game Maker (I'm assuming that it renders from back to front, which is necessary for blending to work correctly).

  5. #15
    Junior Member Newbie
    Join Date
    Aug 2016
    Posts
    13
    yes you are right, game maker draw(render) the objects with a z depth from positive to negative

    the positive values stay back and the negative values come in front
    all the sprites, objects or draw (because you can also draw shapes by code) have an individual alpha

    thank you very much for your support
    I wish continue studying glsl and for sure I will

    If you can advice me to how to learn better and faster it will be very appreciated
    I don't know anything about shaders and I think I will start doing first some exercise from youtube or some courses online, and after I will go deep reading all the manual, I already tried reading all the manual but for me is a little bit complicated, so I think I will start doing some video to have also a visual reference of how things works

    maybe there are some courses better than others or more professional, maybe there are some better for vertex shader and other better for fragment shader
    if you know something about how to start and how to keep going I will try to take your advice

    thank you for all

  6. #16
    Junior Member Newbie
    Join Date
    Aug 2016
    Posts
    13
    Hello, I'm sorry to reopen the thread but I need to change this shader
    maybe you can help me

    I have to change it to swap the palette also if the application surface is not close to it
    secondary, I have to render it dynamic (maybe using an uniform variable) because it have to change the palette

    and if it possible, can you better comment this code, to let me understand better every step and give an help to this question?

    please help me
    thank you so much

    here the code:

    Code :
    ///CGA Shader
    varying vec2 v_vTexcoord; //xy
    varying vec4 v_vColour; //rgba
     
    #define _ 0.0
    #define o (1./3.)
    #define b (2./3.)
    #define B 1.0
     
    #define check(r,g,b) color=vec4(r,g,b,0.); dist = distance(sample,color); if (dist < bestDistance) {bestDistance = dist; bestColor = color;}
     
    void main(out vec4 v_vColour, in vec2 v_vTexcoord)
    {
        float dist;
        float bestDistance = 1000.;
        vec4 color;
        vec4 bestColor;
     
        vec2 pixel = vec2(320,200)-floor( v_vTexcoord.xy / iResolution.xy * vec2(320,200));
        vec4 sample = texture2D(iChannel0, pixel / vec2(320,200));
     
        sample += (texture2D(iChannel1, pixel / iChannelResolution[1].xy)-0.5)*0.5;
     
        // pallete 0
     
        check(_,_,_);
        check(o,B,o);
        check(B,o,o);
        check(B,B,o);
     
        vec4 color1 = bestColor;
        bestDistance = 1000.;
     
        // pallete 1
     
        check(_,_,_);
        check(o,B,B);
        check(B,o,B);
        check(B,B,B);
     
        vec4 color2 = bestColor;
     
        float t = (clamp(sin(iGlobalTime)*4.,-1.,1.)+1.)/2.;
     
        v_vColour = mix(color2, color1, t);
     
        gl_FragColor = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
    }

    an exemple to how to render dynamic a shader in game maker is this:
    here is the shader and how to manipulate it
    the shader is a pixel shader and can be manipulated to change the size of the pixels
    I have to change the cga colors of the palette

    Code :
    //-----------------------------------------------------------------
    //------- PIXELATED SHADER V2--------------------------------------
    //-----------------------------------------------------------------
     
    //fragment
     
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;
     
    uniform vec2 size; //the actual size in pixels
    uniform float pixelSize;
     
    void main()
    {
        vec2 realTexPos = v_vTexcoord * size;
        vec2 floorTexPos = floor(realTexPos / pixelSize) * pixelSize;
        vec2 texPos = floorTexPos / size; //la nuova posizione dei pixel
        gl_FragColor = v_vColour * texture2D( gm_BaseTexture, texPos );
    }

    this is the code of the object to disable the surface and set the shader:

    Code :
    //object
    //create event
     
    ///disable application surface
    application_surface_draw_enable(false);
    pixelSize = 10; //set pixelSize to 10
     
    //draw gui end event
     
    ///draw application surface
    if(shader_is_compiled(shader)) { 
        shader_set(shader);
        var s = shader_get_uniform(shader,"size"); 
        shader_set_uniform_f(s,surface_get_width(application_surface),surface_get_height(application_surface)); 
        var ps = shader_get_uniform(shader,"pixelSize"); 
        shader_set_uniform_f(ps,pixelSize); 
        draw_surface(application_surface,0,0);
        shader_reset(); 
    }
    else {
        draw_surface(application_surface,0,0);
    }

    this is the code to manipulate it:

    Code :
    //step event
     
    ///position in base of the mouse
    x = mouse_x;
    y = mouse_y;
    if(mouse_wheel_up()) { 
        pixelSize++; 
    }
    if(mouse_wheel_down()) { 
        pixelSize = max(1, pixelSize - 1);
    }
    Last edited by Heavybrush; 09-24-2016 at 06:29 AM.

  7. #17
    Intern Contributor
    Join Date
    Sep 2014
    Posts
    53
    It doesn't work well
    It gives me a compiler error

  8. #18
    Junior Member Newbie
    Join Date
    Aug 2016
    Posts
    13
    yes you are right, i'm sorry
    I used the wrong shader

    the shader is this:

    Code :
    ///CGA Shader
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;
     
    const mat3 rgb_to_wcm = mat3(1,-1, 0,  1, 0,-1, -1, 1, 1);
     
    void main()
    {
        vec4 rgba = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
        vec3 wcm = rgb_to_wcm * rgba.rgb;
        vec3 rgb = dot(wcm,vec3(1,1,1)) < 0.5
            ? vec3(0,0,0)
            : wcm.x > wcm.y
                ? (wcm.x > wcm.z ? vec3(1,1,1) : vec3(1,0,1))
                : (wcm.y > wcm.z ? vec3(0,1,1) : vec3(1,0,1));
        if (rgba.a < 0.9) discard;
        gl_FragColor = vec4(rgb, rgba.a);
    }

  9. #19
    Member Regular Contributor
    Join Date
    Jan 2011
    Location
    Paris, France
    Posts
    281
    This can perhaps to be handled by a transformation of RGBA components via a vec4 to ivec4 reduction/conversion followed by another transformation from this ivec4 to a final vec4 conversion/expansion, with something like this code ?

    Code :
    /// CGA Shader
     
    varying vec4 v_vColour;
    varying vec2 v_vTexcoord; 
     
    void main()
    {
        vec4 srccolor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
     
        vec4 reduced = srccolor / 127.0;
     
        ivec4 converted = reduced;
     
        ivec4 expanded = converted * 127;
     
        gl_FragColor = expanded;
    }

    I have not tested this code, so the value of 127 is perhaps not the good value
    (I have initially used values of 64 or 85 but CGA colors use only one bit per color component, not 2 bits)

    I think that the greaterThan vector function can too be used for to handle the reduction/conversion/expansion steps, like this more little code :

    Code :
    /// CGA Shader (set gl_FragColor to the CGA reduction of v_vColor)
     
    varying vec4 v_vColour;
    varying vec2 v_vTexcoord; 
     
    void main()
    {
        vec4 srcColor = v_vColour * texture2D(gm_BaseTexture, v_vTexcoord);
     
        bvec4 cgaed = greaterThan(srcColor, vec4(0.5f));
     
        gl_FragColor = cgaed;
    }
    (a threshold color can to be used instead the vec4(0.5f) if you want to handle a different threshold than 0.5f for each RGBA component)
    Last edited by The Little Body; 10-03-2016 at 03:57 PM.
    @+
    Yannoo

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •