I Need Ideas

I am looking for fresh, out-of-the-box retro shader ideas to implement.

Please keep suggestions completely away from :

  • CRT emulations, scanlines, or shadow/aperture masks.
  • Over-smoothing, blurring, or vectorizing effects.
  • Anti-aliasing or de-dithering (keeping the jagged, raw pixel aesthetic is preferred).

Looking for unique artistic styles, experimental graphic concepts, or alternative visual effects that can be brought to life through code. What are your ideas?

If I read it well, you wanna be the one to implement someone else vision never seen before?

I suggest looking into some artistic/transformative image and film editing techniques and make shaders for them. Just yesterday I got this request for a hue isolation technique: https://github.com/libretro/common-shaders/issues/172

EDIT: we can always use different deinterlacing techniques, different kinds of motionblur and anti-aliasing.

2 Likes

People make pixel art using embroidery (e.g. Dig Dug Arcade Cabinet Screen Cross Stitch and Making Pixel-Art Machine Embroidery).

Why not produce a shader that makes games look like they’ve been embroidered?

2 Likes

Thank you for the great idea! As someone who deeply loves hand sewing and stitches, I truly appreciate your suggestion, and I’ll start thinking about how to implement it.

EDIT: Thinking about how to approach an embroidery shader it’s definitely an interesting challenge! The core approach would likely involve breaking the image down into a cross-stitch grid, applying a procedural woven fabric base, and using a directional pseudo-normal map to give individual threads that physical raised texture and light sheen

Thank you so much for your help and contribution! Since I’ve just finished working on the Noir, Gothic, and analog film shaders, I’m thinking of working on a really cool Color Pop shader next based on your suggestion.

EDIT: Implementing a Color Pop shader isn’t necessarily a walk in the park, but the core logic is manageable. It requires a calculated approach to selective desaturation—isolating the red channel using precise hue and threshold parameters—and optionally layering a subtle, understated bloom or halation to tie the aesthetic together.

EDIT2: This is a simple experimental color pop shader.

#version 110

#pragma parameter key_r         "Key Color R"          1.00 0.00 1.00 0.02
#pragma parameter key_g         "Key Color G"          0.00 0.00 1.00 0.02
#pragma parameter key_b         "Key Color B"          0.00 0.00 1.00 0.02
#pragma parameter hue_range     "Hue Tolerance"        0.08 0.01 0.50 0.01
#pragma parameter edge_soft     "Edge Softness"        0.05 0.00 0.30 0.01
#pragma parameter min_saturation "Min Pixel Saturation" 0.15 0.00 1.00 0.05
#pragma parameter bw_contrast    "Grayscale Contrast"   1.00 0.50 2.00 0.05

#if defined(VERTEX)

attribute vec4 VertexCoord;
attribute vec2 TexCoord;
varying vec2 uv;
uniform mat4 MVPMatrix;

void main()
{
    uv = TexCoord;
    gl_Position = MVPMatrix * VertexCoord;
}

#elif defined(FRAGMENT)

#ifdef GL_ES
precision highp float;
#endif

varying vec2 uv;
uniform sampler2D Texture;
uniform vec2 TextureSize, InputSize;

#ifdef PARAMETER_UNIFORM
uniform float key_r;
uniform float key_g;
uniform float key_b;
uniform float hue_range;
uniform float edge_soft;
uniform float min_saturation;
uniform float bw_contrast;
#else
#define key_r          1.00
#define key_g          0.00
#define key_b          0.00
#define hue_range      0.08
#define edge_soft      0.05
#define min_saturation 0.15
#define bw_contrast    1.00
#endif

vec3 rgb2hsv(vec3 c)
{
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
    vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

void main()
{
    vec3 res = texture2D(Texture, uv).rgb;

    // Convert current and target colors to HSV
    vec3 hsv    = rgb2hsv(res);
    vec3 keyHsv = rgb2hsv(vec3(key_r, key_g, key_b));

    // Distance between colors in Hue (accounting for 0..1 circle wrap)
    float hueDist = abs(hsv.x - keyHsv.x);
    hueDist = min(hueDist, 1.0 - hueDist);

    // Mask: close to target color = 1 (keep color), far = 0 (grayscale)
    float hueMask = 1.0 - smoothstep(hue_range, hue_range + edge_soft, hueDist);

    // Ensure the pixel is actually colored (not neutral gray/white/black)
    float satMask = smoothstep(min_saturation - 0.05, min_saturation + 0.05, hsv.y);

    float mask = hueMask * satMask;

    // Grayscale version
    float luma = dot(res, vec3(0.299, 0.587, 0.114));
    vec3 gray = vec3(luma);
    gray = clamp((gray - 0.5) * bw_contrast + 0.5, 0.0, 1.0);

    vec3 finalColor = mix(gray, res, mask);

    gl_FragColor = vec4(clamp(finalColor, 0.0, 1.0), 1.0);
}
#endif

1 Like

Yes, exactly! I am simply looking for fresh concepts to bring to life. What is the issue with asking for ideas, or with us contributing and helping each other out? The whole point of a community is collaboration. Some people have amazing artistic visions but might not have the time or means to implement them, and I’d love to help make those ideas a reality for everyone to enjoy

1 Like

I don’t know, is there an issue? You got me somehow wrong :wink:

2 Likes