Merge pull request #599 from max-m/Shader-WebGL-compat

Make shaders compatible with GLES 3.0
This commit is contained in:
Lior Halphon
2024-03-31 14:17:49 +03:00
committed by GitHub
6 changed files with 83 additions and 83 deletions

View File

@@ -33,8 +33,8 @@ STATIC vec4 scale2x(sampler2D image, vec2 position, vec2 input_resolution, vec2
}
STATIC vec4 scale2x_wrapper(sampler2D t, vec2 pos, vec2 offset, vec2 input_resolution, vec2 output_resolution)
{
vec2 origin = (floor(pos * input_resolution * 2)) + vec2(0.5, 0.5);
return scale2x(t, (origin + offset) / input_resolution / 2, input_resolution, output_resolution);
vec2 origin = (floor(pos * input_resolution * 2.0)) + vec2(0.5, 0.5);
return scale2x(t, (origin + offset) / input_resolution / 2.0, input_resolution, output_resolution);
}
STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)

View File

@@ -7,23 +7,23 @@
STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
{
/* Curve and pixel ratio */
float y_curve = cos(position.x - 0.5) * CURVENESS + (1 - CURVENESS);
float y_curve = cos(position.x - 0.5) * CURVENESS + (1.0 - CURVENESS);
float y_multiplier = 8.0 / 7.0 / y_curve;
position.y *= y_multiplier;
position.y -= (y_multiplier - 1) / 2;
position.y -= (y_multiplier - 1.0) / 2.0;
if (position.y < 0.0) return vec4(0,0,0,0);
if (position.y > 1.0) return vec4(0,0,0,0);
float x_curve = cos(position.y - 0.5) * CURVENESS + (1 - CURVENESS);
float x_multiplier = 1/x_curve;
float x_curve = cos(position.y - 0.5) * CURVENESS + (1.0 - CURVENESS);
float x_multiplier = 1.0/x_curve;
position.x *= x_multiplier;
position.x -= (x_multiplier - 1) / 2;
position.x -= (x_multiplier - 1.0) / 2.0;
if (position.x < 0.0) return vec4(0,0,0,0);
if (position.x > 1.0) return vec4(0,0,0,0);
/* Setting up common vars */
vec2 pos = fract(position * input_resolution);
vec2 sub_pos = pos * 6;
vec2 sub_pos = pos * 6.0;
vec4 center = texture_relative(image, position, vec2(0, 0));
vec4 left = texture_relative(image, position, vec2(-1, 0));
@@ -36,18 +36,18 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
right = mix(right, texture_relative(image, position, vec2( 1, -1)), 0.5 - sub_pos.y / 2.0);
}
else if (sub_pos.y > 5.0) {
center = mix(center, texture_relative(image, position, vec2( 0, 1)), (sub_pos.y - 5) / 2.0);
left = mix(left, texture_relative(image, position, vec2(-1, 1)), (sub_pos.y - 5) / 2.0);
right = mix(right, texture_relative(image, position, vec2( 1, 1)), (sub_pos.y - 5) / 2.0);
center = mix(center, texture_relative(image, position, vec2( 0, 1)), (sub_pos.y - 5.0) / 2.0);
left = mix(left, texture_relative(image, position, vec2(-1, 1)), (sub_pos.y - 5.0) / 2.0);
right = mix(right, texture_relative(image, position, vec2( 1, 1)), (sub_pos.y - 5.0) / 2.0);
}
/* Scanlines */
float scanline_multiplier;
if (pos.y < 0.5) {
scanline_multiplier = (pos.y * 2) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
scanline_multiplier = (pos.y * 2.0) * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
}
else {
scanline_multiplier = ((1 - pos.y) * 2) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
scanline_multiplier = ((1.0 - pos.y) * 2.0) * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
}
center *= scanline_multiplier;
@@ -63,15 +63,15 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
if (pos.y < 1.0 / 3.0) {
float gradient_position = pos.y * 3.0;
center *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
left *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
right *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
center *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
left *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
right *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
}
else if (pos.y > 2.0 / 3.0) {
float gradient_position = (1 - pos.y) * 3.0;
center *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
left *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
right *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
float gradient_position = (1.0 - pos.y) * 3.0;
center *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
left *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
right *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
}
/* Blur the edges of the separators of adjacent columns */
@@ -82,26 +82,26 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
if (pos.y < 1.0 / 3.0) {
float gradient_position = pos.y * 3.0;
if (pos.x < 0.5) {
gradient_position = 1 - (1 - gradient_position) * (1 - (pos.x) * 6.0);
gradient_position = 1.0 - (1.0 - gradient_position) * (1.0 - (pos.x) * 6.0);
}
else {
gradient_position = 1 - (1 - gradient_position) * (1 - (1 - pos.x) * 6.0);
gradient_position = 1.0 - (1.0 - gradient_position) * (1.0 - (1.0 - pos.x) * 6.0);
}
center *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
left *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
right *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
center *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
left *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
right *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
}
else if (pos.y > 2.0 / 3.0) {
float gradient_position = (1 - pos.y) * 3.0;
float gradient_position = (1.0 - pos.y) * 3.0;
if (pos.x < 0.5) {
gradient_position = 1 - (1 - gradient_position) * (1 - (pos.x) * 6.0);
gradient_position = 1.0 - (1.0 - gradient_position) * (1.0 - (pos.x) * 6.0);
}
else {
gradient_position = 1 - (1 - gradient_position) * (1 - (1 - pos.x) * 6.0);
gradient_position = 1.0 - (1.0 - gradient_position) * (1.0 - (1.0 - pos.x) * 6.0);
}
center *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
left *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
right *= gradient_position * VERTICAL_BORDER_DEPTH + (1 - VERTICAL_BORDER_DEPTH);
center *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
left *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
right *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
}
}
@@ -120,41 +120,41 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
else if (sub_pos.x < 2.0) {
ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1),
vec4(COLOR_HIGH * center.r, COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1),
sub_pos.x - 1);
sub_pos.x - 1.0);
}
else if (sub_pos.x < 3.0) {
ret = mix(vec4(COLOR_HIGH * center.r , COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1),
vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g, COLOR_LOW * center.b, 1),
sub_pos.x - 2);
sub_pos.x - 2.0);
}
else if (sub_pos.x < 4.0) {
ret = mix(vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g , COLOR_LOW * center.b, 1),
vec4(COLOR_LOW * right.r , COLOR_HIGH * center.g, COLOR_HIGH * center.b, 1),
sub_pos.x - 3);
sub_pos.x - 3.0);
}
else if (sub_pos.x < 5.0) {
ret = mix(vec4(COLOR_LOW * right.r, COLOR_HIGH * center.g , COLOR_HIGH * center.b, 1),
vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1),
sub_pos.x - 4);
sub_pos.x - 4.0);
}
else {
ret = mix(vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1),
vec4(COLOR_HIGH * right.r, COLOR_LOW * right.g , COLOR_HIGH * center.b, 1),
sub_pos.x - 5);
sub_pos.x - 5.0);
}
/* Anti alias the curve */
vec2 pixel_position = position * output_resolution;
if (pixel_position.x < 1) {
if (pixel_position.x < 1.0) {
ret *= pixel_position.x;
}
else if (pixel_position.x > output_resolution.x - 1) {
else if (pixel_position.x > output_resolution.x - 1.0) {
ret *= output_resolution.x - pixel_position.x;
}
if (pixel_position.y < 1) {
if (pixel_position.y < 1.0) {
ret *= pixel_position.y;
}
else if (pixel_position.y > output_resolution.y - 1) {
else if (pixel_position.y > output_resolution.y - 1.0) {
ret *= output_resolution.y - pixel_position.y;
}

View File

@@ -5,7 +5,7 @@
STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
{
vec2 pos = fract(position * input_resolution);
vec2 sub_pos = pos * 6;
vec2 sub_pos = pos * 6.0;
vec4 center = texture_relative(image, position, vec2(0, 0));
vec4 left = texture_relative(image, position, vec2(-1, 0));
@@ -15,17 +15,17 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
center = mix(center, texture_relative(image, position, vec2( 0, -1)), 0.5 - sub_pos.y / 2.0);
left = mix(left, texture_relative(image, position, vec2(-1, -1)), 0.5 - sub_pos.y / 2.0);
right = mix(right, texture_relative(image, position, vec2( 1, -1)), 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);
center *= sub_pos.y * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
left *= sub_pos.y * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
right *= sub_pos.y * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
}
else if (sub_pos.y > 5.0) {
center = mix(center, texture_relative(image, position, vec2( 0, 1)), (sub_pos.y - 5) / 2.0);
left = mix(left, texture_relative(image, position, vec2(-1, 1)), (sub_pos.y - 5) / 2.0);
right = mix(right, texture_relative(image, position, vec2( 1, 1)), (sub_pos.y - 5) / 2.0);
center *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
left *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
right *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
center = mix(center, texture_relative(image, position, vec2( 0, 1)), (sub_pos.y - 5.0) / 2.0);
left = mix(left, texture_relative(image, position, vec2(-1, 1)), (sub_pos.y - 5.0) / 2.0);
right = mix(right, texture_relative(image, position, vec2( 1, 1)), (sub_pos.y - 5.0) / 2.0);
center *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
left *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
right *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
}
@@ -41,27 +41,27 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
else if (sub_pos.x < 2.0) {
ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1),
vec4(COLOR_HIGH * center.r, COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1),
sub_pos.x - 1);
sub_pos.x - 1.0);
}
else if (sub_pos.x < 3.0) {
ret = mix(vec4(COLOR_HIGH * center.r , COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1),
vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g, COLOR_LOW * center.b, 1),
sub_pos.x - 2);
sub_pos.x - 2.0);
}
else if (sub_pos.x < 4.0) {
ret = mix(vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g , COLOR_LOW * center.b, 1),
vec4(COLOR_LOW * right.r , COLOR_HIGH * center.g, COLOR_HIGH * center.b, 1),
sub_pos.x - 3);
sub_pos.x - 3.0);
}
else if (sub_pos.x < 5.0) {
ret = mix(vec4(COLOR_LOW * right.r, COLOR_HIGH * center.g , COLOR_HIGH * center.b, 1),
vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1),
sub_pos.x - 4);
sub_pos.x - 4.0);
}
else {
ret = mix(vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1),
vec4(COLOR_HIGH * right.r, COLOR_LOW * right.g , COLOR_HIGH * center.b, 1),
sub_pos.x - 5);
sub_pos.x - 5.0);
}
return ret;

View File

@@ -16,22 +16,22 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
vec4 r2 = mix(q12, q22, s.x);
vec2 pos = fract(position * input_resolution);
vec2 sub_pos = pos * 6;
vec2 sub_pos = pos * 6.0;
float multiplier = 1.0;
if (sub_pos.y < 1.0) {
multiplier *= sub_pos.y * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
multiplier *= sub_pos.y * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
}
else if (sub_pos.y > 5.0) {
multiplier *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
multiplier *= (6.0 - sub_pos.y) * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
}
if (sub_pos.x < 1.0) {
multiplier *= sub_pos.x * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
multiplier *= sub_pos.x * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
}
else if (sub_pos.x > 5.0) {
multiplier *= (6.0 - sub_pos.x) * SCANLINE_DEPTH + (1 - SCANLINE_DEPTH);
multiplier *= (6.0 - sub_pos.x) * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
}
vec4 pre_shadow = mix(texture(image, position) * multiplier, mix(r1, r2, s.y), BLOOM);

View File

@@ -87,7 +87,7 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
if (P(0x2F,0x2F)) {
float dist = length(p - vec2(0.5));
float pixel_size = length(1.0 / (output_resolution / input_resolution));
if (dist < 0.5 - pixel_size / 2) {
if (dist < 0.5 - pixel_size / 2.0) {
return w4;
}
vec4 r;
@@ -98,40 +98,40 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
r = mix(mix(w1 * 0.375 + w0 * 0.25 + w3 * 0.375, w3, p.y * 2.0), w1, p.x * 2.0);
}
if (dist > 0.5 + pixel_size / 2) {
if (dist > 0.5 + pixel_size / 2.0) {
return r;
}
return mix(w4, r, (dist - 0.5 + pixel_size / 2) / pixel_size);
return mix(w4, r, (dist - 0.5 + pixel_size / 2.0) / pixel_size);
}
if (P(0xBF,0x37) || P(0xDB,0x13)) {
float dist = p.x - 2.0 * p.y;
float pixel_size = length(1.0 / (output_resolution / input_resolution)) * sqrt(5.0);
if (dist > pixel_size / 2) {
if (dist > pixel_size / 2.0) {
return w1;
}
vec4 r = mix(w3, w4, p.x + 0.5);
if (dist < -pixel_size / 2) {
if (dist < -pixel_size / 2.0) {
return r;
}
return mix(r, w1, (dist + pixel_size / 2) / pixel_size);
return mix(r, w1, (dist + pixel_size / 2.0) / pixel_size);
}
if (P(0xDB,0x49) || P(0xEF,0x6D)) {
float dist = p.y - 2.0 * p.x;
float pixel_size = length(1.0 / (output_resolution / input_resolution)) * sqrt(5.0);
if (p.y - 2.0 * p.x > pixel_size / 2) {
if (p.y - 2.0 * p.x > pixel_size / 2.0) {
return w3;
}
vec4 r = mix(w1, w4, p.x + 0.5);
if (dist < -pixel_size / 2) {
if (dist < -pixel_size / 2.0) {
return r;
}
return mix(r, w3, (dist + pixel_size / 2) / pixel_size);
return mix(r, w3, (dist + pixel_size / 2.0) / pixel_size);
}
if (P(0xBF,0x8F) || P(0x7E,0x0E)) {
float dist = p.x + 2.0 * p.y;
float pixel_size = length(1.0 / (output_resolution / input_resolution)) * sqrt(5.0);
if (dist > 1.0 + pixel_size / 2) {
if (dist > 1.0 + pixel_size / 2.0) {
return w4;
}
@@ -143,18 +143,18 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
r = mix(mix(w1 * 0.375 + w0 * 0.25 + w3 * 0.375, w3, p.y * 2.0), w1, p.x * 2.0);
}
if (dist < 1.0 - pixel_size / 2) {
if (dist < 1.0 - pixel_size / 2.0) {
return r;
}
return mix(r, w4, (dist + pixel_size / 2 - 1.0) / pixel_size);
return mix(r, w4, (dist + pixel_size / 2.0 - 1.0) / pixel_size);
}
if (P(0x7E,0x2A) || P(0xEF,0xAB)) {
float dist = p.y + 2.0 * p.x;
float pixel_size = length(1.0 / (output_resolution / input_resolution)) * sqrt(5.0);
if (p.y + 2.0 * p.x > 1.0 + pixel_size / 2) {
if (p.y + 2.0 * p.x > 1.0 + pixel_size / 2.0) {
return w4;
}
@@ -167,11 +167,11 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
r = mix(mix(w1 * 0.375 + w0 * 0.25 + w3 * 0.375, w3, p.y * 2.0), w1, p.x * 2.0);
}
if (dist < 1.0 - pixel_size / 2) {
if (dist < 1.0 - pixel_size / 2.0) {
return r;
}
return mix(r, w4, (dist + pixel_size / 2 - 1.0) / pixel_size);
return mix(r, w4, (dist + pixel_size / 2.0 - 1.0) / pixel_size);
}
if (P(0x1B,0x03) || P(0x4F,0x43) || P(0x8B,0x83) || P(0x6B,0x43)) {
@@ -193,7 +193,7 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
float dist = p.x + p.y;
float pixel_size = length(1.0 / (output_resolution / input_resolution));
if (dist > 0.5 + pixel_size / 2) {
if (dist > 0.5 + pixel_size / 2.0) {
return w4;
}
@@ -205,11 +205,11 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
r = mix(mix(w1 * 0.375 + w0 * 0.25 + w3 * 0.375, w3, p.y * 2.0), w1, p.x * 2.0);
}
if (dist < 0.5 - pixel_size / 2) {
if (dist < 0.5 - pixel_size / 2.0) {
return r;
}
return mix(r, w4, (dist + pixel_size / 2 - 0.5) / pixel_size);
return mix(r, w4, (dist + pixel_size / 2.0 - 0.5) / pixel_size);
}
if (P(0x0B,0x01)) {
@@ -223,7 +223,7 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
float dist = p.x + p.y;
float pixel_size = length(1.0 / (output_resolution / input_resolution));
if (dist > 0.5 + pixel_size / 2) {
if (dist > 0.5 + pixel_size / 2.0) {
return w4;
}
@@ -252,10 +252,10 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
if (diagonal_bias <= 0) {
vec4 r = mix(w1, w3, p.y - p.x + 0.5);
if (dist < 0.5 - pixel_size / 2) {
if (dist < 0.5 - pixel_size / 2.0) {
return r;
}
return mix(r, w4, (dist + pixel_size / 2 - 0.5) / pixel_size);
return mix(r, w4, (dist + pixel_size / 2.0 - 0.5) / pixel_size);
}
return w4;

View File

@@ -33,8 +33,8 @@ STATIC vec4 scale2x(sampler2D image, vec2 position, vec2 input_resolution, vec2
STATIC vec4 scale2x_wrapper(sampler2D t, vec2 pos, vec2 offset, vec2 input_resolution, vec2 output_resolution)
{
vec2 origin = (floor(pos * input_resolution * 2)) + vec2(0.5, 0.5);
return scale2x(t, (origin + offset) / input_resolution / 2, input_resolution, output_resolution);
vec2 origin = (floor(pos * input_resolution * 2.0)) + vec2(0.5, 0.5);
return scale2x(t, (origin + offset) / input_resolution / 2.0, input_resolution, output_resolution);
}
STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)