SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
Shaders/MasterShader.metal
1 #include <metal_stdlib>
2 #include <simd/simd.h>
3 #include <metal_math>
4
5 using namespace metal;
6
7 /* For GLSL compatibility */
8 typedef float2 vec2;
9 typedef float3 vec3;
10 typedef float4 vec4;
11 typedef texture2d<half> sampler2D;
12 #define equal(x, y) all((x) == (y))
13 #define inequal(x, y) any((x) != (y))
14 #define STATIC static
15 #define GAMMA (2.2)
16
17 typedef struct {
18 float4 position [[position]];
19 float2 texcoords;
20 } rasterizer_data;
21
22 // Vertex Function
23 vertex rasterizer_data vertex_shader(uint index [[ vertex_id ]],
24 constant vector_float2 *vertices [[ buffer(0) ]])
25 {
26 rasterizer_data out;
27
28 out.position.xy = vertices[index].xy;
29 out.position.z = 0.0;
30 out.position.w = 1.0;
31 out.texcoords = (vertices[index].xy + float2(1, 1)) / 2.0;
32
33 return out;
34 }
35
36
37 static inline float4 texture(texture2d<half> texture, float2 pos)
38 {
39 constexpr sampler texture_sampler;
40 return pow(float4(texture.sample(texture_sampler, pos)), GAMMA);
41 }
42
43 __attribute__((unused)) static inline float4 texture_relative(texture2d<half> t, float2 pos, float2 offset)
44 {
45 float2 input_resolution = float2(t.get_width(), t.get_height());
46 float2 origin = (floor(pos * input_resolution)) + float2(0.5, 0.5);
47 return texture(t, (origin + offset) / input_resolution);
48 }
49
50 #line 1
51 {filter}
52
53 #define BLEND_BIAS (1.0/3.0)
54
55 enum frame_blending_mode {
56 DISABLED,
57 SIMPLE,
58 ACCURATE,
59 ACCURATE_EVEN = ACCURATE,
60 ACCURATE_ODD,
61 };
62
63 fragment float4 fragment_shader(rasterizer_data in [[stage_in]],
64 texture2d<half> image [[ texture(0) ]],
65 texture2d<half> previous_image [[ texture(1) ]],
66 constant enum frame_blending_mode *frame_blending_mode [[ buffer(0) ]],
67 constant float2 *output_resolution [[ buffer(1) ]])
68 {
69 float2 input_resolution = float2(image.get_width(), image.get_height());
70
71 in.texcoords.y = 1 - in.texcoords.y;
72 float ratio;
73 switch (*frame_blending_mode) {
74 default:
75 case DISABLED:
76 return pow(scale(image, in.texcoords, input_resolution, *output_resolution), 1 / GAMMA);
77 case SIMPLE:
78 ratio = 0.5;
79 break;
80 case ACCURATE_EVEN:
81 if (((int)(in.texcoords.y * input_resolution.y) & 1) == 0) {
82 ratio = BLEND_BIAS;
83 }
84 else {
85 ratio = 1 - BLEND_BIAS;
86 }
87 break;
88 case ACCURATE_ODD:
89 if (((int)(in.texcoords.y * input_resolution.y) & 1) == 0) {
90 ratio = 1 - BLEND_BIAS;
91 }
92 else {
93 ratio = BLEND_BIAS;
94 }
95 break;
96 }
97
98 return pow(mix(scale(image, in.texcoords, input_resolution, *output_resolution),
99 scale(previous_image, in.texcoords, input_resolution, *output_resolution), ratio), 1 / GAMMA);
100 }
101
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.