refactor: eliminar sistema de shaders externos (ShaderManager + GpuShaderPreset)
Elimina el sistema multi-pass de shaders runtime en favor del PostFX nativo. Queda solo el ciclo de 5 modos nativos: OFF → Vinyeta → Scanlines → Cromàtica → Complet. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,28 +0,0 @@
|
||||
# Based on dannyld's rainbow settings
|
||||
|
||||
shaders = 2
|
||||
|
||||
shader0 = "../crt/shaders/mame_hlsl/shaders/mame_ntsc_encode.slang"
|
||||
filter_linear0 = "true"
|
||||
scale_type0 = "source"
|
||||
scale0 = "1.000000"
|
||||
|
||||
shader1 = "../crt/shaders/mame_hlsl/shaders/mame_ntsc_decode.slang"
|
||||
filter_linear1 = "true"
|
||||
scale_type1 = "source"
|
||||
scale_1 = "1.000000"
|
||||
|
||||
# ntsc parameters
|
||||
ntscsignal = "1.000000"
|
||||
avalue = "0.000000"
|
||||
bvalue = "0.000000"
|
||||
scantime = "47.900070"
|
||||
|
||||
# optional blur
|
||||
shadowalpha = "0.100000"
|
||||
notch_width = "3.450001"
|
||||
ifreqresponse = "1.750000"
|
||||
qfreqresponse = "1.450000"
|
||||
|
||||
# uncomment for jailbars in blue
|
||||
#pvalue = "1.100000"
|
||||
@@ -1,69 +0,0 @@
|
||||
#version 450
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
// Adapted from mame_ntsc_encode.slang for SDL3 GPU / Vulkan SPIRV
|
||||
|
||||
layout(location=0) in vec2 v_uv;
|
||||
layout(location=0) out vec4 FragColor;
|
||||
|
||||
layout(set=2, binding=0) uniform sampler2D Source;
|
||||
|
||||
layout(set=3, binding=0) uniform NTSCParams {
|
||||
float source_width;
|
||||
float source_height;
|
||||
float a_value;
|
||||
float b_value;
|
||||
float cc_value;
|
||||
float scan_time;
|
||||
float notch_width;
|
||||
float y_freq;
|
||||
float i_freq;
|
||||
float q_freq;
|
||||
float _pad0;
|
||||
float _pad1;
|
||||
} u;
|
||||
|
||||
const float PI = 3.1415927;
|
||||
const float PI2 = PI * 2.0;
|
||||
|
||||
void main() {
|
||||
vec2 source_dims = vec2(u.source_width, u.source_height);
|
||||
|
||||
// p_value=1: one texel step per sub-sample (no horizontal stretch)
|
||||
vec2 PValueSourceTexel = vec2(1.0, 0.0) / source_dims;
|
||||
|
||||
vec2 C0 = v_uv + PValueSourceTexel * vec2(0.00, 0.0);
|
||||
vec2 C1 = v_uv + PValueSourceTexel * vec2(0.25, 0.0);
|
||||
vec2 C2 = v_uv + PValueSourceTexel * vec2(0.50, 0.0);
|
||||
vec2 C3 = v_uv + PValueSourceTexel * vec2(0.75, 0.0);
|
||||
|
||||
vec4 Cx = vec4(C0.x, C1.x, C2.x, C3.x);
|
||||
vec4 Cy = vec4(C0.y, C1.y, C2.y, C3.y);
|
||||
|
||||
vec4 Texel0 = texture(Source, C0);
|
||||
vec4 Texel1 = texture(Source, C1);
|
||||
vec4 Texel2 = texture(Source, C2);
|
||||
vec4 Texel3 = texture(Source, C3);
|
||||
|
||||
vec4 HPosition = Cx;
|
||||
vec4 VPosition = Cy;
|
||||
|
||||
const vec4 YDot = vec4(0.299, 0.587, 0.114, 0.0);
|
||||
const vec4 IDot = vec4(0.595716, -0.274453, -0.321263, 0.0);
|
||||
const vec4 QDot = vec4(0.211456, -0.522591, 0.311135, 0.0);
|
||||
|
||||
vec4 Y = vec4(dot(Texel0, YDot), dot(Texel1, YDot), dot(Texel2, YDot), dot(Texel3, YDot));
|
||||
vec4 I = vec4(dot(Texel0, IDot), dot(Texel1, IDot), dot(Texel2, IDot), dot(Texel3, IDot));
|
||||
vec4 Q = vec4(dot(Texel0, QDot), dot(Texel1, QDot), dot(Texel2, QDot), dot(Texel3, QDot));
|
||||
|
||||
float W = PI2 * u.cc_value * u.scan_time;
|
||||
float WoPI = W / PI;
|
||||
|
||||
float HOffset = u.a_value / WoPI;
|
||||
float VScale = u.b_value * source_dims.y / WoPI;
|
||||
|
||||
vec4 T = HPosition + vec4(HOffset) + VPosition * vec4(VScale);
|
||||
vec4 TW = T * W;
|
||||
|
||||
FragColor = Y + I * cos(TW) + Q * sin(TW);
|
||||
}
|
||||
Binary file not shown.
@@ -1,61 +0,0 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct NTSCParams
|
||||
{
|
||||
float source_width;
|
||||
float source_height;
|
||||
float a_value;
|
||||
float b_value;
|
||||
float cc_value;
|
||||
float scan_time;
|
||||
float notch_width;
|
||||
float y_freq;
|
||||
float i_freq;
|
||||
float q_freq;
|
||||
float _pad0;
|
||||
float _pad1;
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float2 v_uv [[user(locn0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], constant NTSCParams& u [[buffer(0)]], texture2d<float> Source [[texture(0)]], sampler SourceSmplr [[sampler(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float2 source_dims = float2(u.source_width, u.source_height);
|
||||
float2 PValueSourceTexel = float2(1.0, 0.0) / source_dims;
|
||||
float2 C0 = in.v_uv + (PValueSourceTexel * float2(0.0));
|
||||
float2 C1 = in.v_uv + (PValueSourceTexel * float2(0.25, 0.0));
|
||||
float2 C2 = in.v_uv + (PValueSourceTexel * float2(0.5, 0.0));
|
||||
float2 C3 = in.v_uv + (PValueSourceTexel * float2(0.75, 0.0));
|
||||
float4 Cx = float4(C0.x, C1.x, C2.x, C3.x);
|
||||
float4 Cy = float4(C0.y, C1.y, C2.y, C3.y);
|
||||
float4 Texel0 = Source.sample(SourceSmplr, C0);
|
||||
float4 Texel1 = Source.sample(SourceSmplr, C1);
|
||||
float4 Texel2 = Source.sample(SourceSmplr, C2);
|
||||
float4 Texel3 = Source.sample(SourceSmplr, C3);
|
||||
float4 HPosition = Cx;
|
||||
float4 VPosition = Cy;
|
||||
float4 Y = float4(dot(Texel0, float4(0.2989999949932098388671875, 0.58700001239776611328125, 0.114000000059604644775390625, 0.0)), dot(Texel1, float4(0.2989999949932098388671875, 0.58700001239776611328125, 0.114000000059604644775390625, 0.0)), dot(Texel2, float4(0.2989999949932098388671875, 0.58700001239776611328125, 0.114000000059604644775390625, 0.0)), dot(Texel3, float4(0.2989999949932098388671875, 0.58700001239776611328125, 0.114000000059604644775390625, 0.0)));
|
||||
float4 I = float4(dot(Texel0, float4(0.595715999603271484375, -0.2744530141353607177734375, -0.3212629854679107666015625, 0.0)), dot(Texel1, float4(0.595715999603271484375, -0.2744530141353607177734375, -0.3212629854679107666015625, 0.0)), dot(Texel2, float4(0.595715999603271484375, -0.2744530141353607177734375, -0.3212629854679107666015625, 0.0)), dot(Texel3, float4(0.595715999603271484375, -0.2744530141353607177734375, -0.3212629854679107666015625, 0.0)));
|
||||
float4 Q = float4(dot(Texel0, float4(0.211456000804901123046875, -0.52259099483489990234375, 0.311134994029998779296875, 0.0)), dot(Texel1, float4(0.211456000804901123046875, -0.52259099483489990234375, 0.311134994029998779296875, 0.0)), dot(Texel2, float4(0.211456000804901123046875, -0.52259099483489990234375, 0.311134994029998779296875, 0.0)), dot(Texel3, float4(0.211456000804901123046875, -0.52259099483489990234375, 0.311134994029998779296875, 0.0)));
|
||||
float W = (6.283185482025146484375 * u.cc_value) * u.scan_time;
|
||||
float WoPI = W / 3.1415927410125732421875;
|
||||
float HOffset = u.a_value / WoPI;
|
||||
float VScale = (u.b_value * source_dims.y) / WoPI;
|
||||
float4 T = (HPosition + float4(HOffset)) + (VPosition * float4(VScale));
|
||||
float4 TW = T * W;
|
||||
out.FragColor = (Y + (I * cos(TW))) + (Q * sin(TW));
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#version 450
|
||||
layout(location=0) out vec2 v_uv;
|
||||
void main() {
|
||||
vec2 positions[3] = vec2[3](vec2(-1.0,-1.0), vec2(3.0,-1.0), vec2(-1.0,3.0));
|
||||
vec2 uvs[3] = vec2[3](vec2(0.0, 1.0), vec2(2.0, 1.0), vec2(0.0,-1.0));
|
||||
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
||||
v_uv = uvs[gl_VertexIndex];
|
||||
}
|
||||
Binary file not shown.
@@ -1,63 +0,0 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
template<typename T, size_t Num>
|
||||
struct spvUnsafeArray
|
||||
{
|
||||
T elements[Num ? Num : 1];
|
||||
|
||||
thread T& operator [] (size_t pos) thread
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const thread T& operator [] (size_t pos) const thread
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
device T& operator [] (size_t pos) device
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const device T& operator [] (size_t pos) const device
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
constexpr const constant T& operator [] (size_t pos) const constant
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
threadgroup T& operator [] (size_t pos) threadgroup
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
};
|
||||
|
||||
constant spvUnsafeArray<float2, 3> _18 = spvUnsafeArray<float2, 3>({ float2(-1.0), float2(3.0, -1.0), float2(-1.0, 3.0) });
|
||||
constant spvUnsafeArray<float2, 3> _26 = spvUnsafeArray<float2, 3>({ float2(0.0, 1.0), float2(2.0, 1.0), float2(0.0, -1.0) });
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float2 v_uv [[user(locn0)]];
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(uint gl_VertexIndex [[vertex_id]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = float4(_18[int(gl_VertexIndex)], 0.0, 1.0);
|
||||
out.v_uv = _26[int(gl_VertexIndex)];
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
#version 450
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz,ImJezze
|
||||
// Adapted from mame_ntsc_decode.slang for SDL3 GPU / Vulkan SPIRV
|
||||
|
||||
layout(location=0) in vec2 v_uv;
|
||||
layout(location=0) out vec4 FragColor;
|
||||
|
||||
layout(set=2, binding=0) uniform sampler2D Source;
|
||||
|
||||
layout(set=3, binding=0) uniform NTSCParams {
|
||||
float source_width;
|
||||
float source_height;
|
||||
float a_value;
|
||||
float b_value;
|
||||
float cc_value;
|
||||
float scan_time;
|
||||
float notch_width;
|
||||
float y_freq;
|
||||
float i_freq;
|
||||
float q_freq;
|
||||
float _pad0;
|
||||
float _pad1;
|
||||
} u;
|
||||
|
||||
const float PI = 3.1415927;
|
||||
const float PI2 = PI * 2.0;
|
||||
|
||||
const vec3 RDot = vec3(1.0, 0.956, 0.621);
|
||||
const vec3 GDot = vec3(1.0, -0.272, -0.647);
|
||||
const vec3 BDot = vec3(1.0, -1.106, 1.703);
|
||||
|
||||
const vec4 NotchOffset = vec4(0.0, 1.0, 2.0, 3.0);
|
||||
const int SampleCount = 64;
|
||||
const int HalfSampleCount = 32;
|
||||
|
||||
void main() {
|
||||
vec2 source_dims = vec2(u.source_width, u.source_height);
|
||||
vec4 BaseTexel = texture(Source, v_uv);
|
||||
|
||||
float CCValue = u.cc_value;
|
||||
float ScanTime = u.scan_time;
|
||||
float NotchHalfWidth = u.notch_width / 2.0;
|
||||
float YFreqResponse = u.y_freq;
|
||||
float IFreqResponse = u.i_freq;
|
||||
float QFreqResponse = u.q_freq;
|
||||
float AValue = u.a_value;
|
||||
float BValue = u.b_value;
|
||||
|
||||
float TimePerSample = ScanTime / (source_dims.x * 4.0);
|
||||
|
||||
float Fc_y1 = (CCValue - NotchHalfWidth) * TimePerSample;
|
||||
float Fc_y2 = (CCValue + NotchHalfWidth) * TimePerSample;
|
||||
float Fc_y3 = YFreqResponse * TimePerSample;
|
||||
float Fc_i = IFreqResponse * TimePerSample;
|
||||
float Fc_q = QFreqResponse * TimePerSample;
|
||||
|
||||
float Fc_i_2 = Fc_i * 2.0;
|
||||
float Fc_q_2 = Fc_q * 2.0;
|
||||
float Fc_y1_2 = Fc_y1 * 2.0;
|
||||
float Fc_y2_2 = Fc_y2 * 2.0;
|
||||
float Fc_y3_2 = Fc_y3 * 2.0;
|
||||
float Fc_i_pi2 = Fc_i * PI2;
|
||||
float Fc_q_pi2 = Fc_q * PI2;
|
||||
float Fc_y1_pi2 = Fc_y1 * PI2;
|
||||
float Fc_y2_pi2 = Fc_y2 * PI2;
|
||||
float Fc_y3_pi2 = Fc_y3 * PI2;
|
||||
float PI2Length = PI2 / float(SampleCount);
|
||||
|
||||
float W = PI2 * CCValue * ScanTime;
|
||||
float WoPI = W / PI;
|
||||
|
||||
float HOffset = BValue / WoPI;
|
||||
float VScale = AValue * source_dims.y / WoPI;
|
||||
|
||||
vec4 YAccum = vec4(0.0);
|
||||
vec4 IAccum = vec4(0.0);
|
||||
vec4 QAccum = vec4(0.0);
|
||||
|
||||
vec4 Cy = vec4(v_uv.y);
|
||||
vec4 VPosition = Cy;
|
||||
|
||||
for (float i = 0.0; i < float(SampleCount); i += 4.0) {
|
||||
float n = i - float(HalfSampleCount);
|
||||
vec4 n4 = n + NotchOffset;
|
||||
|
||||
vec4 Cx = vec4(v_uv.x) + (n4 * 0.25) / source_dims.x;
|
||||
vec4 HPosition = Cx;
|
||||
|
||||
vec4 C = texture(Source, vec2(Cx.r, Cy.r));
|
||||
vec4 T = HPosition + vec4(HOffset) + VPosition * vec4(VScale);
|
||||
vec4 WT = W * T;
|
||||
|
||||
vec4 SincKernel = 0.54 + 0.46 * cos(PI2Length * n4);
|
||||
|
||||
vec4 SincYIn1 = Fc_y1_pi2 * n4;
|
||||
vec4 SincYIn2 = Fc_y2_pi2 * n4;
|
||||
vec4 SincYIn3 = Fc_y3_pi2 * n4;
|
||||
vec4 SincIIn = Fc_i_pi2 * n4;
|
||||
vec4 SincQIn = Fc_q_pi2 * n4;
|
||||
|
||||
vec4 SincY1, SincY2, SincY3;
|
||||
SincY1.x = (SincYIn1.x != 0.0) ? sin(SincYIn1.x) / SincYIn1.x : 1.0;
|
||||
SincY1.y = (SincYIn1.y != 0.0) ? sin(SincYIn1.y) / SincYIn1.y : 1.0;
|
||||
SincY1.z = (SincYIn1.z != 0.0) ? sin(SincYIn1.z) / SincYIn1.z : 1.0;
|
||||
SincY1.w = (SincYIn1.w != 0.0) ? sin(SincYIn1.w) / SincYIn1.w : 1.0;
|
||||
SincY2.x = (SincYIn2.x != 0.0) ? sin(SincYIn2.x) / SincYIn2.x : 1.0;
|
||||
SincY2.y = (SincYIn2.y != 0.0) ? sin(SincYIn2.y) / SincYIn2.y : 1.0;
|
||||
SincY2.z = (SincYIn2.z != 0.0) ? sin(SincYIn2.z) / SincYIn2.z : 1.0;
|
||||
SincY2.w = (SincYIn2.w != 0.0) ? sin(SincYIn2.w) / SincYIn2.w : 1.0;
|
||||
SincY3.x = (SincYIn3.x != 0.0) ? sin(SincYIn3.x) / SincYIn3.x : 1.0;
|
||||
SincY3.y = (SincYIn3.y != 0.0) ? sin(SincYIn3.y) / SincYIn3.y : 1.0;
|
||||
SincY3.z = (SincYIn3.z != 0.0) ? sin(SincYIn3.z) / SincYIn3.z : 1.0;
|
||||
SincY3.w = (SincYIn3.w != 0.0) ? sin(SincYIn3.w) / SincYIn3.w : 1.0;
|
||||
|
||||
vec4 IdealY = Fc_y1_2 * SincY1 - Fc_y2_2 * SincY2 + Fc_y3_2 * SincY3;
|
||||
|
||||
vec4 IdealI, IdealQ;
|
||||
IdealI.x = Fc_i_2 * ((SincIIn.x != 0.0) ? sin(SincIIn.x) / SincIIn.x : 1.0);
|
||||
IdealI.y = Fc_i_2 * ((SincIIn.y != 0.0) ? sin(SincIIn.y) / SincIIn.y : 1.0);
|
||||
IdealI.z = Fc_i_2 * ((SincIIn.z != 0.0) ? sin(SincIIn.z) / SincIIn.z : 1.0);
|
||||
IdealI.w = Fc_i_2 * ((SincIIn.w != 0.0) ? sin(SincIIn.w) / SincIIn.w : 1.0);
|
||||
IdealQ.x = Fc_q_2 * ((SincQIn.x != 0.0) ? sin(SincQIn.x) / SincQIn.x : 1.0);
|
||||
IdealQ.y = Fc_q_2 * ((SincQIn.y != 0.0) ? sin(SincQIn.y) / SincQIn.y : 1.0);
|
||||
IdealQ.z = Fc_q_2 * ((SincQIn.z != 0.0) ? sin(SincQIn.z) / SincQIn.z : 1.0);
|
||||
IdealQ.w = Fc_q_2 * ((SincQIn.w != 0.0) ? sin(SincQIn.w) / SincQIn.w : 1.0);
|
||||
|
||||
vec4 FilterY = SincKernel * IdealY;
|
||||
vec4 FilterI = SincKernel * IdealI;
|
||||
vec4 FilterQ = SincKernel * IdealQ;
|
||||
|
||||
YAccum += C * FilterY;
|
||||
IAccum += C * cos(WT) * FilterI;
|
||||
QAccum += C * sin(WT) * FilterQ;
|
||||
}
|
||||
|
||||
vec3 YIQ = vec3(
|
||||
(YAccum.r + YAccum.g + YAccum.b + YAccum.a),
|
||||
(IAccum.r + IAccum.g + IAccum.b + IAccum.a) * 2.0,
|
||||
(QAccum.r + QAccum.g + QAccum.b + QAccum.a) * 2.0);
|
||||
|
||||
vec3 RGB = vec3(
|
||||
dot(YIQ, RDot),
|
||||
dot(YIQ, GDot),
|
||||
dot(YIQ, BDot));
|
||||
|
||||
FragColor = vec4(RGB, BaseTexel.a);
|
||||
}
|
||||
Binary file not shown.
@@ -1,304 +0,0 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
struct NTSCParams
|
||||
{
|
||||
float source_width;
|
||||
float source_height;
|
||||
float a_value;
|
||||
float b_value;
|
||||
float cc_value;
|
||||
float scan_time;
|
||||
float notch_width;
|
||||
float y_freq;
|
||||
float i_freq;
|
||||
float q_freq;
|
||||
float _pad0;
|
||||
float _pad1;
|
||||
};
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float4 FragColor [[color(0)]];
|
||||
};
|
||||
|
||||
struct main0_in
|
||||
{
|
||||
float2 v_uv [[user(locn0)]];
|
||||
};
|
||||
|
||||
fragment main0_out main0(main0_in in [[stage_in]], constant NTSCParams& u [[buffer(0)]], texture2d<float> Source [[texture(0)]], sampler SourceSmplr [[sampler(0)]])
|
||||
{
|
||||
main0_out out = {};
|
||||
float2 source_dims = float2(u.source_width, u.source_height);
|
||||
float4 BaseTexel = Source.sample(SourceSmplr, in.v_uv);
|
||||
float CCValue = u.cc_value;
|
||||
float ScanTime = u.scan_time;
|
||||
float NotchHalfWidth = u.notch_width / 2.0;
|
||||
float YFreqResponse = u.y_freq;
|
||||
float IFreqResponse = u.i_freq;
|
||||
float QFreqResponse = u.q_freq;
|
||||
float AValue = u.a_value;
|
||||
float BValue = u.b_value;
|
||||
float TimePerSample = ScanTime / (source_dims.x * 4.0);
|
||||
float Fc_y1 = (CCValue - NotchHalfWidth) * TimePerSample;
|
||||
float Fc_y2 = (CCValue + NotchHalfWidth) * TimePerSample;
|
||||
float Fc_y3 = YFreqResponse * TimePerSample;
|
||||
float Fc_i = IFreqResponse * TimePerSample;
|
||||
float Fc_q = QFreqResponse * TimePerSample;
|
||||
float Fc_i_2 = Fc_i * 2.0;
|
||||
float Fc_q_2 = Fc_q * 2.0;
|
||||
float Fc_y1_2 = Fc_y1 * 2.0;
|
||||
float Fc_y2_2 = Fc_y2 * 2.0;
|
||||
float Fc_y3_2 = Fc_y3 * 2.0;
|
||||
float Fc_i_pi2 = Fc_i * 6.283185482025146484375;
|
||||
float Fc_q_pi2 = Fc_q * 6.283185482025146484375;
|
||||
float Fc_y1_pi2 = Fc_y1 * 6.283185482025146484375;
|
||||
float Fc_y2_pi2 = Fc_y2 * 6.283185482025146484375;
|
||||
float Fc_y3_pi2 = Fc_y3 * 6.283185482025146484375;
|
||||
float PI2Length = 0.098174773156642913818359375;
|
||||
float W = (6.283185482025146484375 * CCValue) * ScanTime;
|
||||
float WoPI = W / 3.1415927410125732421875;
|
||||
float HOffset = BValue / WoPI;
|
||||
float VScale = (AValue * source_dims.y) / WoPI;
|
||||
float4 YAccum = float4(0.0);
|
||||
float4 IAccum = float4(0.0);
|
||||
float4 QAccum = float4(0.0);
|
||||
float4 Cy = float4(in.v_uv.y);
|
||||
float4 VPosition = Cy;
|
||||
float4 SincY1;
|
||||
float _259;
|
||||
float _274;
|
||||
float _290;
|
||||
float _306;
|
||||
float4 SincY2;
|
||||
float _322;
|
||||
float _337;
|
||||
float _352;
|
||||
float _367;
|
||||
float4 SincY3;
|
||||
float _383;
|
||||
float _398;
|
||||
float _413;
|
||||
float _428;
|
||||
float4 IdealI;
|
||||
float _457;
|
||||
float _474;
|
||||
float _491;
|
||||
float _508;
|
||||
float4 IdealQ;
|
||||
float _526;
|
||||
float _543;
|
||||
float _560;
|
||||
float _577;
|
||||
for (float i = 0.0; i < 64.0; i += 4.0)
|
||||
{
|
||||
float n = i - 32.0;
|
||||
float4 n4 = float4(n) + float4(0.0, 1.0, 2.0, 3.0);
|
||||
float4 Cx = float4(in.v_uv.x) + ((n4 * 0.25) / float4(source_dims.x));
|
||||
float4 HPosition = Cx;
|
||||
float4 C = Source.sample(SourceSmplr, float2(Cx.x, Cy.x));
|
||||
float4 T = (HPosition + float4(HOffset)) + (VPosition * float4(VScale));
|
||||
float4 WT = T * W;
|
||||
float4 SincKernel = float4(0.540000021457672119140625) + (cos(n4 * PI2Length) * 0.4600000083446502685546875);
|
||||
float4 SincYIn1 = n4 * Fc_y1_pi2;
|
||||
float4 SincYIn2 = n4 * Fc_y2_pi2;
|
||||
float4 SincYIn3 = n4 * Fc_y3_pi2;
|
||||
float4 SincIIn = n4 * Fc_i_pi2;
|
||||
float4 SincQIn = n4 * Fc_q_pi2;
|
||||
if (SincYIn1.x != 0.0)
|
||||
{
|
||||
_259 = sin(SincYIn1.x) / SincYIn1.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
_259 = 1.0;
|
||||
}
|
||||
SincY1.x = _259;
|
||||
if (SincYIn1.y != 0.0)
|
||||
{
|
||||
_274 = sin(SincYIn1.y) / SincYIn1.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
_274 = 1.0;
|
||||
}
|
||||
SincY1.y = _274;
|
||||
if (SincYIn1.z != 0.0)
|
||||
{
|
||||
_290 = sin(SincYIn1.z) / SincYIn1.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
_290 = 1.0;
|
||||
}
|
||||
SincY1.z = _290;
|
||||
if (SincYIn1.w != 0.0)
|
||||
{
|
||||
_306 = sin(SincYIn1.w) / SincYIn1.w;
|
||||
}
|
||||
else
|
||||
{
|
||||
_306 = 1.0;
|
||||
}
|
||||
SincY1.w = _306;
|
||||
if (SincYIn2.x != 0.0)
|
||||
{
|
||||
_322 = sin(SincYIn2.x) / SincYIn2.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
_322 = 1.0;
|
||||
}
|
||||
SincY2.x = _322;
|
||||
if (SincYIn2.y != 0.0)
|
||||
{
|
||||
_337 = sin(SincYIn2.y) / SincYIn2.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
_337 = 1.0;
|
||||
}
|
||||
SincY2.y = _337;
|
||||
if (SincYIn2.z != 0.0)
|
||||
{
|
||||
_352 = sin(SincYIn2.z) / SincYIn2.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
_352 = 1.0;
|
||||
}
|
||||
SincY2.z = _352;
|
||||
if (SincYIn2.w != 0.0)
|
||||
{
|
||||
_367 = sin(SincYIn2.w) / SincYIn2.w;
|
||||
}
|
||||
else
|
||||
{
|
||||
_367 = 1.0;
|
||||
}
|
||||
SincY2.w = _367;
|
||||
if (SincYIn3.x != 0.0)
|
||||
{
|
||||
_383 = sin(SincYIn3.x) / SincYIn3.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
_383 = 1.0;
|
||||
}
|
||||
SincY3.x = _383;
|
||||
if (SincYIn3.y != 0.0)
|
||||
{
|
||||
_398 = sin(SincYIn3.y) / SincYIn3.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
_398 = 1.0;
|
||||
}
|
||||
SincY3.y = _398;
|
||||
if (SincYIn3.z != 0.0)
|
||||
{
|
||||
_413 = sin(SincYIn3.z) / SincYIn3.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
_413 = 1.0;
|
||||
}
|
||||
SincY3.z = _413;
|
||||
if (SincYIn3.w != 0.0)
|
||||
{
|
||||
_428 = sin(SincYIn3.w) / SincYIn3.w;
|
||||
}
|
||||
else
|
||||
{
|
||||
_428 = 1.0;
|
||||
}
|
||||
SincY3.w = _428;
|
||||
float4 IdealY = ((SincY1 * Fc_y1_2) - (SincY2 * Fc_y2_2)) + (SincY3 * Fc_y3_2);
|
||||
if (SincIIn.x != 0.0)
|
||||
{
|
||||
_457 = sin(SincIIn.x) / SincIIn.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
_457 = 1.0;
|
||||
}
|
||||
IdealI.x = Fc_i_2 * _457;
|
||||
if (SincIIn.y != 0.0)
|
||||
{
|
||||
_474 = sin(SincIIn.y) / SincIIn.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
_474 = 1.0;
|
||||
}
|
||||
IdealI.y = Fc_i_2 * _474;
|
||||
if (SincIIn.z != 0.0)
|
||||
{
|
||||
_491 = sin(SincIIn.z) / SincIIn.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
_491 = 1.0;
|
||||
}
|
||||
IdealI.z = Fc_i_2 * _491;
|
||||
if (SincIIn.w != 0.0)
|
||||
{
|
||||
_508 = sin(SincIIn.w) / SincIIn.w;
|
||||
}
|
||||
else
|
||||
{
|
||||
_508 = 1.0;
|
||||
}
|
||||
IdealI.w = Fc_i_2 * _508;
|
||||
if (SincQIn.x != 0.0)
|
||||
{
|
||||
_526 = sin(SincQIn.x) / SincQIn.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
_526 = 1.0;
|
||||
}
|
||||
IdealQ.x = Fc_q_2 * _526;
|
||||
if (SincQIn.y != 0.0)
|
||||
{
|
||||
_543 = sin(SincQIn.y) / SincQIn.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
_543 = 1.0;
|
||||
}
|
||||
IdealQ.y = Fc_q_2 * _543;
|
||||
if (SincQIn.z != 0.0)
|
||||
{
|
||||
_560 = sin(SincQIn.z) / SincQIn.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
_560 = 1.0;
|
||||
}
|
||||
IdealQ.z = Fc_q_2 * _560;
|
||||
if (SincQIn.w != 0.0)
|
||||
{
|
||||
_577 = sin(SincQIn.w) / SincQIn.w;
|
||||
}
|
||||
else
|
||||
{
|
||||
_577 = 1.0;
|
||||
}
|
||||
IdealQ.w = Fc_q_2 * _577;
|
||||
float4 FilterY = SincKernel * IdealY;
|
||||
float4 FilterI = SincKernel * IdealI;
|
||||
float4 FilterQ = SincKernel * IdealQ;
|
||||
YAccum += (C * FilterY);
|
||||
IAccum += ((C * cos(WT)) * FilterI);
|
||||
QAccum += ((C * sin(WT)) * FilterQ);
|
||||
}
|
||||
float3 YIQ = float3(((YAccum.x + YAccum.y) + YAccum.z) + YAccum.w, (((IAccum.x + IAccum.y) + IAccum.z) + IAccum.w) * 2.0, (((QAccum.x + QAccum.y) + QAccum.z) + QAccum.w) * 2.0);
|
||||
float3 RGB = float3(dot(YIQ, float3(1.0, 0.95599997043609619140625, 0.620999991893768310546875)), dot(YIQ, float3(1.0, -0.272000014781951904296875, -0.647000014781951904296875)), dot(YIQ, float3(1.0, -1.10599994659423828125, 1.70299994945526123046875)));
|
||||
out.FragColor = float4(RGB, BaseTexel.w);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#version 450
|
||||
layout(location=0) out vec2 v_uv;
|
||||
void main() {
|
||||
vec2 positions[3] = vec2[3](vec2(-1.0,-1.0), vec2(3.0,-1.0), vec2(-1.0,3.0));
|
||||
vec2 uvs[3] = vec2[3](vec2(0.0, 1.0), vec2(2.0, 1.0), vec2(0.0,-1.0));
|
||||
gl_Position = vec4(positions[gl_VertexIndex], 0.0, 1.0);
|
||||
v_uv = uvs[gl_VertexIndex];
|
||||
}
|
||||
Binary file not shown.
@@ -1,63 +0,0 @@
|
||||
#pragma clang diagnostic ignored "-Wmissing-prototypes"
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
using namespace metal;
|
||||
|
||||
template<typename T, size_t Num>
|
||||
struct spvUnsafeArray
|
||||
{
|
||||
T elements[Num ? Num : 1];
|
||||
|
||||
thread T& operator [] (size_t pos) thread
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const thread T& operator [] (size_t pos) const thread
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
device T& operator [] (size_t pos) device
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const device T& operator [] (size_t pos) const device
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
constexpr const constant T& operator [] (size_t pos) const constant
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
|
||||
threadgroup T& operator [] (size_t pos) threadgroup
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
constexpr const threadgroup T& operator [] (size_t pos) const threadgroup
|
||||
{
|
||||
return elements[pos];
|
||||
}
|
||||
};
|
||||
|
||||
constant spvUnsafeArray<float2, 3> _18 = spvUnsafeArray<float2, 3>({ float2(-1.0), float2(3.0, -1.0), float2(-1.0, 3.0) });
|
||||
constant spvUnsafeArray<float2, 3> _26 = spvUnsafeArray<float2, 3>({ float2(0.0, 1.0), float2(2.0, 1.0), float2(0.0, -1.0) });
|
||||
|
||||
struct main0_out
|
||||
{
|
||||
float2 v_uv [[user(locn0)]];
|
||||
float4 gl_Position [[position]];
|
||||
};
|
||||
|
||||
vertex main0_out main0(uint gl_VertexIndex [[vertex_id]])
|
||||
{
|
||||
main0_out out = {};
|
||||
out.gl_Position = float4(_18[int(gl_VertexIndex)], 0.0, 1.0);
|
||||
out.v_uv = _26[int(gl_VertexIndex)];
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
name = ntsc-md-rainbows
|
||||
passes = 2
|
||||
|
||||
pass0_vert = pass0_encode.vert
|
||||
pass0_frag = pass0_encode.frag
|
||||
|
||||
pass1_vert = pass1_decode.vert
|
||||
pass1_frag = pass1_decode.frag
|
||||
|
||||
; NTSC parameters (mapped to NTSCParams uniform buffer)
|
||||
scantime = 47.9
|
||||
avalue = 0.0
|
||||
bvalue = 0.0
|
||||
ccvalue = 3.5795455
|
||||
notch_width = 3.45
|
||||
yfreqresponse = 1.75
|
||||
ifreqresponse = 1.75
|
||||
qfreqresponse = 1.45
|
||||
Reference in New Issue
Block a user