Fix shader artifacts, revise AAScale4x

This commit is contained in:
Lior Halphon 2022-07-29 17:08:51 +03:00
parent 859ff79527
commit 84a193a918
10 changed files with 102 additions and 121 deletions

View File

@ -1,21 +1,15 @@
STATIC vec4 scale2x(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
{
// o = offset, the width of a pixel
vec2 o = 1.0 / input_resolution;
{
// texel arrangement
// A B C
// D E F
// G H I
// 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));
vec4 B = texture_relative(image, position, vec2( 0, 1));
vec4 D = texture_relative(image, position, vec2( -1, 0));
vec4 E = texture_relative(image, position, vec2( 0, 0));
vec4 F = texture_relative(image, position, vec2( 1, 0));
vec4 H = texture_relative(image, position, vec2( 0, -1));
vec2 p = position * input_resolution;
// p = the position within a pixel [0...1]
p = fract(p);

View File

@ -1,20 +1,15 @@
STATIC vec4 scale2x(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
{
// o = offset, the width of a pixel
vec2 o = 1.0 / input_resolution;
// texel arrangement
// A B C
// D E F
// G H I
// 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));
vec4 B = texture_relative(image, position, vec2( 0, 1));
vec4 D = texture_relative(image, position, vec2( -1, 0));
vec4 E = texture_relative(image, position, vec2( 0, 0));
vec4 F = texture_relative(image, position, vec2( 1, 0));
vec4 H = texture_relative(image, position, vec2( 0, -1));
vec2 p = position * input_resolution;
// p = the position within a pixel [0...1]
p = fract(p);
@ -36,30 +31,24 @@ STATIC vec4 scale2x(sampler2D image, vec2 position, vec2 input_resolution, vec2
}
}
}
STATIC vec4 aaScale2x(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
STATIC vec4 scale2x_wrapper(sampler2D t, vec2 pos, vec2 offset, vec2 input_resolution, vec2 output_resolution)
{
return mix(texture(image, position), scale2x(image, position, input_resolution, output_resolution), 0.5);
vec2 origin = (floor(pos * input_resolution * 2)) + vec2(0.5, 0.5);
return scale2x(t, (origin + offset) / input_resolution / 2, input_resolution, output_resolution);
}
STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
{
// o = offset, the width of a pixel
vec2 o = 1.0 / (input_resolution * 2.);
// texel arrangement
// A B C
// D E F
// G H I
// vec4 A = aaScale2x(image, position + vec2( -o.x, o.y), input_resolution, output_resolution);
vec4 B = aaScale2x(image, position + vec2( 0, o.y), input_resolution, output_resolution);
// vec4 C = aaScale2x(image, position + vec2( o.x, o.y), input_resolution, output_resolution);
vec4 D = aaScale2x(image, position + vec2( -o.x, 0), input_resolution, output_resolution);
vec4 E = aaScale2x(image, position + vec2( 0, 0), input_resolution, output_resolution);
vec4 F = aaScale2x(image, position + vec2( o.x, 0), input_resolution, output_resolution);
// vec4 G = aaScale2x(image, position + vec2( -o.x, -o.y), input_resolution, output_resolution);
vec4 H = aaScale2x(image, position + vec2( 0, -o.y), input_resolution, output_resolution);
// vec4 I = aaScale2x(image, position + vec2( o.x, -o.y), input_resolution, output_resolution);
vec4 B = scale2x_wrapper(image, position, vec2( 0, 1), input_resolution, output_resolution);
vec4 D = scale2x_wrapper(image, position, vec2( -1, 0), input_resolution, output_resolution);
vec4 E = scale2x_wrapper(image, position, vec2( 0, 0), input_resolution, output_resolution);
vec4 F = scale2x_wrapper(image, position, vec2( 1, 0), input_resolution, output_resolution);
vec4 H = scale2x_wrapper(image, position, vec2( 0, -1), input_resolution, output_resolution);
vec4 R;
vec2 p = position * input_resolution * 2.;
// p = the position within a pixel [0...1]

View File

@ -25,20 +25,20 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
vec2 pos = fract(position * input_resolution);
vec2 sub_pos = fract(position * input_resolution * 6);
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));
vec4 center = texture_relative(image, position, vec2(0, 0));
vec4 left = texture_relative(image, position, vec2(-1, 0));
vec4 right = texture_relative(image, position, vec2(1, 0));
/* Vertical blurring */
if (pos.y < 1.0 / 6.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 = 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);
}
else if (pos.y > 5.0 / 6.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 = mix(center, texture_relative(image, position, vec2( 0, 1)), sub_pos.y / 2.0);
left = mix(left, texture_relative(image, position, vec2(-1, 1)), sub_pos.y / 2.0);
right = mix(right, texture_relative(image, position, vec2( 1, 1)), sub_pos.y / 2.0);
}
/* Scanlines */

View File

@ -30,7 +30,7 @@ STATIC vec4 interp_3px(vec4 c1, float w1, vec4 c2, float w2, vec4 c3, float w3)
STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
{
// o = offset, the width of a pixel
vec2 o = 1.0 / input_resolution;
vec2 o = vec2(1, 1);
/* We always calculate the top left pixel. If we need a different pixel, we flip the image */
@ -40,17 +40,15 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
if (p.x > 0.5) o.x = -o.x;
if (p.y > 0.5) o.y = -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));
vec4 w0 = texture_relative(image, position, vec2( -o.x, -o.y));
vec4 w1 = texture_relative(image, position, vec2( 0, -o.y));
vec4 w2 = texture_relative(image, position, vec2( o.x, -o.y));
vec4 w3 = texture_relative(image, position, vec2( -o.x, 0));
vec4 w4 = texture_relative(image, position, vec2( 0, 0));
vec4 w5 = texture_relative(image, position, vec2( o.x, 0));
vec4 w6 = texture_relative(image, position, vec2( -o.x, o.y));
vec4 w7 = texture_relative(image, position, vec2( 0, o.y));
vec4 w8 = texture_relative(image, position, vec2( o.x, o.y));
int pattern = 0;
if (is_different(w0, w4)) pattern |= 1;

View File

@ -7,22 +7,22 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
vec2 pos = fract(position * input_resolution);
vec2 sub_pos = fract(position * input_resolution * 6);
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));
vec4 center = texture_relative(image, position, vec2(0, 0));
vec4 left = texture_relative(image, position, vec2(-1, 0));
vec4 right = texture_relative(image, position, vec2(1, 0));
if (pos.y < 1.0 / 6.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 = 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);
}
else if (pos.y > 5.0 / 6.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 = mix(center, texture_relative(image, position, vec2( 0, 1)), sub_pos.y / 2.0);
left = mix(left, texture_relative(image, position, vec2(-1, 1)), sub_pos.y / 2.0);
right = mix(right, texture_relative(image, position, vec2( 1, 1)), 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);

View File

@ -18,6 +18,12 @@ vec4 _texture(sampler2D t, vec2 pos)
return pow(texture(t, pos), vec4(GAMMA));
}
vec4 texture_relative(sampler2D t, vec2 pos, vec2 offset)
{
vec2 input_resolution = textureSize(t, 0);
return _texture(t, (floor(pos * input_resolution) + offset + vec2(0.5, 0.5)) / input_resolution);
}
#define texture _texture
#line 1

