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 1 of 2 12 LastLast
Results 1 to 10 of 19

Thread: simple CGA shader

  1. #1
    Junior Member Newbie
    Join Date
    Aug 2016
    Posts
    13

    simple CGA shader

    Hi I'm new here and I'm trying to get into shaders
    It's a very fascinating thing, in particular I need it for game development

    I use it in game maker studio professional which allows the using of glsl es language
    and I started reading the hard manual and following a lot of video tutorials online

    actually I'm able to change colors, channel colors of the original color, make an average to draw in grayscale and using the uniform variable to make a bridge from the shader and the object that I need to be drawn with the shader (or everything if I draw the shader to the surface)

    actually I'm developing a game and I woud use this basic skills to write a CGA shader, so I need to limit the colors and set four vec4 to have cyan, magenta, black and white (I would use only this kind of palette and I don't need dithering)

    can you help me??

    I'm using only the fragment shader (my game is a 2D game so I need only this)

    this is what I've written

    //
    // Simple passthrough fragment shader
    //
    varying vec2 v_vTexcoord; //this is the coord xy
    varying vec4 v_vColour; //this is the color space of the original surface

    void main()
    {
    vec4 color1 = vec4(0.0, 1.0, 1.0, 1.0); //magenta
    vec4 color2 = vec4(1.0, 0.0, 1.0, 1.0); //cyan
    vec4 color3 = vec4(1.0, 1.0, 1.0, 1.0); //black
    vec4 color4 = vec4(0.0, 0.0, 0.0, 1.0); //white

    vec4 CGA = vec4(color1,color2,color3,color4); //this doesnt work so well

    gl_FragColor = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
    //this is a variable that take the original color and draw it as it is
    }

    thanks a lot

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,848
    Quote Originally Posted by Heavybrush View Post
    actually I'm developing a game and I woud use this basic skills to write a CGA shader, so I need to limit the colors and set four vec4 to have cyan, magenta, black and white (I would use only this kind of palette and I don't need dithering)

    can you help me??
    First, you'll need to explain the problem more clearly.

    You want a shader where each pixel is converted to one of those four colours, whichever is closest? Or a shader that clamps to the set of colours which could be obtained by mixing them (i.e. as if you dithered to a CGA palette then filtered the result)? Or what?

    In any case, the matrix:
    Code :
    [ 1   1  -1]
    [-1   0   1]
    [ 0  -1   1]
    will transform R,G,B to White,Cyan,Magenta, i.e. [1,1,1]->[1,0,0], [0,1,1]->[0,1,0], [1,0,1]->[0,0,1].

    From there, you can clamp or scale to the volume bounded by those colours (i.e. W+C+M<=1), or find which of the colours are nearest (if W+C+M<1/2, it's black, otherwise it's whichever component has the largest value).

    You can then transform back to R,G,B with
    Code :
    [ 1   0   1]
    [ 1   1   0]
    [ 1   1   1]

  3. #3
    Junior Member Newbie
    Join Date
    Aug 2016
    Posts
    13
    Quote Originally Posted by GClements View Post
    First, you'll need to explain the problem more clearly.

    You want a shader where each pixel is converted to one of those four colours, whichever is closest? Or a shader that clamps to the set of colours which could be obtained by mixing them (i.e. as if you dithered to a CGA palette then filtered the result)? Or what?
    I need the first case, I'm trying to convert all the colors in one of those four colors to limit the palette and change all the original colors closest to one of those

    I'm a very basic user in shaders, can you write me how to write those informations??

    I explane you well, (maybe game maker studio variables are different from usual glsl)

    when I create a new shader in game maker studio I have:

    //this vertex shader

    //
    // Simple passthrough vertex shader
    //
    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;
    }

    //this fragment shader

    //
    // Simple passthrough fragment shader
    //
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;

    void main()
    {
    gl_FragColor = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord );
    }

    the first two variables (I don't know what varying it is) are:

    v_vTexcoord the texture coordinate xy where the shader is drawn
    v_vColour the color rgba

    gl_FragColor return the original color of the application surface
    gm_BaseTexture i think is a game maker variable

    anyway, this is the starting point

    how can I write your cga shader here ??

    Thank you so much

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,848
    Quote Originally Posted by Heavybrush View Post
    I need the first case, I'm trying to convert all the colors in one of those four colors to limit the palette and change all the original colors closest to one of those
    Code :
    uniform sampler2D gm_BaseTexture;
     
    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));
        gl_FragColor = vec4(rgb, rgba.a);
    }

  5. #5
    Junior Member Newbie
    Join Date
    Aug 2016
    Posts
    13
    it doesn't work well
    it gives me a compiler error

    and as I can see it is more complicated that I could imagine

    I really don't understand why it doesn't work

    anyway thanks a lot

  6. #6
    Senior Member OpenGL Pro
    Join Date
    Jan 2007
    Posts
    1,789
    Quote Originally Posted by Heavybrush View Post
    it gives me a compiler error
    You stand a better chance of getting help if you say what the compiler error is. Those error messages exist for a reason: to assist people in diagnosing the cause of the error.

  7. #7
    Junior Member Newbie
    Join Date
    Aug 2016
    Posts
    13
    Reading project file....Error compiling fragment shader:
    In Shader shd_CGA at line 2 : 'gm_BaseTexture' : redefinition
    Compile Failed - Please check the Compile window for any additional information

    It doesn't give additional information

  8. #8
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,848
    Quote Originally Posted by Heavybrush View Post
    'gm_BaseTexture' : redefinition
    So remove the declaration of that variable.

    Game Maker is presumably either adding its own code to the shader or adding its own shader(s) to the program.

  9. #9
    Junior Member Newbie
    Join Date
    Aug 2016
    Posts
    13
    ok I leaved the uniform decalration at start
    now it works, but is only black and white, how to add also the other two?

    now the code is this:

    Code :
    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));
        gl_FragColor = vec4(rgb, rgba.a);
    }

  10. #10
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,848
    Quote Originally Posted by Heavybrush View Post
    now it works, but is only black and white, how to add also the other two?
    Find a scene with more cyan and/or magenta in it, or bias the comparison against white (e.g. use k*wcm.x instead of wcm.x, for some k less than 1).

    Partitioning the RGB colour space according to the closest colour (of black, white, cyan, magenta) results in proportions of 50% black, 20% white, 15% cyan, 15% magenta. Note that cyan and magenta need to be quite saturated to match those primaries rather than black or white. E.g. (1,0.5,1) is on the boundary between white and magenta, while (0.5,1,1) is on the boundary between white and cyan.

Posting Permissions

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