Scaling filters in Metal
This commit is contained in:
parent
4466a55de6
commit
cd045fde15
@ -54,10 +54,11 @@ static const vector_float2 rect[] =
|
||||
length:sizeof(default_mix_value)
|
||||
options:MTLResourceStorageModeShared];
|
||||
|
||||
output_resolution_buffer = [device newBufferWithBytes:&default_mix_value
|
||||
length:sizeof(default_mix_value)
|
||||
output_resolution_buffer = [device newBufferWithBytes:&output_resolution
|
||||
length:sizeof(output_resolution)
|
||||
options:MTLResourceStorageModeShared];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loadShader) name:@"GBFilterChanged" object:nil];
|
||||
[self loadShader];
|
||||
}
|
||||
|
||||
@ -69,11 +70,25 @@ static const vector_float2 rect[] =
|
||||
inDirectory:@"Shaders"]
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:nil];
|
||||
|
||||
NSString *shader_name = [[NSUserDefaults standardUserDefaults] objectForKey:@"GBFilter"];
|
||||
NSString *scaler_source = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:shader_name
|
||||
ofType:@"fsh"
|
||||
inDirectory:@"Shaders"]
|
||||
encoding:NSUTF8StringEncoding
|
||||
error:nil];
|
||||
|
||||
shader_source = [shader_source stringByReplacingOccurrencesOfString:@"{filter}"
|
||||
withString:scaler_source];
|
||||
|
||||
id<MTLLibrary> library = [device newLibraryWithSource:shader_source
|
||||
options:nil
|
||||
error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Error: %@", error);
|
||||
if (!library) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
id<MTLFunction> vertex_function = [library newFunctionWithName:@"vertex_shader"];
|
||||
@ -90,6 +105,7 @@ static const vector_float2 rect[] =
|
||||
error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Failed to created pipeline state, error %@", error);
|
||||
return;
|
||||
}
|
||||
|
||||
command_queue = [device newCommandQueue];
|
||||
|
@ -18,16 +18,16 @@ vec4 omniScale(sampler2D image, vec2 position, vec2 input_resolution, vec2 outpu
|
||||
/* Special handling for diaonals */
|
||||
bool hasDownDiagonal = false;
|
||||
bool hasUpDiagonal = false;
|
||||
if (q12 == q21 && q11 != q22) hasUpDiagonal = true;
|
||||
else if (q12 != q21 && q11 == q22) hasDownDiagonal = true;
|
||||
else if (q12 == q21 && q11 == q22) {
|
||||
if (q11 == q12) return q11;
|
||||
if (equal(q12, q21) && inequal(q11, q22)) hasUpDiagonal = true;
|
||||
else if (inequal(q12, q21) && equal(q11, q22)) hasDownDiagonal = true;
|
||||
else if (equal(q12, q21) && equal(q11, q22)) {
|
||||
if (equal(q11, q12)) return q11;
|
||||
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)) / input_resolution);
|
||||
if (color == q11) diagonalBias++;
|
||||
if (color == q12) diagonalBias--;
|
||||
if (equal(color, q11)) diagonalBias++;
|
||||
if (equal(color, q12)) diagonalBias--;
|
||||
}
|
||||
}
|
||||
if (diagonalBias <= 0) {
|
||||
@ -89,15 +89,15 @@ vec4 omniScale(sampler2D image, vec2 position, vec2 input_resolution, vec2 outpu
|
||||
min(q12d,
|
||||
q22d)));
|
||||
|
||||
if (q11d == best) {
|
||||
if (equal(q11d, best)) {
|
||||
return q11;
|
||||
}
|
||||
|
||||
if (q21d == best) {
|
||||
if (equal(q21d, best)) {
|
||||
return q21;
|
||||
}
|
||||
|
||||
if (q12d == best) {
|
||||
if (equal(q12d, best)) {
|
||||
return q12;
|
||||
}
|
||||
|
||||
|
@ -22,18 +22,18 @@ vec4 scale2x(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_
|
||||
if (p.x > .5) {
|
||||
if (p.y > .5) {
|
||||
// Top Right
|
||||
return B == F && B != D && F != H ? F : E;
|
||||
return equal(B, F) && inequal(B, D) && inequal(F, H) ? F : E;
|
||||
} else {
|
||||
// Bottom Right
|
||||
return H == F && D != H && B != F ? F : E;
|
||||
return equal(H, F) && inequal(D, H) && inequal(B, F) ? F : E;
|
||||
}
|
||||
} else {
|
||||
if (p.y > .5) {
|
||||
// Top Left
|
||||
return D == B && B != F && D != H ? D : E;
|
||||
return equal(D, B) && inequal(B, F) && inequal(D, H) ? D : E;
|
||||
} else {
|
||||
// Bottom Left
|
||||
return D == H && D != B && H != F ? D : E;
|
||||
return equal(D, H) && inequal(D, B) && inequal(H, F) ? D : E;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,18 +21,18 @@ vec4 scale2x(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_
|
||||
if (p.x > .5) {
|
||||
if (p.y > .5) {
|
||||
// Top Right
|
||||
return B == F && B != D && F != H ? F : E;
|
||||
return equal(B, F) && inequal(B, D) && inequal(F, H) ? F : E;
|
||||
} else {
|
||||
// Bottom Right
|
||||
return H == F && D != H && B != F ? F : E;
|
||||
return equal(H, F) && inequal(D, H) && inequal(B, F) ? F : E;
|
||||
}
|
||||
} else {
|
||||
if (p.y > .5) {
|
||||
// Top Left
|
||||
return D == B && B != F && D != H ? D : E;
|
||||
return equal(D, B) && inequal(B, F) && inequal(D, H) ? D : E;
|
||||
} else {
|
||||
// Bottom Left
|
||||
return D == H && D != B && H != F ? D : E;
|
||||
return equal(D, H) && inequal(D, B) && inequal(H, F) ? D : E;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -67,18 +67,18 @@ vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_re
|
||||
if (p.x > .5) {
|
||||
if (p.y > .5) {
|
||||
// Top Right
|
||||
R = B == F && B != D && F != H ? F : E;
|
||||
R = equal(B, F) && inequal(B, D) && inequal(F, H) ? F : E;
|
||||
} else {
|
||||
// Bottom Right
|
||||
R = H == F && D != H && B != F ? F : E;
|
||||
R = equal(H, F) && inequal(D, H) && inequal(B, F) ? F : E;
|
||||
}
|
||||
} else {
|
||||
if (p.y > .5) {
|
||||
// Top Left
|
||||
R = D == B && B != F && D != H ? D : E;
|
||||
R = equal(D, B) && inequal(B, F) && inequal(D, H) ? D : E;
|
||||
} else {
|
||||
// Bottom Left
|
||||
R = D == H && D != B && H != F ? D : E;
|
||||
R = equal(D, H) && inequal(D, B) && inequal(H, F) ? D : E;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,9 @@ uniform vec2 output_resolution;
|
||||
uniform vec2 origin;
|
||||
const vec2 input_resolution = vec2(160, 144);
|
||||
|
||||
#define equal(x, y) ((x) == (y))
|
||||
#define inequal(x, y) ((x) != (y))
|
||||
|
||||
out vec4 frag_color;
|
||||
|
||||
#line 1
|
||||
|
@ -9,6 +9,9 @@ constant float2 input_resolution = float2(160, 144);
|
||||
typedef float2 vec2;
|
||||
typedef float3 vec3;
|
||||
typedef float4 vec4;
|
||||
typedef texture2d<half> sampler2D;
|
||||
#define equal(x, y) all((x) == (y))
|
||||
#define inequal(x, y) any((x) != (y))
|
||||
|
||||
typedef struct {
|
||||
float4 position [[position]];
|
||||
@ -36,6 +39,8 @@ static inline float4 texture(texture2d<half> texture, float2 pos)
|
||||
return float4(texture.sample(texture_sampler, pos));
|
||||
}
|
||||
|
||||
#line 1
|
||||
{filter}
|
||||
|
||||
fragment float4 fragment_shader(rasterizer_data in [[stage_in]],
|
||||
texture2d<half> image [[ texture(0) ]],
|
||||
@ -45,8 +50,9 @@ fragment float4 fragment_shader(rasterizer_data in [[stage_in]],
|
||||
{
|
||||
in.texcoords.y = 1 - in.texcoords.y;
|
||||
if (*mix_previous) {
|
||||
return mix(texture(image, in.texcoords), texture(previous_image, in.texcoords), 0.5);
|
||||
return mix(scale(image, in.texcoords, input_resolution, *output_resolution),
|
||||
scale(previous_image, in.texcoords, input_resolution, *output_resolution), 0.5);
|
||||
}
|
||||
return texture(image, in.texcoords);
|
||||
return scale(image, in.texcoords, input_resolution, *output_resolution);
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_re
|
||||
}
|
||||
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);
|
||||
float pixel_size = length(1.0 / (output_resolution / input_resolution)) * sqrt(5.0);
|
||||
if (dist > pixel_size / 2) {
|
||||
return w1;
|
||||
}
|
||||
@ -111,7 +111,7 @@ vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_re
|
||||
}
|
||||
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);
|
||||
float pixel_size = length(1.0 / (output_resolution / input_resolution)) * sqrt(5.0);
|
||||
if (p.y - 2.0 * p.x > pixel_size / 2) {
|
||||
return w3;
|
||||
}
|
||||
@ -123,7 +123,7 @@ vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_re
|
||||
}
|
||||
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);
|
||||
float pixel_size = length(1.0 / (output_resolution / input_resolution)) * sqrt(5.0);
|
||||
|
||||
if (dist > 1.0 + pixel_size / 2) {
|
||||
return w4;
|
||||
@ -147,7 +147,7 @@ vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_re
|
||||
|
||||
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);
|
||||
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) {
|
||||
return w4;
|
||||
|
@ -18,16 +18,16 @@ vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_re
|
||||
/* Special handling for diaonals */
|
||||
bool hasDownDiagonal = false;
|
||||
bool hasUpDiagonal = false;
|
||||
if (q12 == q21 && q11 != q22) hasUpDiagonal = true;
|
||||
else if (q12 != q21 && q11 == q22) hasDownDiagonal = true;
|
||||
else if (q12 == q21 && q11 == q22) {
|
||||
if (q11 == q12) return q11;
|
||||
if (equal(q12, q21) && inequal(q11, q22)) hasUpDiagonal = true;
|
||||
else if (inequal(q12, q21) && equal(q11, q22)) hasDownDiagonal = true;
|
||||
else if (equal(q12, q21) && equal(q11, q22)) {
|
||||
if (equal(q11, q12)) return q11;
|
||||
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)) / input_resolution);
|
||||
if (color == q11) diagonalBias++;
|
||||
if (color == q12) diagonalBias--;
|
||||
if (equal(color, q11)) diagonalBias++;
|
||||
if (equal(color, q12)) diagonalBias--;
|
||||
}
|
||||
}
|
||||
if (diagonalBias <= 0) {
|
||||
@ -89,15 +89,15 @@ vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_re
|
||||
min(q12d,
|
||||
q22d)));
|
||||
|
||||
if (q11d == best) {
|
||||
if (equal(q11d, best)) {
|
||||
return q11;
|
||||
}
|
||||
|
||||
if (q21d == best) {
|
||||
if (equal(q21d, best)) {
|
||||
return q21;
|
||||
}
|
||||
|
||||
if (q12d == best) {
|
||||
if (equal(q12d, best)) {
|
||||
return q12;
|
||||
}
|
||||
|
||||
|
@ -24,18 +24,18 @@ vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_re
|
||||
if (p.x > .5) {
|
||||
if (p.y > .5) {
|
||||
// Top Right
|
||||
return B == F && B != D && F != H ? F : E;
|
||||
return equal(B, F) && inequal(B, D) && inequal(F, H) ? F : E;
|
||||
} else {
|
||||
// Bottom Right
|
||||
return H == F && D != H && B != F ? F : E;
|
||||
return equal(H, F) && inequal(D, H) && inequal(B, F) ? F : E;
|
||||
}
|
||||
} else {
|
||||
if (p.y > .5) {
|
||||
// Top Left
|
||||
return D == B && B != F && D != H ? D : E;
|
||||
return equal(D, B) && inequal(B, F) && inequal(D, H) ? D : E;
|
||||
} else {
|
||||
// Bottom Left
|
||||
return D == H && D != B && H != F ? D : E;
|
||||
return equal(D, H) && inequal(D, B) && inequal(H, F) ? D : E;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,18 +22,18 @@ vec4 scale2x(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_
|
||||
if (p.x > .5) {
|
||||
if (p.y > .5) {
|
||||
// Top Right
|
||||
return B == F && B != D && F != H ? F : E;
|
||||
return equal(B, F) && inequal(B, D) && inequal(F, H) ? F : E;
|
||||
} else {
|
||||
// Bottom Right
|
||||
return H == F && D != H && B != F ? F : E;
|
||||
return equal(H, F) && inequal(D, H) && inequal(B, F) ? F : E;
|
||||
}
|
||||
} else {
|
||||
if (p.y > .5) {
|
||||
// Top Left
|
||||
return D == B && B != F && D != H ? D : E;
|
||||
return equal(D, B) && inequal(B, F) && inequal(D, H) ? D : E;
|
||||
} else {
|
||||
// Bottom Left
|
||||
return D == H && D != B && H != F ? D : E;
|
||||
return equal(D, H) && inequal(D, B) && inequal(H, F) ? D : E;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -62,18 +62,18 @@ vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_re
|
||||
if (p.x > .5) {
|
||||
if (p.y > .5) {
|
||||
// Top Right
|
||||
return B == F && B != D && F != H ? F : E;
|
||||
return equal(B, F) && inequal(B, D) && inequal(F, H) ? F : E;
|
||||
} else {
|
||||
// Bottom Right
|
||||
return H == F && D != H && B != F ? F : E;
|
||||
return equal(H, F) && inequal(D, H) && inequal(B, F) ? F : E;
|
||||
}
|
||||
} else {
|
||||
if (p.y > .5) {
|
||||
// Top Left
|
||||
return D == B && B != F && D != H ? D : E;
|
||||
return equal(D, B) && inequal(B, F) && inequal(D, H) ? D : E;
|
||||
} else {
|
||||
// Bottom Left
|
||||
return D == H && D != B && H != F ? D : E;
|
||||
return equal(D, H) && inequal(D, B) && inequal(H, F) ? D : E;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user