Skip to content

Instantly share code, notes, and snippets.

@Lucrecious
Created July 19, 2022 23:51
Show Gist options
  • Save Lucrecious/bb2a53587bd36be6b150fd6298d680bf to your computer and use it in GitHub Desktop.
Save Lucrecious/bb2a53587bd36be6b150fd6298d680bf to your computer and use it in GitHub Desktop.
A Fast Rot-Sprite shader based on Scale3x
shader_type canvas_item;
const vec4 background = vec4(1., 1., 1., 0.);
float dist(vec4 c1, vec4 c2) {
return (c1 == c2) ? 0.0 : abs(c1.r - c2.r) + abs(c1.g - c2.g) + abs(c1.b - c2.b);
}
bool similar(vec4 c1, vec4 c2, vec4 input) {
return (c1 == c2 || (dist(c1, c2) <= dist(input, c2) && dist(c1, c2) <= dist(input, c1)));
}
bool different(vec4 c1, vec4 c2, vec4 input) {
return !similar(c1, c2, input);
}
// rotsprite 2x enlargement algorithm:
// suppose we are looking at input pixel cE which is surrounded by 8 other
// pixels:
// cA cB cC
// cD cE cF
// cG cH cI
// and for that 1 input pixel cE we want to output 4 pixels oA, oB, oC, and oD:
// oA oB
// oC oD
vec4 scale2x(sampler2D tex, vec2 uv, vec2 pixel_size) {
vec4 input = texture(tex, uv);
vec4 cD = texture(tex, uv + pixel_size * vec2(-1., .0));
cD.a = 1.0;
vec4 cF = texture(tex, uv + pixel_size * vec2(1., .0));
cF.a = 1.0;
vec4 cH = texture(tex, uv + pixel_size * vec2(.0, 1.));
cH.a = 1.0;
vec4 cB = texture(tex, uv + pixel_size * vec2(.0, -1.));
cB.a = 1.0;
vec4 cA = texture(tex, uv + pixel_size * vec2(-1., -1.));
cA.a = 1.0;
vec4 cI = texture(tex, uv + pixel_size * vec2(1., 1.));
cI.a = 1.0;
vec4 cG = texture(tex, uv + pixel_size * vec2(-1., 1.));
cG.a = 1.0;
vec4 cC = texture(tex, uv + pixel_size * vec2(1., -1.));
cC.a = 1.0;
if (different(cD,cF, input)
&& different(cH,cB, input)
&& ((similar(input, cD, input) || similar(input, cH, input) || similar(input, cF, input) || similar(input, cB, input) ||
((different(cA, cI, input) || similar(input, cG, input) || similar(input, cC, input)) &&
(different(cG, cC, input) || similar(input, cA, input) || similar(input, cI, input))))))
{
vec2 unit = uv - (floor(uv / pixel_size) * pixel_size);
vec2 pixel_half_size = pixel_size / 2.0;
if (unit.x < pixel_half_size.x && unit.y < pixel_half_size.y) {
return ((similar(cB, cD, input) && ((different(input, cA, input) || different(cB, background, input)) && (different(input, cA, input) || different(input, cI, input) || different(cB, cC, input) || different(cD, cG, input)))) ? cB : input);
}
if (unit.x >= pixel_half_size.x && unit.y < pixel_half_size.y) {
return ((similar(cF, cB, input) && ((different(input, cC, input) || different(cF, background, input)) && (different(input, cC, input) || different(input, cG, input) || different(cF, cI, input) || different(cB, cA, input)))) ? cF : input);
}
if (unit.x < pixel_half_size.x && unit.y >= pixel_half_size.y) {
return ((similar(cD, cH, input) && ((different(input, cG, input) || different(cD, background, input)) && (different(input, cG, input) || different(input, cC, input) || different(cD, cA, input) || different(cH, cI, input)))) ? cD : input);
}
return ((similar(cH, cF, input) && ((different(input, cI, input) || different(cH, background, input)) && (different(input, cI, input) || different(input, cA, input) || different(cH, cG, input) || different(cF, cC, input)))) ? cH : input);
}
return input;
}
void fragment() {
COLOR = scale2x(TEXTURE, UV, TEXTURE_PIXEL_SIZE);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment