diff --git a/Cocoa/GBGLShader.m b/Cocoa/GBGLShader.m index 1fa2ba3..444ee89 100644 --- a/Cocoa/GBGLShader.m +++ b/Cocoa/GBGLShader.m @@ -50,7 +50,7 @@ void main(void) {\n\ // Attributes position_attribute = glGetAttribLocation(program, "aPosition"); // Uniforms - resolution_uniform = glGetUniformLocation(program, "uResolution"); + resolution_uniform = glGetUniformLocation(program, "output_resolution"); glGenTextures(1, &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_T, GL_CLAMP_TO_EDGE); 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 [self configureOpenGL]; diff --git a/Makefile b/Makefile index afd56b6..85a92bd 100755 --- a/Makefile +++ b/Makefile @@ -286,7 +286,7 @@ $(BIN)/SDL/background.bmp: SDL/background.bmp cp -f $^ $@ $(BIN)/SDL/Shaders: Shaders - -@$(MKDIR) -p $(dir $@) + -@$(MKDIR) -p $@ cp -rf Shaders/*.fsh $@ # Boot ROMs diff --git a/SDL/shader.c b/SDL/shader.c index a34866e..5b41b2a 100644 --- a/SDL/shader.c +++ b/SDL/shader.c @@ -109,8 +109,8 @@ bool init_shader_with_name(shader_t *shader, const char *name) // Attributes shader->position_attribute = glGetAttribLocation(shader->program, "aPosition"); // Uniforms - shader->resolution_uniform = glGetUniformLocation(shader->program, "uResolution"); - shader->origin_uniform = glGetUniformLocation(shader->program, "uOrigin"); + shader->resolution_uniform = glGetUniformLocation(shader->program, "output_resolution"); + shader->origin_uniform = glGetUniformLocation(shader->program, "origin"); glGenTextures(1, &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_T, GL_CLAMP_TO_EDGE); 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 diff --git a/Shaders/AAOmniScaleLegacy.fsh b/Shaders/AAOmniScaleLegacy.fsh index d667edf..6aff04a 100644 --- a/Shaders/AAOmniScaleLegacy.fsh +++ b/Shaders/AAOmniScaleLegacy.fsh @@ -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); } -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 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / textureDimensions); - vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / textureDimensions); - vec4 q22 = texture(image, (ceil(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) / input_resolution); + vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / input_resolution); + vec4 q22 = texture(image, (ceil(pixel) + 0.5) / input_resolution); vec2 pos = fract(pixel); @@ -25,7 +25,7 @@ vec4 omniScale(sampler2D image, vec2 texCoord) int diagonalBias = 0; for (float y = -1.0; y < 3.0; y++) { 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 == q12) diagonalBias--; } @@ -104,16 +104,15 @@ vec4 omniScale(sampler2D image, vec2 texCoord) 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) / uResolution; + vec2 pixel = vec2(1.0, 1.0) / output_resolution; // 4-pixel super sampling - vec4 q11 = omniScale(image, texCoord + pixel * vec2(-0.25, -0.25)); - vec4 q21 = omniScale(image, texCoord + pixel * vec2(+0.25, -0.25)); - vec4 q12 = omniScale(image, texCoord + pixel * vec2(-0.25, +0.25)); - vec4 q22 = omniScale(image, texCoord + pixel * vec2(+0.25, +0.25)); + vec4 q11 = omniScale(image, position + pixel * vec2(-0.25, -0.25)); + vec4 q21 = omniScale(image, position + pixel * vec2(+0.25, -0.25)); + vec4 q12 = omniScale(image, position + pixel * vec2(-0.25, +0.25)); + vec4 q22 = omniScale(image, position + pixel * vec2(+0.25, +0.25)); return (q11 + q21 + q12 + q22) / 4.0; -} \ No newline at end of file +} diff --git a/Shaders/AAScale2x.fsh b/Shaders/AAScale2x.fsh index bdd8403..4f5d415 100644 --- a/Shaders/AAScale2x.fsh +++ b/Shaders/AAScale2x.fsh @@ -1,23 +1,22 @@ -vec4 scale2x(sampler2D image) +vec4 scale2x(sampler2D image, vec2 position) { // o = offset, the width of a pixel - vec2 o = 1.0 / textureDimensions; - vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; - + vec2 o = 1.0 / input_resolution; + // texel arrangement // A B C // D E F // G H I - vec4 A = texture(image, texCoord + vec2( -o.x, o.y)); - vec4 B = texture(image, texCoord + vec2( 0, o.y)); - vec4 C = texture(image, texCoord + vec2( o.x, o.y)); - vec4 D = texture(image, texCoord + vec2( -o.x, 0)); - vec4 E = texture(image, texCoord + vec2( 0, 0)); - vec4 F = texture(image, texCoord + vec2( o.x, 0)); - vec4 G = texture(image, texCoord + vec2( -o.x, -o.y)); - vec4 H = texture(image, texCoord + vec2( 0, -o.y)); - vec4 I = texture(image, texCoord + vec2( o.x, -o.y)); - vec2 p = texCoord * textureDimensions; + vec4 A = texture(image, position + vec2( -o.x, o.y)); + vec4 B = texture(image, position + vec2( 0, o.y)); + vec4 C = texture(image, position + vec2( o.x, o.y)); + vec4 D = texture(image, position + vec2( -o.x, 0)); + vec4 E = texture(image, position + vec2( 0, 0)); + vec4 F = texture(image, position + vec2( o.x, 0)); + vec4 G = texture(image, position + vec2( -o.x, -o.y)); + vec4 H = texture(image, position + vec2( 0, -o.y)); + vec4 I = texture(image, position + vec2( o.x, -o.y)); + vec2 p = position * input_resolution; // p = the position within a pixel [0...1] p = fract(p); 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, texCoord), scale2x(image), 0.5); -} \ No newline at end of file + return mix(texture(image, position), scale2x(image, position), 0.5); +} diff --git a/Shaders/AAScale4x.fsh b/Shaders/AAScale4x.fsh index 83380d1..b08fd93 100644 --- a/Shaders/AAScale4x.fsh +++ b/Shaders/AAScale4x.fsh @@ -1,21 +1,21 @@ -vec4 scale2x(sampler2D image, vec2 texCoord) +vec4 scale2x(sampler2D image, vec2 position) { // o = offset, the width of a pixel - vec2 o = 1.0 / textureDimensions; + vec2 o = 1.0 / input_resolution; // texel arrangement // A B C // D E F // G H I - vec4 A = texture(image, texCoord + vec2( -o.x, o.y)); - vec4 B = texture(image, texCoord + vec2( 0, o.y)); - vec4 C = texture(image, texCoord + vec2( o.x, o.y)); - vec4 D = texture(image, texCoord + vec2( -o.x, 0)); - vec4 E = texture(image, texCoord + vec2( 0, 0)); - vec4 F = texture(image, texCoord + vec2( o.x, 0)); - vec4 G = texture(image, texCoord + vec2( -o.x, -o.y)); - vec4 H = texture(image, texCoord + vec2( 0, -o.y)); - vec4 I = texture(image, texCoord + vec2( o.x, -o.y)); - vec2 p = texCoord * textureDimensions; + vec4 A = texture(image, position + vec2( -o.x, o.y)); + vec4 B = texture(image, position + vec2( 0, o.y)); + vec4 C = texture(image, position + vec2( o.x, o.y)); + vec4 D = texture(image, position + vec2( -o.x, 0)); + vec4 E = texture(image, position + vec2( 0, 0)); + vec4 F = texture(image, position + vec2( o.x, 0)); + vec4 G = texture(image, position + vec2( -o.x, -o.y)); + vec4 H = texture(image, position + vec2( 0, -o.y)); + vec4 I = texture(image, position + vec2( o.x, -o.y)); + vec2 p = position * input_resolution; // p = the position within a pixel [0...1] p = fract(p); 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 - vec2 o = 1.0 / (textureDimensions * 2.); - vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; - + vec2 o = 1.0 / (input_resolution * 2.); + // texel arrangement // A B C // D E F // G H I - vec4 A = aaScale2x(image, texCoord + vec2( -o.x, o.y)); - vec4 B = aaScale2x(image, texCoord + vec2( 0, o.y)); - vec4 C = aaScale2x(image, texCoord + vec2( o.x, o.y)); - vec4 D = aaScale2x(image, texCoord + vec2( -o.x, 0)); - vec4 E = aaScale2x(image, texCoord + vec2( 0, 0)); - vec4 F = aaScale2x(image, texCoord + vec2( o.x, 0)); - vec4 G = aaScale2x(image, texCoord + vec2( -o.x, -o.y)); - vec4 H = aaScale2x(image, texCoord + vec2( 0, -o.y)); - vec4 I = aaScale2x(image, texCoord + vec2( o.x, -o.y)); + vec4 A = aaScale2x(image, position + vec2( -o.x, o.y)); + vec4 B = aaScale2x(image, position + vec2( 0, o.y)); + vec4 C = aaScale2x(image, position + vec2( o.x, o.y)); + vec4 D = aaScale2x(image, position + vec2( -o.x, 0)); + vec4 E = aaScale2x(image, position + vec2( 0, 0)); + vec4 F = aaScale2x(image, position + vec2( o.x, 0)); + vec4 G = aaScale2x(image, position + vec2( -o.x, -o.y)); + vec4 H = aaScale2x(image, position + vec2( 0, -o.y)); + vec4 I = aaScale2x(image, position + vec2( o.x, -o.y)); vec4 R; - vec2 p = texCoord * textureDimensions * 2.; + vec2 p = position * input_resolution * 2.; // p = the position within a pixel [0...1] p = fract(p); if (p.x > .5) { @@ -84,4 +83,4 @@ vec4 scale(sampler2D image) } return mix(R, E, 0.5); -} \ No newline at end of file +} diff --git a/Shaders/Bilinear.fsh b/Shaders/Bilinear.fsh index 6fa5e21..7e8d259 100644 --- a/Shaders/Bilinear.fsh +++ b/Shaders/Bilinear.fsh @@ -1,16 +1,14 @@ -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) / textureDimensions); - vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / textureDimensions); - vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / textureDimensions); - vec4 q22 = texture(image, (ceil(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) / input_resolution); + vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / input_resolution); + vec4 q22 = texture(image, (ceil(pixel) + 0.5) / input_resolution); vec4 r1 = mix(q11, q21, fract(pixel.x)); vec4 r2 = mix(q12, q22, fract(pixel.x)); return mix (r1, r2, fract(pixel.y)); -} \ No newline at end of file +} diff --git a/Shaders/HQ2x.fsh b/Shaders/HQ2x.fsh index 7a4fb1e..a815a60 100644 --- a/Shaders/HQ2x.fsh +++ b/Shaders/HQ2x.fsh @@ -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); } -vec4 scale(sampler2D image) +vec4 scale(sampler2D image, vec2 position) { // o = offset, the width of a pixel - vec2 o = 1.0 / textureDimensions; - vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; - + vec2 o = 1.0 / input_resolution; + /* 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] - vec2 p = fract(texCoord * textureDimensions); + vec2 p = fract(position * input_resolution); if (p.x > 0.5) o.x = -o.x; if (p.y > 0.5) o.y = -o.y; - vec4 w0 = texture(image, texCoord + vec2( -o.x, -o.y)); - vec4 w1 = texture(image, texCoord + vec2( 0, -o.y)); - vec4 w2 = texture(image, texCoord + vec2( o.x, -o.y)); - vec4 w3 = texture(image, texCoord + vec2( -o.x, 0)); - vec4 w4 = texture(image, texCoord + vec2( 0, 0)); - vec4 w5 = texture(image, texCoord + vec2( o.x, 0)); - vec4 w6 = texture(image, texCoord + vec2( -o.x, o.y)); - vec4 w7 = texture(image, texCoord + vec2( 0, o.y)); - vec4 w8 = texture(image, texCoord + vec2( o.x, o.y)); + vec4 w0 = texture(image, position + vec2( -o.x, -o.y)); + vec4 w1 = texture(image, position + vec2( 0, -o.y)); + vec4 w2 = texture(image, position + vec2( o.x, -o.y)); + vec4 w3 = texture(image, position + vec2( -o.x, 0)); + vec4 w4 = texture(image, position + vec2( 0, 0)); + vec4 w5 = texture(image, position + vec2( o.x, 0)); + vec4 w6 = texture(image, position + vec2( -o.x, o.y)); + vec4 w7 = texture(image, position + vec2( 0, o.y)); + vec4 w8 = texture(image, position + vec2( o.x, o.y)); int pattern = 0; if (is_different(w0, w4)) pattern |= 1; @@ -99,4 +98,4 @@ vec4 scale(sampler2D image) return interp_3px(w4, 2.0, w3, 1.0, w1, 1.0); return interp_3px(w4, 6.0, w3, 1.0, w1, 1.0); -} \ No newline at end of file +} diff --git a/Shaders/LCD.fsh b/Shaders/LCD.fsh index 980f3bd..f41cf5b 100644 --- a/Shaders/LCD.fsh +++ b/Shaders/LCD.fsh @@ -2,29 +2,27 @@ #define COLOR_HIGH 1.0 #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); - vec2 sub_pos = fract(texCoord * textureDimensions * 6); - - 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)); + vec4 center = texture(image, position); + vec4 left = texture(image, position - vec2(1.0 / input_resolution.x, 0)); + vec4 right = texture(image, position + vec2(1.0 / input_resolution.x, 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); - left = mix(left, texture(image, texCoord + vec2(-1.0 / textureDimensions.x, -1.0 / textureDimensions.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); + 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, position + vec2(-1.0 / input_resolution.x, -1.0 / input_resolution.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); left *= 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) { - center = mix(center, texture(image, texCoord + vec2(0, 1.0 / textureDimensions.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); - right = mix(right, texture(image, texCoord + vec2( 1.0 / textureDimensions.x, 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, position + vec2(-1.0 / input_resolution.x, 1.0 / input_resolution.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); left *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); right *= (1.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH); diff --git a/Shaders/MasterShader.fsh b/Shaders/MasterShader.fsh index 4103056..9df2c1a 100644 --- a/Shaders/MasterShader.fsh +++ b/Shaders/MasterShader.fsh @@ -1,27 +1,28 @@ #version 150 uniform sampler2D image; -uniform sampler2D previousImage; -uniform bool uMixPrevious; +uniform sampler2D previous_image; +uniform bool mix_previous; -uniform vec2 uResolution; -uniform vec2 uOrigin; -const vec2 textureDimensions = vec2(160, 144); +uniform vec2 output_resolution; +uniform vec2 origin; +const vec2 input_resolution = vec2(160, 144); out vec4 frag_color; vec4 modified_frag_cord; -#define gl_FragCoord modified_frag_cord #line 1 {filter} -#undef gl_FragCoord -void main() { - modified_frag_cord = gl_FragCoord - vec4(uOrigin.x, uOrigin.y, 0, 0); +void main() +{ + vec2 position = gl_FragCoord.xy - origin; + position /= output_resolution; + position.y = 1 - position.y; - if (uMixPrevious) { - frag_color = mix(scale(image), scale(previousImage), 0.5); + if (mix_previous) { + frag_color = mix(scale(image, position), scale(previous_image, position), 0.5); } else { - frag_color = scale(image); + frag_color = scale(image, position); } -} \ No newline at end of file +} diff --git a/Shaders/MasterShader.metal b/Shaders/MasterShader.metal index 928c4c7..3c22736 100644 --- a/Shaders/MasterShader.metal +++ b/Shaders/MasterShader.metal @@ -3,6 +3,7 @@ #include using namespace metal; +const float4 input_resolution = float4(160, 144); /* For GLSL compatibility */ typedef float2 vec2; @@ -17,7 +18,6 @@ typedef struct { // Vertex Function vertex rasterizer_data vertex_shader(uint index [[ vertex_id ]], constant vector_float2 *vertices [[ buffer(0) ]]) - { rasterizer_data out; diff --git a/Shaders/NearestNeighbor.fsh b/Shaders/NearestNeighbor.fsh index 661e5fb..e8b0759 100644 --- a/Shaders/NearestNeighbor.fsh +++ b/Shaders/NearestNeighbor.fsh @@ -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, texCoord); -} \ No newline at end of file + return texture(image, position); +} diff --git a/Shaders/OmniScale.fsh b/Shaders/OmniScale.fsh index 7e8b6cb..384fdd3 100644 --- a/Shaders/OmniScale.fsh +++ b/Shaders/OmniScale.fsh @@ -24,16 +24,15 @@ bool is_different(vec4 a, vec4 b) #define P(m, r) ((pattern & (m)) == (r)) -vec4 scale(sampler2D image) +vec4 scale(sampler2D image, vec2 position) { // o = offset, the width of a pixel - vec2 o = 1.0 / textureDimensions; - vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; - + vec2 o = 1.0 / input_resolution; + /* 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] - vec2 p = fract(texCoord * textureDimensions); + vec2 p = fract(position * input_resolution); if (p.x > 0.5) { o.x = -o.x; @@ -44,17 +43,15 @@ vec4 scale(sampler2D image) p.y = 1.0 - p.y; } - - - vec4 w0 = texture(image, texCoord + vec2( -o.x, -o.y)); - vec4 w1 = texture(image, texCoord + vec2( 0, -o.y)); - vec4 w2 = texture(image, texCoord + vec2( o.x, -o.y)); - vec4 w3 = texture(image, texCoord + vec2( -o.x, 0)); - vec4 w4 = texture(image, texCoord + vec2( 0, 0)); - vec4 w5 = texture(image, texCoord + vec2( o.x, 0)); - vec4 w6 = texture(image, texCoord + vec2( -o.x, o.y)); - vec4 w7 = texture(image, texCoord + vec2( 0, o.y)); - vec4 w8 = texture(image, texCoord + vec2( o.x, o.y)); + vec4 w0 = texture(image, position + vec2( -o.x, -o.y)); + vec4 w1 = texture(image, position + vec2( 0, -o.y)); + vec4 w2 = texture(image, position + vec2( o.x, -o.y)); + vec4 w3 = texture(image, position + vec2( -o.x, 0)); + vec4 w4 = texture(image, position + vec2( 0, 0)); + vec4 w5 = texture(image, position + vec2( o.x, 0)); + vec4 w6 = texture(image, position + vec2( -o.x, o.y)); + vec4 w7 = texture(image, position + vec2( 0, o.y)); + vec4 w8 = texture(image, position + vec2( o.x, o.y)); int pattern = 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); if (P(0x2f,0x2f)) { 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) { return w4; } @@ -102,7 +99,7 @@ vec4 scale(sampler2D image) } if (P(0xbf,0x37) || P(0xdb,0x13)) { 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) { return w1; } @@ -114,7 +111,7 @@ vec4 scale(sampler2D image) } if (P(0xdb,0x49) || P(0xef,0x6d)) { 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) { return w3; } @@ -126,7 +123,7 @@ vec4 scale(sampler2D image) } if (P(0xbf,0x8f) || P(0x7e,0x0e)) { 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) { return w4; @@ -150,7 +147,7 @@ vec4 scale(sampler2D image) if (P(0x7e,0x2a) || P(0xef,0xab)) { 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) { return w4; @@ -186,7 +183,7 @@ vec4 scale(sampler2D image) P(0xbe,0x0a) || P(0xee,0x0a) || P(0x7e,0x0a) || P(0xeb,0x4b) || P(0x3b,0x1b)) { 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) { 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); 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) return w4; /* We need more samples to "solve" this diagonal */ - vec4 x0 = texture(image, texCoord + vec2( -o.x * 2.0, -o.y * 2.0)); - vec4 x1 = texture(image, texCoord + vec2( -o.x , -o.y * 2.0)); - vec4 x2 = texture(image, texCoord + vec2( 0.0 , -o.y * 2.0)); - vec4 x3 = texture(image, texCoord + vec2( o.x , -o.y * 2.0)); - vec4 x4 = texture(image, texCoord + vec2( -o.x * 2.0, -o.y )); - vec4 x5 = texture(image, texCoord + vec2( -o.x * 2.0, 0.0 )); - vec4 x6 = texture(image, texCoord + vec2( -o.x * 2.0, o.y )); + vec4 x0 = texture(image, position + vec2( -o.x * 2.0, -o.y * 2.0)); + vec4 x1 = texture(image, position + vec2( -o.x , -o.y * 2.0)); + vec4 x2 = texture(image, position + vec2( 0.0 , -o.y * 2.0)); + vec4 x3 = texture(image, position + vec2( o.x , -o.y * 2.0)); + vec4 x4 = texture(image, position + vec2( -o.x * 2.0, -o.y )); + vec4 x5 = texture(image, position + vec2( -o.x * 2.0, 0.0 )); + vec4 x6 = texture(image, position + vec2( -o.x * 2.0, o.y )); if (is_different(x0, w4)) pattern |= 1 << 8; if (is_different(x1, w4)) pattern |= 1 << 9; @@ -251,4 +248,4 @@ vec4 scale(sampler2D image) } return w4; -} \ No newline at end of file +} diff --git a/Shaders/OmniScaleLegacy.fsh b/Shaders/OmniScaleLegacy.fsh index f4bdea9..2d38a2f 100644 --- a/Shaders/OmniScaleLegacy.fsh +++ b/Shaders/OmniScaleLegacy.fsh @@ -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); } -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) / textureDimensions); - vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / textureDimensions); - vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / textureDimensions); - vec4 q22 = texture(image, (ceil(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) / input_resolution); + vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / input_resolution); + vec4 q22 = texture(image, (ceil(pixel) + 0.5) / input_resolution); vec2 pos = fract(pixel); @@ -27,7 +25,7 @@ vec4 scale(sampler2D image) int diagonalBias = 0; for (float y = -1.0; y < 3.0; y++) { 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 == q12) diagonalBias--; } @@ -104,4 +102,4 @@ vec4 scale(sampler2D image) } return q22; -} \ No newline at end of file +} diff --git a/Shaders/Scale2x.fsh b/Shaders/Scale2x.fsh index 3968057..ffc68f5 100644 --- a/Shaders/Scale2x.fsh +++ b/Shaders/Scale2x.fsh @@ -1,25 +1,24 @@ /* 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 - vec2 o = 1.0 / textureDimensions; - vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; - + vec2 o = 1.0 / input_resolution; + // texel arrangement // A B C // D E F // G H I - vec4 A = texture(image, texCoord + vec2( -o.x, o.y)); - vec4 B = texture(image, texCoord + vec2( 0, o.y)); - vec4 C = texture(image, texCoord + vec2( o.x, o.y)); - vec4 D = texture(image, texCoord + vec2( -o.x, 0)); - vec4 E = texture(image, texCoord + vec2( 0, 0)); - vec4 F = texture(image, texCoord + vec2( o.x, 0)); - vec4 G = texture(image, texCoord + vec2( -o.x, -o.y)); - vec4 H = texture(image, texCoord + vec2( 0, -o.y)); - vec4 I = texture(image, texCoord + vec2( o.x, -o.y)); - vec2 p = texCoord * textureDimensions; + vec4 A = texture(image, position + vec2( -o.x, o.y)); + vec4 B = texture(image, position + vec2( 0, o.y)); + vec4 C = texture(image, position + vec2( o.x, o.y)); + vec4 D = texture(image, position + vec2( -o.x, 0)); + vec4 E = texture(image, position + vec2( 0, 0)); + vec4 F = texture(image, position + vec2( o.x, 0)); + vec4 G = texture(image, position + vec2( -o.x, -o.y)); + vec4 H = texture(image, position + vec2( 0, -o.y)); + vec4 I = texture(image, position + vec2( o.x, -o.y)); + vec2 p = position * input_resolution; // p = the position within a pixel [0...1] p = fract(p); if (p.x > .5) { @@ -39,4 +38,4 @@ vec4 scale(sampler2D image) return D == H && D != B && H != F ? D : E; } } -} \ No newline at end of file +} diff --git a/Shaders/Scale4x.fsh b/Shaders/Scale4x.fsh index 1c763fc..e6be367 100644 --- a/Shaders/Scale4x.fsh +++ b/Shaders/Scale4x.fsh @@ -1,21 +1,21 @@ -vec4 scale2x(sampler2D image, vec2 texCoord) +vec4 scale2x(sampler2D image, vec2 position) { // o = offset, the width of a pixel - vec2 o = 1.0 / textureDimensions; + vec2 o = 1.0 / input_resolution; // texel arrangement // A B C // D E F // G H I - vec4 A = texture(image, texCoord + vec2( -o.x, o.y)); - vec4 B = texture(image, texCoord + vec2( 0, o.y)); - vec4 C = texture(image, texCoord + vec2( o.x, o.y)); - vec4 D = texture(image, texCoord + vec2( -o.x, 0)); - vec4 E = texture(image, texCoord + vec2( 0, 0)); - vec4 F = texture(image, texCoord + vec2( o.x, 0)); - vec4 G = texture(image, texCoord + vec2( -o.x, -o.y)); - vec4 H = texture(image, texCoord + vec2( 0, -o.y)); - vec4 I = texture(image, texCoord + vec2( o.x, -o.y)); - vec2 p = texCoord * textureDimensions; + vec4 A = texture(image, position + vec2( -o.x, o.y)); + vec4 B = texture(image, position + vec2( 0, o.y)); + vec4 C = texture(image, position + vec2( o.x, o.y)); + vec4 D = texture(image, position + vec2( -o.x, 0)); + vec4 E = texture(image, position + vec2( 0, 0)); + vec4 F = texture(image, position + vec2( o.x, 0)); + vec4 G = texture(image, position + vec2( -o.x, -o.y)); + vec4 H = texture(image, position + vec2( 0, -o.y)); + vec4 I = texture(image, position + vec2( o.x, -o.y)); + vec2 p = position * input_resolution; // p = the position within a pixel [0...1] vec4 R; 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 - vec2 o = 1.0 / (textureDimensions * 2.); - vec2 texCoord = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y) / uResolution; - + vec2 o = 1.0 / (input_resolution * 2.); + // texel arrangement // A B C // D E F // G H I - vec4 A = scale2x(image, texCoord + vec2( -o.x, o.y)); - vec4 B = scale2x(image, texCoord + vec2( 0, o.y)); - vec4 C = scale2x(image, texCoord + vec2( o.x, o.y)); - vec4 D = scale2x(image, texCoord + vec2( -o.x, 0)); - vec4 E = scale2x(image, texCoord + vec2( 0, 0)); - vec4 F = scale2x(image, texCoord + vec2( o.x, 0)); - vec4 G = scale2x(image, texCoord + vec2( -o.x, -o.y)); - vec4 H = scale2x(image, texCoord + vec2( 0, -o.y)); - vec4 I = scale2x(image, texCoord + vec2( o.x, -o.y)); - vec2 p = texCoord * textureDimensions * 2.; + vec4 A = scale2x(image, position + vec2( -o.x, o.y)); + vec4 B = scale2x(image, position + vec2( 0, o.y)); + vec4 C = scale2x(image, position + vec2( o.x, o.y)); + vec4 D = scale2x(image, position + vec2( -o.x, 0)); + vec4 E = scale2x(image, position + vec2( 0, 0)); + vec4 F = scale2x(image, position + vec2( o.x, 0)); + vec4 G = scale2x(image, position + vec2( -o.x, -o.y)); + vec4 H = scale2x(image, position + vec2( 0, -o.y)); + vec4 I = scale2x(image, position + vec2( o.x, -o.y)); + vec2 p = position * input_resolution * 2.; // p = the position within a pixel [0...1] p = fract(p); if (p.x > .5) { @@ -77,4 +76,4 @@ vec4 scale(sampler2D image) return D == H && D != B && H != F ? D : E; } } -} \ No newline at end of file +} diff --git a/Shaders/SmoothBilinear.fsh b/Shaders/SmoothBilinear.fsh index b796d88..0e40043 100644 --- a/Shaders/SmoothBilinear.fsh +++ b/Shaders/SmoothBilinear.fsh @@ -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) / textureDimensions); - vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / textureDimensions); - vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / textureDimensions); - vec4 q22 = texture(image, (ceil(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) / input_resolution); + vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / input_resolution); + vec4 q22 = texture(image, (ceil(pixel) + 0.5) / input_resolution); vec2 s = smoothstep(0., 1., fract(pixel)); @@ -15,4 +13,4 @@ vec4 scale(sampler2D image) vec4 r2 = mix(q12, q22, s.x); return mix (r1, r2, s.y); -} \ No newline at end of file +}