HQ4X Shader (like in Emulators)

Yo! NekotoArts here, and if I’m honest, I have no idea how actually useful this is.

 

Understanding how RetroArch and stuff are able to do the HQ4X was probably the worst nightmare I’ve had to sit through.

Seriously, take a look at this:

_x0063 = TEX0.xy*TextureSize;
_fp = fract(_x0063);
_a0065 = -5.00000000E-01 + _fp;
_val0065 = vec2(float((_a0065.x > 0.00000000E+00)), float((_a0065.y > 0.00000000E+00)));
_TMP0 = _val0065 - vec2(float((_a0065.x < 0.00000000E+00)), float((_a0065.y < 0.00000000E+00)));
_quad = vec2(float(_TMP0.x), float(_TMP0.y));
_TMP1 = COMPAT_TEXTURE(Texture, TEX0.xy);
_c0069 = TEX0.xy + vec2(VARps.x, VARps.y)*vec2(float(_quad.x), float(_quad.y));
_TMP2 = COMPAT_TEXTURE(Texture, _c0069);
_c0071 = TEX0.xy + vec2(VARps.x, 0.00000000E+00)*vec2(float(_quad.x), float(_quad.y));
_TMP3 = COMPAT_TEXTURE(Texture, _c0071);
_c0073 = TEX0.xy + vec2(0.00000000E+00, VARps.y)*vec2(float(_quad.x), float(_quad.y));

Ye… I have no idea either.

So if the shader has some artifacts… have mercy on me plz.

Shader code
shader_type canvas_item;

/*
Made with a whole lot of nightmare fuel.
Logic's Under Pressure and Bobby Tarantino II Albums was in rotation during
the making process.
Hope you enjoy!

You're auto-friended to me if you're a Logic fan
RattPack all day!
*/

//image mipmap level, for base upscaling
const int ML = 0;

//equality threshold of 2 colors before forming lines
uniform float THRESHOLD = 0.1;

//anti aliasing scaling, smaller value make lines more blurry
uniform float AA_SCALE = 10.0;

//draw diagonal line connecting 2 pixels if within threshold
bool diag(inout vec4 sum, vec2 uv, vec2 p1, vec2 p2, sampler2D iChannel0, float LINE_THICKNESS) {
    vec4 v1 = texelFetch(iChannel0,ivec2(uv+vec2(p1.x,p1.y)),ML),
        v2 = texelFetch(iChannel0,ivec2(uv+vec2(p2.x,p2.y)),ML);
    if (length(v1-v2) < THRESHOLD) {
    	vec2 dir = p2-p1,
            lp = uv-(floor(uv+p1)+.5);
    	dir = normalize(vec2(dir.y,-dir.x));
        float l = clamp((LINE_THICKNESS-dot(lp,dir))*AA_SCALE,0.,1.);
        sum = mix(sum,v1,l);
    	return true;
    }
    return false;
}

void fragment(){
	//line thickness
	float LINE_THICKNESS;
	vec2 ip = UV * (1.0 / TEXTURE_PIXEL_SIZE);
	
	
		//start with nearest pixel as 'background'
		vec4 s = texelFetch(TEXTURE,ivec2(int(ip.x),int(ip.y)),ML);
		
		//draw anti aliased diagonal lines of surrounding pixels as 'foreground'
		LINE_THICKNESS = 0.4;
		if (diag(s,ip,vec2(-1,0),vec2(0,1), TEXTURE, LINE_THICKNESS)) {
			LINE_THICKNESS = 0.3;
			diag(s,ip,vec2(-1,0),vec2(1,1), TEXTURE, LINE_THICKNESS);
			diag(s,ip,vec2(-1,-1),vec2(0,1), TEXTURE, LINE_THICKNESS);
		}
		LINE_THICKNESS = 0.4;
		if (diag(s,ip,vec2(0,1),vec2(1,0), TEXTURE, LINE_THICKNESS)) {
			LINE_THICKNESS = 0.3;
			diag(s,ip,vec2(0,1),vec2(1,-1), TEXTURE, LINE_THICKNESS);
			diag(s,ip,vec2(-1,1),vec2(1,0), TEXTURE, LINE_THICKNESS);
		}
		LINE_THICKNESS = 0.4;
		if (diag(s,ip,vec2(1,0),vec2(0,-1), TEXTURE, LINE_THICKNESS)) {
			LINE_THICKNESS = 0.3;
			diag(s,ip,vec2(1,0),vec2(-1,-1), TEXTURE, LINE_THICKNESS);
			diag(s,ip,vec2(1,1),vec2(0,-1), TEXTURE, LINE_THICKNESS);
		}
		LINE_THICKNESS = 0.4;
		if (diag(s,ip,vec2(0,-1),vec2(-1,0), TEXTURE, LINE_THICKNESS)) {
			LINE_THICKNESS = 0.3;
			diag(s,ip,vec2(0,-1),vec2(-1,1), TEXTURE, LINE_THICKNESS);
			diag(s,ip,vec2(1,-1),vec2(-1,0), TEXTURE, LINE_THICKNESS);
		}
		
		COLOR = s;
}
Tags
hq4x, hqx, upscale, upscaling
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from NekotoArts

Wind Waker Water – NO Textures needed!

Daruk’s Protection Shader!

TRUE BoTW Toon Shader!

Related shaders

Earthbound-like battle background shader w/scroll effect and palette cycling

2D Hologram Shader

Half-Tone Comic Shader

guest
0 Comments
Inline Feedbacks
View all comments