# The Industry's Foundation for High Performance Graphics

#### from games to virtual reality, mobile phones to supercomputers

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

//
//
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. Originally Posted by Heavybrush
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. Originally Posted by GClements
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:

//
//
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;
}

//
//
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

Thank you so much

4. Originally Posted by Heavybrush
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. 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. Originally Posted by Heavybrush
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.

In Shader shd_CGA at line 2 : 'gm_BaseTexture' : redefinition
Compile Failed - Please check the Compile window for any additional information

8. Originally Posted by Heavybrush
'gm_BaseTexture' : redefinition
So remove the declaration of that variable.

9. 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. Originally Posted by Heavybrush
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
•