View File

@ -40,6 +40,13 @@ static inline float4 texture(texture2d<half> texture, float2 pos)
return pow(float4(texture.sample(texture_sampler, pos)), GAMMA);
}
__attribute__((unused)) static inline float4 texture_relative(texture2d<half> t, float2 pos, float2 offset)
{
float2 input_resolution = float2(t.get_width(), t.get_height());;
float2 origin = (floor(pos * input_resolution)) + float2(0.5, 0.5);
return texture(t, (origin + offset) / input_resolution);
}
#line 1
{filter}

View File

@ -27,7 +27,7 @@ STATIC bool is_different(vec4 a, vec4 b)
STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
{
// o = offset, the width of a pixel
vec2 o = 1.0 / input_resolution;
vec2 o = vec2(1, 1);
/* We always calculate the top left quarter. If we need a different quarter, we flip our co-ordinates */
@ -43,15 +43,15 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
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 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));
vec4 w0 = texture_relative(image, position, vec2( -o.x, -o.y));
vec4 w1 = texture_relative(image, position, vec2( 0, -o.y));
vec4 w2 = texture_relative(image, position, vec2( o.x, -o.y));
vec4 w3 = texture_relative(image, position, vec2( -o.x, 0));
vec4 w4 = texture_relative(image, position, vec2( 0, 0));
vec4 w5 = texture_relative(image, position, vec2( o.x, 0));
vec4 w6 = texture_relative(image, position, vec2( -o.x, o.y));
vec4 w7 = texture_relative(image, position, vec2( 0, o.y));
vec4 w8 = texture_relative(image, position, vec2( o.x, o.y));
int pattern = 0;
if (is_different(w0, w4)) pattern |= 1 << 0;
@ -228,13 +228,13 @@ STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 ou
}
/* We need more samples to "solve" this diagonal */
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 ));
vec4 x0 = texture_relative(image, position, vec2( -o.x * 2.0, -o.y * 2.0));
vec4 x1 = texture_relative(image, position, vec2( -o.x , -o.y * 2.0));
vec4 x2 = texture_relative(image, position, vec2( 0.0 , -o.y * 2.0));
vec4 x3 = texture_relative(image, position, vec2( o.x , -o.y * 2.0));
vec4 x4 = texture_relative(image, position, vec2( -o.x * 2.0, -o.y ));
vec4 x5 = texture_relative(image, position, vec2( -o.x * 2.0, 0.0 ));
vec4 x6 = texture_relative(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;

View File

@ -2,22 +2,16 @@
STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
{
// o = offset, the width of a pixel
vec2 o = 1.0 / input_resolution;
// texel arrangement
// A B C
// D E F
// G H I
// 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));
vec4 B = texture_relative(image, position, vec2( 0, 1));
vec4 D = texture_relative(image, position, vec2( -1, 0));
vec4 E = texture_relative(image, position, vec2( 0, 0));
vec4 F = texture_relative(image, position, vec2( 1, 0));
vec4 H = texture_relative(image, position, vec2( 0, -1));
vec2 p = position * input_resolution;
// p = the position within a pixel [0...1]
p = fract(p);

View File

@ -1,23 +1,16 @@
STATIC vec4 scale2x(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
{
// o = offset, the width of a pixel
vec2 o = 1.0 / input_resolution;
// texel arrangement
// A B C
// D E F
// G H I
// 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));
vec4 B = texture_relative(image, position, vec2( 0, 1));
vec4 D = texture_relative(image, position, vec2( -1, 0));
vec4 E = texture_relative(image, position, vec2( 0, 0));
vec4 F = texture_relative(image, position, vec2( 1, 0));
vec4 H = texture_relative(image, position, vec2( 0, -1));
vec2 p = position * input_resolution;
// p = the position within a pixel [0...1]
vec4 R;
p = fract(p);
if (p.x > .5) {
if (p.y > .5) {
@ -38,24 +31,24 @@ 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);
}
STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
{
// o = offset, the width of a pixel
vec2 o = 1.0 / (input_resolution * 2.);
// texel arrangement
// A B C
// D E F
// G H I
// vec4 A = scale2x(image, position + vec2( -o.x, o.y), input_resolution, output_resolution);
vec4 B = scale2x(image, position + vec2( 0, o.y), input_resolution, output_resolution);
// vec4 C = scale2x(image, position + vec2( o.x, o.y), input_resolution, output_resolution);
vec4 D = scale2x(image, position + vec2( -o.x, 0), input_resolution, output_resolution);
vec4 E = scale2x(image, position + vec2( 0, 0), input_resolution, output_resolution);
vec4 F = scale2x(image, position + vec2( o.x, 0), input_resolution, output_resolution);
// vec4 G = scale2x(image, position + vec2( -o.x, -o.y), input_resolution, output_resolution);
vec4 H = scale2x(image, position + vec2( 0, -o.y), input_resolution, output_resolution);
// vec4 I = scale2x(image, position + vec2( o.x, -o.y), input_resolution, output_resolution);
vec4 B = scale2x_wrapper(image, position, vec2( 0, 1), input_resolution, output_resolution);
vec4 D = scale2x_wrapper(image, position, vec2( -1, 0), input_resolution, output_resolution);
vec4 E = scale2x_wrapper(image, position, vec2( 0, 0), input_resolution, output_resolution);
vec4 F = scale2x_wrapper(image, position, vec2( 1, 0), input_resolution, output_resolution);
vec4 H = scale2x_wrapper(image, position, vec2( 0, -1), input_resolution, output_resolution);
vec2 p = position * input_resolution * 2.;
// p = the position within a pixel [0...1]
p = fract(p);