Analog Monochrome Monitor
My attempt at translating this photoshop effect by TextureLabs in Godot.
I recommend downloading the “Soft Pixel Pattern Tile” on their website and use that as the Tiled Texture in the Shader Parameters. Alternatively, you could make your own.
It’s missing a few features like ghosting, for which I recommend this bloom shader by Zylann in the Godot Forums.
UPDATE: Added a new option to change the background color, it will be black by default.
Shader code
shader_type canvas_item;
// texture to be used as "pixels"
uniform sampler2D tiledtexture: repeat_enable, filter_linear_mipmap;
// how much of the tiled texture to show (1 recommended)
uniform float opacity : hint_range(0.0, 1.0);
// size of pixelation effect
uniform float pixel_size = 0.01;
// whether to greyscale the image or not before applying tiletexture
uniform bool greyscale = true;
// whether to greyscale the image or not before applying tiletexture
uniform float contrast;
// grab the camera's view
uniform sampler2D screen_texture : hint_screen_texture, filter_linear_mipmap;
// the overriding color of the tiled texture, white by default
uniform vec3 pixel_colors : source_color;
// the overriding color of the background, black by default
uniform vec3 background_color : source_color;
// Convert to Greyscale using luminosity method if aplicable
vec4 to_grayscale(vec4 color) {
float luminance = 0.21 * color.r + 0.72 * color.g + 0.07 * color.b;
return vec4(luminance, luminance, luminance, color.a);
}
// Adjust contrast of the greyscale image
vec4 adjust_contrast(vec4 color) {
color.rgb = (color.rgb - 0.5) * max(contrast, 0.0) + 0.5;
return color;
}
// Applies the tiled texture on top of the original texture imitating
// photoshop's HARD MIX blending mode
vec4 hard_mix(vec4 color1, vec4 color2) {
vec4 result; // The resulting texture
for (int i = 0; i < 4; i++) { // loop through the four channels
float value = color1[i] + color2[i]; // add the values of the two colors
if (value >= 1.0) { // if the value is greater than or equal to 1.0, set it to 1.0
result[i] = 1.0;
} else { // otherwise, set it to 0.0
result[i] = 0.0;
}
}
return result; // return the result color
}
// main fragment func
void fragment() {
vec2 uv = SCREEN_UV;
vec2 uv2 = SCREEN_UV;
// apply pixelation on the base texture
uv = floor(uv / pixel_size) * pixel_size;
vec4 color1 = texture(screen_texture, uv);
// apply greyscale adjustments if applicable
if (greyscale) {
color1 = to_grayscale(color1);
color1 = adjust_contrast(color1);
}
// apply hard mix blending
vec4 color2 = texture(tiledtexture, uv2 / pixel_size);
vec4 final_result = mix(color1, hard_mix(color1, color2), opacity);
// replace default white with desired color
if (final_result == vec4(1.0, 1.0, 1.0, 1.0)) {
final_result = vec4(pixel_colors, 1.0);
// replace default black background with desired color
} else {
if (final_result == vec4(0.0, 0.0, 0.0, 1.0)) {
final_result = vec4(background_color, 1.0);
}
}
// assign final texture
COLOR = final_result;
}
Very nice effect. Than you for sharing.
it is not working for me how is it meant to be setup?
Create a color rect, assign this shader and parent it to your camera
Godot doesn’t support Photoshop’s .pat files (at least, I don’t know how to use them in Godot).
To get the suggested patterns you can use Photoshop, Photopea, or GIMP to import the .pat file, create a 100x100px canvas, apply the pattern fill (there are 2 pixel patterns), then save them each as a PNG.
I admit I couldn’t get this working (Godot 4.2.2). I created a ColorRect, assigned this shader, set the ‘Tiledtexture’ to one of the PNGs, and made it a child of an active Camera2D on the scene. Perhaps there is a nuance to setup I didn’t understand.
I gave the wrong instructions to the previous commenter. You should create a CanvasLayer node and add the ColorRect as a child. Then you can add the TiledTexture png, change the ‘pixel color’ parameter to whatever color you want, and increase the contrast.
Here’s the pattern converted to a png in case you need it -> https://imgur.com/Y29SlKt
Thank you so much!