Simplify shaders

This commit is contained in:
Lior Halphon 2018-06-15 18:08:54 +03:00
parent c1fcd1a0c0
commit c6dba26d02
17 changed files with 200 additions and 220 deletions

View File

@ -50,7 +50,7 @@ void main(void) {\n\
// Attributes // Attributes
position_attribute = glGetAttribLocation(program, "aPosition"); position_attribute = glGetAttribLocation(program, "aPosition");
// Uniforms // Uniforms
resolution_uniform = glGetUniformLocation(program, "uResolution"); resolution_uniform = glGetUniformLocation(program, "output_resolution");
glGenTextures(1, &texture); glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture); glBindTexture(GL_TEXTURE_2D, texture);
@ -68,9 +68,9 @@ void main(void) {\n\
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
previous_texture_uniform = glGetUniformLocation(program, "previousImage"); previous_texture_uniform = glGetUniformLocation(program, "previous_image");
mix_previous_uniform = glGetUniformLocation(program, "uMixPrevious"); mix_previous_uniform = glGetUniformLocation(program, "mix_previous");
// Configure OpenGL // Configure OpenGL
[self configureOpenGL]; [self configureOpenGL];

View File

@ -286,7 +286,7 @@ $(BIN)/SDL/background.bmp: SDL/background.bmp
cp -f $^ $@ cp -f $^ $@
$(BIN)/SDL/Shaders: Shaders $(BIN)/SDL/Shaders: Shaders
-@$(MKDIR) -p $(dir $@) -@$(MKDIR) -p $@
cp -rf Shaders/*.fsh $@ cp -rf Shaders/*.fsh $@
# Boot ROMs # Boot ROMs

View File

@ -109,8 +109,8 @@ bool init_shader_with_name(shader_t *shader, const char *name)
// Attributes // Attributes
shader->position_attribute = glGetAttribLocation(shader->program, "aPosition"); shader->position_attribute = glGetAttribLocation(shader->program, "aPosition");
// Uniforms // Uniforms
shader->resolution_uniform = glGetUniformLocation(shader->program, "uResolution"); shader->resolution_uniform = glGetUniformLocation(shader->program, "output_resolution");
shader->origin_uniform = glGetUniformLocation(shader->program, "uOrigin"); shader->origin_uniform = glGetUniformLocation(shader->program, "origin");
glGenTextures(1, &shader->texture); glGenTextures(1, &shader->texture);
glBindTexture(GL_TEXTURE_2D, shader->texture); glBindTexture(GL_TEXTURE_2D, shader->texture);
@ -128,9 +128,9 @@ bool init_shader_with_name(shader_t *shader, const char *name)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
shader->previous_texture_uniform = glGetUniformLocation(shader->program, "previousImage"); shader->previous_texture_uniform = glGetUniformLocation(shader->program, "previous_image");
shader->mix_previous_uniform = glGetUniformLocation(shader->program, "uMixPrevious"); shader->mix_previous_uniform = glGetUniformLocation(shader->program, "mix_previous");
// Program // Program

View File

@ -4,14 +4,14 @@ float quickDistance(vec4 a, vec4 b)
return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z); return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z);
} }
vec4 omniScale(sampler2D image, vec2 texCoord) vec4 omniScale(sampler2D image, vec2 position)
{ {
vec2 pixel = texCoord * textureDimensions - vec2(0.5, 0.5); vec2 pixel = position * input_resolution - vec2(0.5, 0.5);
vec4 q11 = texture(image, (floor(pixel) + 0.5) / textureDimensions); vec4 q11 = texture(image, (floor(pixel) + 0.5) / input_resolution);
vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / textureDimensions); vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / input_resolution);
vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / textureDimensions); vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / input_resolution);
vec4 q22 = texture(image, (ceil(pixel) + 0.5) / textureDimensions); vec4 q22 = texture(image, (ceil(pixel) + 0.5) / input_resolution);
vec2 pos = fract(pixel); vec2 pos = fract(pixel);
@ -25,7 +25,7 @@ vec4 omniScale(sampler2D image, vec2 texCoord)
int diagonalBias = 0; int diagonalBias = 0;
for (float y = -1.0; y < 3.0; y++) { for (float y = -1.0; y < 3.0; y++) {
for (float x = -1.0; x < 3.0; x++) { for (float x = -1.0; x < 3.0; x++) {
vec4 color = texture(image, (pixel + vec2(x, y)) / textureDimensions); vec4 color = texture(image, (pixel + vec2(x, y)) / input_resolution);
if (color == q11) diagonalBias++; if (color == q11) diagonalBias++;
if (color == q12) diagonalBias--; if (color == q12) diagonalBias--;
} }
@ -104,16 +104,15 @@ vec4 omniScale(sampler2D image, vec2 texCoord)
return q22; return q22;
} }
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; vec2 pixel = vec2(1.0, 1.0) / output_resolution;
vec2 pixel = vec2(1.0, 1.0) / uResolution;
// 4-pixel super sampling // 4-pixel super sampling
vec4 q11 = omniScale(image, texCoord + pixel * vec2(-0.25, -0.25)); vec4 q11 = omniScale(image, position + pixel * vec2(-0.25, -0.25));
vec4 q21 = omniScale(image, texCoord + pixel * vec2(+0.25, -0.25)); vec4 q21 = omniScale(image, position + pixel * vec2(+0.25, -0.25));
vec4 q12 = omniScale(image, texCoord + pixel * vec2(-0.25, +0.25)); vec4 q12 = omniScale(image, position + pixel * vec2(-0.25, +0.25));
vec4 q22 = omniScale(image, texCoord + pixel * vec2(+0.25, +0.25)); vec4 q22 = omniScale(image, position + pixel * vec2(+0.25, +0.25));
return (q11 + q21 + q12 + q22) / 4.0; return (q11 + q21 + q12 + q22) / 4.0;
} }

View File

@ -1,23 +1,22 @@
vec4 scale2x(sampler2D image) vec4 scale2x(sampler2D image, vec2 position)
{ {
// o = offset, the width of a pixel // o = offset, the width of a pixel
vec2 o = 1.0 / textureDimensions; vec2 o = 1.0 / input_resolution;
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution;
// texel arrangement // texel arrangement
// A B C // A B C
// D E F // D E F
// G H I // G H I
vec4 A = texture(image, texCoord + vec2( -o.x, o.y)); vec4 A = texture(image, position + vec2( -o.x, o.y));
vec4 B = texture(image, texCoord + vec2( 0, o.y)); vec4 B = texture(image, position + vec2( 0, o.y));
vec4 C = texture(image, texCoord + vec2( o.x, o.y)); vec4 C = texture(image, position + vec2( o.x, o.y));
vec4 D = texture(image, texCoord + vec2( -o.x, 0)); vec4 D = texture(image, position + vec2( -o.x, 0));
vec4 E = texture(image, texCoord + vec2( 0, 0)); vec4 E = texture(image, position + vec2( 0, 0));
vec4 F = texture(image, texCoord + vec2( o.x, 0)); vec4 F = texture(image, position + vec2( o.x, 0));
vec4 G = texture(image, texCoord + vec2( -o.x, -o.y)); vec4 G = texture(image, position + vec2( -o.x, -o.y));
vec4 H = texture(image, texCoord + vec2( 0, -o.y)); vec4 H = texture(image, position + vec2( 0, -o.y));
vec4 I = texture(image, texCoord + vec2( o.x, -o.y)); vec4 I = texture(image, position + vec2( o.x, -o.y));
vec2 p = texCoord * textureDimensions; vec2 p = position * input_resolution;
// p = the position within a pixel [0...1] // p = the position within a pixel [0...1]
p = fract(p); p = fract(p);
if (p.x > .5) { if (p.x > .5) {
@ -39,9 +38,7 @@ vec4 scale2x(sampler2D image)
} }
} }
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; return mix(texture(image, position), scale2x(image, position), 0.5);
return mix(texture(image, texCoord), scale2x(image), 0.5);
} }

View File

@ -1,21 +1,21 @@
vec4 scale2x(sampler2D image, vec2 texCoord) vec4 scale2x(sampler2D image, vec2 position)
{ {
// o = offset, the width of a pixel // o = offset, the width of a pixel
vec2 o = 1.0 / textureDimensions; vec2 o = 1.0 / input_resolution;
// texel arrangement // texel arrangement
// A B C // A B C
// D E F // D E F
// G H I // G H I
vec4 A = texture(image, texCoord + vec2( -o.x, o.y)); vec4 A = texture(image, position + vec2( -o.x, o.y));
vec4 B = texture(image, texCoord + vec2( 0, o.y)); vec4 B = texture(image, position + vec2( 0, o.y));
vec4 C = texture(image, texCoord + vec2( o.x, o.y)); vec4 C = texture(image, position + vec2( o.x, o.y));
vec4 D = texture(image, texCoord + vec2( -o.x, 0)); vec4 D = texture(image, position + vec2( -o.x, 0));
vec4 E = texture(image, texCoord + vec2( 0, 0)); vec4 E = texture(image, position + vec2( 0, 0));
vec4 F = texture(image, texCoord + vec2( o.x, 0)); vec4 F = texture(image, position + vec2( o.x, 0));
vec4 G = texture(image, texCoord + vec2( -o.x, -o.y)); vec4 G = texture(image, position + vec2( -o.x, -o.y));
vec4 H = texture(image, texCoord + vec2( 0, -o.y)); vec4 H = texture(image, position + vec2( 0, -o.y));
vec4 I = texture(image, texCoord + vec2( o.x, -o.y)); vec4 I = texture(image, position + vec2( o.x, -o.y));
vec2 p = texCoord * textureDimensions; vec2 p = position * input_resolution;
// p = the position within a pixel [0...1] // p = the position within a pixel [0...1]
p = fract(p); p = fract(p);
if (p.x > .5) { if (p.x > .5) {
@ -37,32 +37,31 @@ vec4 scale2x(sampler2D image, vec2 texCoord)
} }
} }
vec4 aaScale2x(sampler2D image, vec2 texCoord) vec4 aaScale2x(sampler2D image, vec2 position)
{ {
return mix(texture(image, texCoord), scale2x(image, texCoord), 0.5); return mix(texture(image, position), scale2x(image, position), 0.5);
} }
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
// o = offset, the width of a pixel // o = offset, the width of a pixel
vec2 o = 1.0 / (textureDimensions * 2.); vec2 o = 1.0 / (input_resolution * 2.);
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution;
// texel arrangement // texel arrangement
// A B C // A B C
// D E F // D E F
// G H I // G H I
vec4 A = aaScale2x(image, texCoord + vec2( -o.x, o.y)); vec4 A = aaScale2x(image, position + vec2( -o.x, o.y));
vec4 B = aaScale2x(image, texCoord + vec2( 0, o.y)); vec4 B = aaScale2x(image, position + vec2( 0, o.y));
vec4 C = aaScale2x(image, texCoord + vec2( o.x, o.y)); vec4 C = aaScale2x(image, position + vec2( o.x, o.y));
vec4 D = aaScale2x(image, texCoord + vec2( -o.x, 0)); vec4 D = aaScale2x(image, position + vec2( -o.x, 0));
vec4 E = aaScale2x(image, texCoord + vec2( 0, 0)); vec4 E = aaScale2x(image, position + vec2( 0, 0));
vec4 F = aaScale2x(image, texCoord + vec2( o.x, 0)); vec4 F = aaScale2x(image, position + vec2( o.x, 0));
vec4 G = aaScale2x(image, texCoord + vec2( -o.x, -o.y)); vec4 G = aaScale2x(image, position + vec2( -o.x, -o.y));
vec4 H = aaScale2x(image, texCoord + vec2( 0, -o.y)); vec4 H = aaScale2x(image, position + vec2( 0, -o.y));
vec4 I = aaScale2x(image, texCoord + vec2( o.x, -o.y)); vec4 I = aaScale2x(image, position + vec2( o.x, -o.y));
vec4 R; vec4 R;
vec2 p = texCoord * textureDimensions * 2.; vec2 p = position * input_resolution * 2.;
// p = the position within a pixel [0...1] // p = the position within a pixel [0...1]
p = fract(p); p = fract(p);
if (p.x > .5) { if (p.x > .5) {

View File

@ -1,13 +1,11 @@
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; vec2 pixel = position * input_resolution - vec2(0.5, 0.5);
vec2 pixel = texCoord * textureDimensions - vec2(0.5, 0.5); vec4 q11 = texture(image, (floor(pixel) + 0.5) / input_resolution);
vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / input_resolution);
vec4 q11 = texture(image, (floor(pixel) + 0.5) / textureDimensions); vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / input_resolution);
vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / textureDimensions); vec4 q22 = texture(image, (ceil(pixel) + 0.5) / input_resolution);
vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / textureDimensions);
vec4 q22 = texture(image, (ceil(pixel) + 0.5) / textureDimensions);
vec4 r1 = mix(q11, q21, fract(pixel.x)); vec4 r1 = mix(q11, q21, fract(pixel.x));
vec4 r2 = mix(q12, q22, fract(pixel.x)); vec4 r2 = mix(q12, q22, fract(pixel.x));

View File

@ -27,31 +27,30 @@ vec4 interp_3px(vec4 c1, float w1, vec4 c2, float w2, vec4 c3, float w3)
return (c1 * w1 + c2 * w2 + c3 * w3) / (w1 + w2 + w3); return (c1 * w1 + c2 * w2 + c3 * w3) / (w1 + w2 + w3);
} }
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
// o = offset, the width of a pixel // o = offset, the width of a pixel
vec2 o = 1.0 / textureDimensions; vec2 o = 1.0 / input_resolution;
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution;
/* We always calculate the top left pixel. If we need a different pixel, we flip the image */ /* We always calculate the top left pixel. If we need a different pixel, we flip the image */
// p = the position within a pixel [0...1] // p = the position within a pixel [0...1]
vec2 p = fract(texCoord * textureDimensions); vec2 p = fract(position * input_resolution);
if (p.x > 0.5) o.x = -o.x; if (p.x > 0.5) o.x = -o.x;
if (p.y > 0.5) o.y = -o.y; if (p.y > 0.5) o.y = -o.y;
vec4 w0 = texture(image, texCoord + vec2( -o.x, -o.y)); vec4 w0 = texture(image, position + vec2( -o.x, -o.y));
vec4 w1 = texture(image, texCoord + vec2( 0, -o.y)); vec4 w1 = texture(image, position + vec2( 0, -o.y));
vec4 w2 = texture(image, texCoord + vec2( o.x, -o.y)); vec4 w2 = texture(image, position + vec2( o.x, -o.y));
vec4 w3 = texture(image, texCoord + vec2( -o.x, 0)); vec4 w3 = texture(image, position + vec2( -o.x, 0));
vec4 w4 = texture(image, texCoord + vec2( 0, 0)); vec4 w4 = texture(image, position + vec2( 0, 0));
vec4 w5 = texture(image, texCoord + vec2( o.x, 0)); vec4 w5 = texture(image, position + vec2( o.x, 0));
vec4 w6 = texture(image, texCoord + vec2( -o.x, o.y)); vec4 w6 = texture(image, position + vec2( -o.x, o.y));
vec4 w7 = texture(image, texCoord + vec2( 0, o.y)); vec4 w7 = texture(image, position + vec2( 0, o.y));
vec4 w8 = texture(image, texCoord + vec2( o.x, o.y)); vec4 w8 = texture(image, position + vec2( o.x, o.y));
int pattern = 0; int pattern = 0;
if (is_different(w0, w4)) pattern |= 1; if (is_different(w0, w4)) pattern |= 1;

View File

@ -2,29 +2,27 @@
#define COLOR_HIGH 1.0 #define COLOR_HIGH 1.0
#define SCANLINE_DEPTH 0.1 #define SCANLINE_DEPTH 0.1
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; vec2 pos = fract(position * input_resolution);
vec2 sub_pos = fract(position * input_resolution * 6);
vec2 pos = fract(texCoord * textureDimensions); vec4 center = texture(image, position);
vec2 sub_pos = fract(texCoord * textureDimensions * 6); vec4 left = texture(image, position - vec2(1.0 / input_resolution.x, 0));
vec4 right = texture(image, position + vec2(1.0 / input_resolution.x, 0));
vec4 center = texture(image, texCoord);
vec4 left = texture(image, texCoord - vec2(1.0 / textureDimensions.x, 0));
vec4 right = texture(image, texCoord + vec2(1.0 / textureDimensions.x, 0));
if (pos.y < 1.0 / 6.0) { if (pos.y < 1.0 / 6.0) {
center = mix(center, texture(image, texCoord + vec2(0, -1.0 / textureDimensions.y)), 0.5 - sub_pos.y / 2.0); center = mix(center, texture(image, position + vec2(0, -1.0 / input_resolution.y)), 0.5 - sub_pos.y / 2.0);
left = mix(left, texture(image, texCoord + vec2(-1.0 / textureDimensions.x, -1.0 / textureDimensions.y)), 0.5 - sub_pos.y / 2.0); left = mix(left, texture(image, position + vec2(-1.0 / input_resolution.x, -1.0 / input_resolution.y)), 0.5 - sub_pos.y / 2.0);
right = mix(right, texture(image, texCoord + vec2( 1.0 / textureDimensions.x, -1.0 / textureDimensions.y)), 0.5 - sub_pos.y / 2.0); right = mix(right, texture(image, position + vec2( 1.0 / input_resolution.x, -1.0 / input_resolution.y)), 0.5 - sub_pos.y / 2.0);
center *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); center *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
left *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); left *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
right *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); right *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
} }
else if (pos.y > 5.0 / 6.0) { else if (pos.y > 5.0 / 6.0) {
center = mix(center, texture(image, texCoord + vec2(0, 1.0 / textureDimensions.y)), sub_pos.y / 2.0); center = mix(center, texture(image, position + vec2(0, 1.0 / input_resolution.y)), sub_pos.y / 2.0);
left = mix(left, texture(image, texCoord + vec2(-1.0 / textureDimensions.x, 1.0 / textureDimensions.y)), sub_pos.y / 2.0); left = mix(left, texture(image, position + vec2(-1.0 / input_resolution.x, 1.0 / input_resolution.y)), sub_pos.y / 2.0);
right = mix(right, texture(image, texCoord + vec2( 1.0 / textureDimensions.x, 1.0 / textureDimensions.y)), sub_pos.y / 2.0); right = mix(right, texture(image, position + vec2( 1.0 / input_resolution.x, 1.0 / input_resolution.y)), sub_pos.y / 2.0);
center *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); center *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
left *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); left *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
right *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); right *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);

View File

@ -1,27 +1,28 @@
#version 150 #version 150
uniform sampler2D image; uniform sampler2D image;
uniform sampler2D previousImage; uniform sampler2D previous_image;
uniform bool uMixPrevious; uniform bool mix_previous;
uniform vec2 uResolution; uniform vec2 output_resolution;
uniform vec2 uOrigin; uniform vec2 origin;
const vec2 textureDimensions = vec2(160, 144); const vec2 input_resolution = vec2(160, 144);
out vec4 frag_color; out vec4 frag_color;
vec4 modified_frag_cord; vec4 modified_frag_cord;
#define gl_FragCoord modified_frag_cord
#line 1 #line 1
{filter} {filter}
#undef gl_FragCoord
void main() { void main()
modified_frag_cord = gl_FragCoord - vec4(uOrigin.x, uOrigin.y, 0, 0); {
vec2 position = gl_FragCoord.xy - origin;
position /= output_resolution;
position.y = 1 - position.y;
if (uMixPrevious) { if (mix_previous) {
frag_color = mix(scale(image), scale(previousImage), 0.5); frag_color = mix(scale(image, position), scale(previous_image, position), 0.5);
} }
else { else {
frag_color = scale(image); frag_color = scale(image, position);
} }
} }

View File

@ -3,6 +3,7 @@
#include <metal_math> #include <metal_math>
using namespace metal; using namespace metal;
const float4 input_resolution = float4(160, 144);
/* For GLSL compatibility */ /* For GLSL compatibility */
typedef float2 vec2; typedef float2 vec2;
@ -17,7 +18,6 @@ typedef struct {
// Vertex Function // Vertex Function
vertex rasterizer_data vertex_shader(uint index [[ vertex_id ]], vertex rasterizer_data vertex_shader(uint index [[ vertex_id ]],
constant vector_float2 *vertices [[ buffer(0) ]]) constant vector_float2 *vertices [[ buffer(0) ]])
{ {
rasterizer_data out; rasterizer_data out;

View File

@ -1,6 +1,4 @@
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; return texture(image, position);
return texture(image, texCoord);
} }

View File

@ -24,16 +24,15 @@ bool is_different(vec4 a, vec4 b)
#define P(m, r) ((pattern & (m)) == (r)) #define P(m, r) ((pattern & (m)) == (r))
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
// o = offset, the width of a pixel // o = offset, the width of a pixel
vec2 o = 1.0 / textureDimensions; vec2 o = 1.0 / input_resolution;
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution;
/* We always calculate the top left quarter. If we need a different quarter, we flip our co-ordinates */ /* We always calculate the top left quarter. If we need a different quarter, we flip our co-ordinates */
// p = the position within a pixel [0...1] // p = the position within a pixel [0...1]
vec2 p = fract(texCoord * textureDimensions); vec2 p = fract(position * input_resolution);
if (p.x > 0.5) { if (p.x > 0.5) {
o.x = -o.x; o.x = -o.x;
@ -44,17 +43,15 @@ vec4 scale(sampler2D image)
p.y = 1.0 - p.y; p.y = 1.0 - p.y;
} }
vec4 w0 = texture(image, position + vec2( -o.x, -o.y));
vec4 w1 = texture(image, position + vec2( 0, -o.y));
vec4 w0 = texture(image, texCoord + vec2( -o.x, -o.y)); vec4 w2 = texture(image, position + vec2( o.x, -o.y));
vec4 w1 = texture(image, texCoord + vec2( 0, -o.y)); vec4 w3 = texture(image, position + vec2( -o.x, 0));
vec4 w2 = texture(image, texCoord + vec2( o.x, -o.y)); vec4 w4 = texture(image, position + vec2( 0, 0));
vec4 w3 = texture(image, texCoord + vec2( -o.x, 0)); vec4 w5 = texture(image, position + vec2( o.x, 0));
vec4 w4 = texture(image, texCoord + vec2( 0, 0)); vec4 w6 = texture(image, position + vec2( -o.x, o.y));
vec4 w5 = texture(image, texCoord + vec2( o.x, 0)); vec4 w7 = texture(image, position + vec2( 0, o.y));
vec4 w6 = texture(image, texCoord + vec2( -o.x, o.y)); vec4 w8 = texture(image, position + vec2( o.x, o.y));
vec4 w7 = texture(image, texCoord + vec2( 0, o.y));
vec4 w8 = texture(image, texCoord + vec2( o.x, o.y));
int pattern = 0; int pattern = 0;
if (is_different(w0, w4)) pattern |= 1 << 0; if (is_different(w0, w4)) pattern |= 1 << 0;
@ -83,7 +80,7 @@ vec4 scale(sampler2D image)
return mix(mix(w0 * 0.375 + w3 * 0.25 + w4 * 0.375, w4 * 0.5 + w3 * 0.5, p.y * 2.0), w4, p.x * 2.0); return mix(mix(w0 * 0.375 + w3 * 0.25 + w4 * 0.375, w4 * 0.5 + w3 * 0.5, p.y * 2.0), w4, p.x * 2.0);
if (P(0x2f,0x2f)) { if (P(0x2f,0x2f)) {
float dist = length(p - vec2(0.5)); float dist = length(p - vec2(0.5));
float pixel_size = length(1.0 / (uResolution / textureDimensions)); float pixel_size = length(1.0 / (output_resolution / input_resolution));
if (dist < 0.5 - pixel_size / 2) { if (dist < 0.5 - pixel_size / 2) {
return w4; return w4;
} }
@ -102,7 +99,7 @@ vec4 scale(sampler2D image)
} }
if (P(0xbf,0x37) || P(0xdb,0x13)) { if (P(0xbf,0x37) || P(0xdb,0x13)) {
float dist = p.x - 2.0 * p.y; float dist = p.x - 2.0 * p.y;
float pixel_size = length(1.0 / (uResolution / textureDimensions)) * sqrt(5); float pixel_size = length(1.0 / (output_resolution / input_resolution)) * sqrt(5);
if (dist > pixel_size / 2) { if (dist > pixel_size / 2) {
return w1; return w1;
} }
@ -114,7 +111,7 @@ vec4 scale(sampler2D image)
} }
if (P(0xdb,0x49) || P(0xef,0x6d)) { if (P(0xdb,0x49) || P(0xef,0x6d)) {
float dist = p.y - 2.0 * p.x; float dist = p.y - 2.0 * p.x;
float pixel_size = length(1.0 / (uResolution / textureDimensions)) * sqrt(5); float pixel_size = length(1.0 / (output_resolution / input_resolution)) * sqrt(5);
if (p.y - 2.0 * p.x > pixel_size / 2) { if (p.y - 2.0 * p.x > pixel_size / 2) {
return w3; return w3;
} }
@ -126,7 +123,7 @@ vec4 scale(sampler2D image)
} }
if (P(0xbf,0x8f) || P(0x7e,0x0e)) { if (P(0xbf,0x8f) || P(0x7e,0x0e)) {
float dist = p.x + 2.0 * p.y; float dist = p.x + 2.0 * p.y;
float pixel_size = length(1.0 / (uResolution / textureDimensions)) * sqrt(5); float pixel_size = length(1.0 / (output_resolution / input_resolution)) * sqrt(5);
if (dist > 1.0 + pixel_size / 2) { if (dist > 1.0 + pixel_size / 2) {
return w4; return w4;
@ -150,7 +147,7 @@ vec4 scale(sampler2D image)
if (P(0x7e,0x2a) || P(0xef,0xab)) { if (P(0x7e,0x2a) || P(0xef,0xab)) {
float dist = p.y + 2.0 * p.x; float dist = p.y + 2.0 * p.x;
float pixel_size = length(1.0 / (uResolution / textureDimensions)) * sqrt(5); float pixel_size = length(1.0 / (output_resolution / input_resolution)) * sqrt(5);
if (p.y + 2.0 * p.x > 1.0 + pixel_size / 2) { if (p.y + 2.0 * p.x > 1.0 + pixel_size / 2) {
return w4; return w4;
@ -186,7 +183,7 @@ vec4 scale(sampler2D image)
P(0xbe,0x0a) || P(0xee,0x0a) || P(0x7e,0x0a) || P(0xeb,0x4b) || P(0xbe,0x0a) || P(0xee,0x0a) || P(0x7e,0x0a) || P(0xeb,0x4b) ||
P(0x3b,0x1b)) { P(0x3b,0x1b)) {
float dist = p.x + p.y; float dist = p.x + p.y;
float pixel_size = length(1.0 / (uResolution / textureDimensions)); float pixel_size = length(1.0 / (output_resolution / input_resolution));
if (dist > 0.5 + pixel_size / 2) { if (dist > 0.5 + pixel_size / 2) {
return w4; return w4;
@ -214,19 +211,19 @@ vec4 scale(sampler2D image)
return mix(mix(w4, w3, 0.5 - p.x), mix(w1, w0, 0.5 - p.x), 0.5 - p.y); return mix(mix(w4, w3, 0.5 - p.x), mix(w1, w0, 0.5 - p.x), 0.5 - p.y);
float dist = p.x + p.y; float dist = p.x + p.y;
float pixel_size = length(1.0 / (uResolution / textureDimensions)); float pixel_size = length(1.0 / (output_resolution / input_resolution));
if (dist > 0.5 + pixel_size / 2) if (dist > 0.5 + pixel_size / 2)
return w4; return w4;
/* We need more samples to "solve" this diagonal */ /* We need more samples to "solve" this diagonal */
vec4 x0 = texture(image, texCoord + vec2( -o.x * 2.0, -o.y * 2.0)); vec4 x0 = texture(image, position + vec2( -o.x * 2.0, -o.y * 2.0));
vec4 x1 = texture(image, texCoord + vec2( -o.x , -o.y * 2.0)); vec4 x1 = texture(image, position + vec2( -o.x , -o.y * 2.0));
vec4 x2 = texture(image, texCoord + vec2( 0.0 , -o.y * 2.0)); vec4 x2 = texture(image, position + vec2( 0.0 , -o.y * 2.0));
vec4 x3 = texture(image, texCoord + vec2( o.x , -o.y * 2.0)); vec4 x3 = texture(image, position + vec2( o.x , -o.y * 2.0));
vec4 x4 = texture(image, texCoord + vec2( -o.x * 2.0, -o.y )); vec4 x4 = texture(image, position + vec2( -o.x * 2.0, -o.y ));
vec4 x5 = texture(image, texCoord + vec2( -o.x * 2.0, 0.0 )); vec4 x5 = texture(image, position + vec2( -o.x * 2.0, 0.0 ));
vec4 x6 = texture(image, texCoord + vec2( -o.x * 2.0, o.y )); vec4 x6 = texture(image, position + vec2( -o.x * 2.0, o.y ));
if (is_different(x0, w4)) pattern |= 1 << 8; if (is_different(x0, w4)) pattern |= 1 << 8;
if (is_different(x1, w4)) pattern |= 1 << 9; if (is_different(x1, w4)) pattern |= 1 << 9;

View File

@ -4,16 +4,14 @@ float quickDistance(vec4 a, vec4 b)
return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z); return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z);
} }
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; vec2 pixel = position * input_resolution - vec2(0.5, 0.5);
vec2 pixel = texCoord * textureDimensions - vec2(0.5, 0.5); vec4 q11 = texture(image, (floor(pixel) + 0.5) / input_resolution);
vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / input_resolution);
vec4 q11 = texture(image, (floor(pixel) + 0.5) / textureDimensions); vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / input_resolution);
vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / textureDimensions); vec4 q22 = texture(image, (ceil(pixel) + 0.5) / input_resolution);
vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / textureDimensions);
vec4 q22 = texture(image, (ceil(pixel) + 0.5) / textureDimensions);
vec2 pos = fract(pixel); vec2 pos = fract(pixel);
@ -27,7 +25,7 @@ vec4 scale(sampler2D image)
int diagonalBias = 0; int diagonalBias = 0;
for (float y = -1.0; y < 3.0; y++) { for (float y = -1.0; y < 3.0; y++) {
for (float x = -1.0; x < 3.0; x++) { for (float x = -1.0; x < 3.0; x++) {
vec4 color = texture(image, (pixel + vec2(x, y)) / textureDimensions); vec4 color = texture(image, (pixel + vec2(x, y)) / input_resolution);
if (color == q11) diagonalBias++; if (color == q11) diagonalBias++;
if (color == q12) diagonalBias--; if (color == q12) diagonalBias--;
} }

View File

@ -1,25 +1,24 @@
/* Shader implementation of Scale2x is adapted from https://gist.github.com/singron/3161079 */ /* Shader implementation of Scale2x is adapted from https://gist.github.com/singron/3161079 */
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
// o = offset, the width of a pixel // o = offset, the width of a pixel
vec2 o = 1.0 / textureDimensions; vec2 o = 1.0 / input_resolution;
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution;
// texel arrangement // texel arrangement
// A B C // A B C
// D E F // D E F
// G H I // G H I
vec4 A = texture(image, texCoord + vec2( -o.x, o.y)); vec4 A = texture(image, position + vec2( -o.x, o.y));
vec4 B = texture(image, texCoord + vec2( 0, o.y)); vec4 B = texture(image, position + vec2( 0, o.y));
vec4 C = texture(image, texCoord + vec2( o.x, o.y)); vec4 C = texture(image, position + vec2( o.x, o.y));
vec4 D = texture(image, texCoord + vec2( -o.x, 0)); vec4 D = texture(image, position + vec2( -o.x, 0));
vec4 E = texture(image, texCoord + vec2( 0, 0)); vec4 E = texture(image, position + vec2( 0, 0));
vec4 F = texture(image, texCoord + vec2( o.x, 0)); vec4 F = texture(image, position + vec2( o.x, 0));
vec4 G = texture(image, texCoord + vec2( -o.x, -o.y)); vec4 G = texture(image, position + vec2( -o.x, -o.y));
vec4 H = texture(image, texCoord + vec2( 0, -o.y)); vec4 H = texture(image, position + vec2( 0, -o.y));
vec4 I = texture(image, texCoord + vec2( o.x, -o.y)); vec4 I = texture(image, position + vec2( o.x, -o.y));
vec2 p = texCoord * textureDimensions; vec2 p = position * input_resolution;
// p = the position within a pixel [0...1] // p = the position within a pixel [0...1]
p = fract(p); p = fract(p);
if (p.x > .5) { if (p.x > .5) {

View File

@ -1,21 +1,21 @@
vec4 scale2x(sampler2D image, vec2 texCoord) vec4 scale2x(sampler2D image, vec2 position)
{ {
// o = offset, the width of a pixel // o = offset, the width of a pixel
vec2 o = 1.0 / textureDimensions; vec2 o = 1.0 / input_resolution;
// texel arrangement // texel arrangement
// A B C // A B C
// D E F // D E F
// G H I // G H I
vec4 A = texture(image, texCoord + vec2( -o.x, o.y)); vec4 A = texture(image, position + vec2( -o.x, o.y));
vec4 B = texture(image, texCoord + vec2( 0, o.y)); vec4 B = texture(image, position + vec2( 0, o.y));
vec4 C = texture(image, texCoord + vec2( o.x, o.y)); vec4 C = texture(image, position + vec2( o.x, o.y));
vec4 D = texture(image, texCoord + vec2( -o.x, 0)); vec4 D = texture(image, position + vec2( -o.x, 0));
vec4 E = texture(image, texCoord + vec2( 0, 0)); vec4 E = texture(image, position + vec2( 0, 0));
vec4 F = texture(image, texCoord + vec2( o.x, 0)); vec4 F = texture(image, position + vec2( o.x, 0));
vec4 G = texture(image, texCoord + vec2( -o.x, -o.y)); vec4 G = texture(image, position + vec2( -o.x, -o.y));
vec4 H = texture(image, texCoord + vec2( 0, -o.y)); vec4 H = texture(image, position + vec2( 0, -o.y));
vec4 I = texture(image, texCoord + vec2( o.x, -o.y)); vec4 I = texture(image, position + vec2( o.x, -o.y));
vec2 p = texCoord * textureDimensions; vec2 p = position * input_resolution;
// p = the position within a pixel [0...1] // p = the position within a pixel [0...1]
vec4 R; vec4 R;
p = fract(p); p = fract(p);
@ -38,26 +38,25 @@ vec4 scale2x(sampler2D image, vec2 texCoord)
} }
} }
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
// o = offset, the width of a pixel // o = offset, the width of a pixel
vec2 o = 1.0 / (textureDimensions * 2.); vec2 o = 1.0 / (input_resolution * 2.);
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution;
// texel arrangement // texel arrangement
// A B C // A B C
// D E F // D E F
// G H I // G H I
vec4 A = scale2x(image, texCoord + vec2( -o.x, o.y)); vec4 A = scale2x(image, position + vec2( -o.x, o.y));
vec4 B = scale2x(image, texCoord + vec2( 0, o.y)); vec4 B = scale2x(image, position + vec2( 0, o.y));
vec4 C = scale2x(image, texCoord + vec2( o.x, o.y)); vec4 C = scale2x(image, position + vec2( o.x, o.y));
vec4 D = scale2x(image, texCoord + vec2( -o.x, 0)); vec4 D = scale2x(image, position + vec2( -o.x, 0));
vec4 E = scale2x(image, texCoord + vec2( 0, 0)); vec4 E = scale2x(image, position + vec2( 0, 0));
vec4 F = scale2x(image, texCoord + vec2( o.x, 0)); vec4 F = scale2x(image, position + vec2( o.x, 0));
vec4 G = scale2x(image, texCoord + vec2( -o.x, -o.y)); vec4 G = scale2x(image, position + vec2( -o.x, -o.y));
vec4 H = scale2x(image, texCoord + vec2( 0, -o.y)); vec4 H = scale2x(image, position + vec2( 0, -o.y));
vec4 I = scale2x(image, texCoord + vec2( o.x, -o.y)); vec4 I = scale2x(image, position + vec2( o.x, -o.y));
vec2 p = texCoord * textureDimensions * 2.; vec2 p = position * input_resolution * 2.;
// p = the position within a pixel [0...1] // p = the position within a pixel [0...1]
p = fract(p); p = fract(p);
if (p.x > .5) { if (p.x > .5) {

View File

@ -1,13 +1,11 @@
vec4 scale(sampler2D image) vec4 scale(sampler2D image, vec2 position)
{ {
vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; vec2 pixel = position * input_resolution - vec2(0.5, 0.5);
vec2 pixel = texCoord * textureDimensions - vec2(0.5, 0.5); vec4 q11 = texture(image, (floor(pixel) + 0.5) / input_resolution);
vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / input_resolution);
vec4 q11 = texture(image, (floor(pixel) + 0.5) / textureDimensions); vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / input_resolution);
vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / textureDimensions); vec4 q22 = texture(image, (ceil(pixel) + 0.5) / input_resolution);
vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / textureDimensions);
vec4 q22 = texture(image, (ceil(pixel) + 0.5) / textureDimensions);
vec2 s = smoothstep(0., 1., fract(pixel)); vec2 s = smoothstep(0., 1., fract(pixel));