Files
vibe3_physics/data/shaders/ntsc-md-rainbows/pass0_encode.frag.spv.msl
Sergio Valor 5b4a970157 feat(macos): suport Metal per GpuShaderPreset via spirv-cross
- CMakeLists: bloc if(APPLE) que transpila .spv → .spv.msl amb spirv-cross
- gpu_shader_preset: carrega MSL (main0) a macOS, SPIR-V (main) a la resta
- Afegeix null-terminator als buffers MSL (SDL3 els tracta com C-string)
- README: secció de dependències de shaders per plataforma (Vulkan SDK, spirv-cross)
- Inclou .spv.msl generats per ntsc-md-rainbows

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 13:54:05 +01:00

62 lines
3.1 KiB
Plaintext

#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;
}