Skip to content

Instantly share code, notes, and snippets.

@Skaruts
Last active February 6, 2022 17:47
Show Gist options
  • Save Skaruts/9f4c3e15a2e78867ffd9ad25f2e504cf to your computer and use it in GitHub Desktop.
Save Skaruts/9f4c3e15a2e78867ffd9ad25f2e504cf to your computer and use it in GitHub Desktop.
terminal emulator shader (for love2d)
const vec3 WHITE = vec3(1.0);
const vec3 BLACK = vec3(0.0);
uniform vec2 grid_size = vec2(80.0, 50.0); // size of the terminal grid
uniform vec2 tileset_size = vec2(16.0, 16.0); // size of the font image or tileset image
uniform float cw = 20.0; // cell width
uniform float ch = 20.0; // cell height
uniform Image tileset; // the bitmap font image or tileset image
uniform Image bg_tex; // background grid colors (textures with the same size as the grid (e.g. 80x50))
uniform Image fg_tex; // foreground grid colors
uniform Image chr_tex; // glyph values in the red channel
vec4 effect(vec4 color, Image TEXTURE, vec2 UV, vec2 SCREEN_UV) {
vec4 COLOR = color;
// get tileset size in pixels
vec2 ts_img_size = vec2(tileset_size.x*cw, tileset_size.y*ch);
vec2 canvas_size = vec2(grid_size.x*cw, grid_size.y*ch);
// get the glyph value (stored in the red channel), and scale it to 0-255
float g = Texel(chr_tex, UV).r * 255.0;
// get the glyph uv coords on the tileset, in pixels (normalized)
vec2 guv = vec2(
floor(mod(g, 16.0)) / ts_img_size.x * cw,
floor(g/16.0) / ts_img_size.y * ch
);
// Get the pixel offset from the UV, to add to the 'guv' (the glyph's uv coords).
// (For each cell there's a 'cw*ch' amount of pixels. This determines which pixel
// we're at in the current cell.)
vec2 ofs = vec2(
mod(UV.x*canvas_size.x, cw) / ts_img_size.x,
mod(UV.y*canvas_size.y, ch) / ts_img_size.y
);
// Get the color at the glyph's coords IN THE TILESET, offset to the current pixel in the tile
vec4 px_col = Texel(tileset, guv+ofs);
// If 'px_col' is white, that means this pixel belongs to the glyph,
// otherwise this pixel is from the space around the glyph.
// If white, use fg color, else use bg color
COLOR = px_col.rgb != BLACK // I actually inverted this check, because my terminal ensures all fonts have a black background
? Texel(fg_tex, UV) // before using them. You could switch this around to check for WHITE pixels instead, if the
: Texel(bg_tex, UV); // terminal supports font images with arbitrary non-black backgrounds (transparent, pink, etc).
return COLOR;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment