How to properly grey scale your game in GameMaker
(Or with anything that uses Shaders)

grey scale sprite in gamemaker

Now I’m not saying any of these are the right or wrong way to do greyscale because they all have a slightly different style, however I’m absolutely telling you Relative Luminance is the correct one to use so we will start with that.

Relative Luminance

This is similar to how programs like GIMP desaturate their images and it takes into account how many cones our eyes have to see each colour and adjusts accordingly.

vec4 this_colour = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord ); 
float new_colour = dot(this_colour.rgb, vec3(0.2126, 0.7152, 0.0722 ));
gl_FragColor = vec4(new_colour,new_colour,new_colour,1.0);
	

Code Explanation; The first line gets the current colour of the pixel. The second line finds the Dot Product of the current colour against how humans are able to see each colour channel. The last line puts this new value into all the channels and returns this as the colour we want to draw.

In Review; Relative Luminance uses darker darks and lighter lights so everything has far more contrast. In the examples I have tried it produces the darkest images relative to the other demos on this page, however this will change depending on your game (if you have a game with lots of different vivid colours those will come out as very different shades of grey)

visible colour spectrum vs rgb
Average Colour
vec4 this_colour = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord ); 
float new_colour = (this_colour.r+this_colour.g+this_colour.b)/3.0;
gl_FragColor = vec4(new_colour,new_colour,new_colour,1.0);
	

Code Explanation; The first line gets the current colour of the pixel. The second line finds the average value of the red, green and blue channels. The last line puts this new value into all the channels and returns this as the colour we want to draw.

In Review; This is likely to make colours on the same channel look more distinct, for example if your game uses lots of green grass and trees it will make the variation in those shades stark and look more detailed.

Max Colour
vec4 this_colour = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord ); 
float new_colour = max(this_colour.r,max(this_colour.g,this_colour.b));
gl_FragColor = vec4(new_colour,new_colour,new_colour,1.0);
	

Code Explanation; The first line gets the current colour of the pixel. The second line finds the maximum value of the red, green and blue channels. The last line puts this new value into all the channels and returns this as the colour we want to draw.

In Review; There are likely to be very few case where this is the best one to use, however if you have a game with a very dark palette or a retro game that uses a lot of pure black it will maintain those intense changes.

Average of the Min and Max
vec4 this_colour = v_vColour * texture2D( gm_BaseTexture, v_vTexcoord ); 
float new_colour = (max(this_colour.r, max(this_colour.g, this_colour.b)) 
		  + min(this_colour.r, min(this_colour.g, this_colour.b)) ) / 2.0 ;
gl_FragColor = vec4(new_colour,new_colour,new_colour,1.0);
	

Code Explanation; The first line gets the current colour of the pixel. The second and third lines take the maximum RGB value and the minimum RGB value and finds the mid point. The last line puts this new value into all the channels and returns this as the colour we want to draw.

In Review; This one is slightly better at preserving the white and black areas than a basic average and is more likely to show the difference between colours. However it's a little less likely to keep the true colour because it drops the information about the colour channel in between the brightest and darkest.

Medium Difficulty
Shaders
By David Strachan