SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
Shaders/AAOmniScaleLegacy.fsh
1
2 STATIC float quickDistance(vec4 a, vec4 b)
3 {
4 return abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z);
5 }
6
7 STATIC vec4 omniScale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
8 {
9 vec2 pixel = position * input_resolution - vec2(0.5, 0.5);
10
11 vec4 q11 = texture(image, (floor(pixel) + 0.5) / input_resolution);
12 vec4 q12 = texture(image, (vec2(floor(pixel.x), ceil(pixel.y)) + 0.5) / input_resolution);
13 vec4 q21 = texture(image, (vec2(ceil(pixel.x), floor(pixel.y)) + 0.5) / input_resolution);
14 vec4 q22 = texture(image, (ceil(pixel) + 0.5) / input_resolution);
15
16 vec2 pos = fract(pixel);
17
18 /* Special handling for diaonals */
19 bool hasDownDiagonal = false;
20 bool hasUpDiagonal = false;
21 if (equal(q12, q21) && inequal(q11, q22)) hasUpDiagonal = true;
22 else if (inequal(q12, q21) && equal(q11, q22)) hasDownDiagonal = true;
23 else if (equal(q12, q21) && equal(q11, q22)) {
24 if (equal(q11, q12)) return q11;
25 int diagonalBias = 0;
26 for (float y = -1.0; y < 3.0; y++) {
27 for (float x = -1.0; x < 3.0; x++) {
28 vec4 color = texture(image, (pixel + vec2(x, y)) / input_resolution);
29 if (equal(color, q11)) diagonalBias++;
30 if (equal(color, q12)) diagonalBias--;
31 }
32 }
33 if (diagonalBias <= 0) {
34 hasDownDiagonal = true;
35 }
36 if (diagonalBias >= 0) {
37 hasUpDiagonal = true;
38 }
39 }
40
41 if (hasUpDiagonal || hasDownDiagonal) {
42 vec4 downDiagonalResult, upDiagonalResult;
43
44 if (hasUpDiagonal) {
45 float diagonalPos = pos.x + pos.y;
46
47 if (diagonalPos < 0.5) {
48 upDiagonalResult = q11;
49 }
50 else if (diagonalPos > 1.5) {
51 upDiagonalResult = q22;
52 }
53 else {
54 upDiagonalResult = q12;
55 }
56 }
57
58 if (hasDownDiagonal) {
59 float diagonalPos = 1.0 - pos.x + pos.y;
60
61 if (diagonalPos < 0.5) {
62 downDiagonalResult = q21;
63 }
64 else if (diagonalPos > 1.5) {
65 downDiagonalResult = q12;
66 }
67 else {
68 downDiagonalResult = q11;
69 }
70 }
71
72 if (!hasUpDiagonal) return downDiagonalResult;
73 if (!hasDownDiagonal) return upDiagonalResult;
74 return mix(downDiagonalResult, upDiagonalResult, 0.5);
75 }
76
77 vec4 r1 = mix(q11, q21, fract(pos.x));
78 vec4 r2 = mix(q12, q22, fract(pos.x));
79
80 vec4 unqunatized = mix(r1, r2, fract(pos.y));
81
82 float q11d = quickDistance(unqunatized, q11);
83 float q21d = quickDistance(unqunatized, q21);
84 float q12d = quickDistance(unqunatized, q12);
85 float q22d = quickDistance(unqunatized, q22);
86
87 float best = min(q11d,
88 min(q21d,
89 min(q12d,
90 q22d)));
91
92 if (equal(q11d, best)) {
93 return q11;
94 }
95
96 if (equal(q21d, best)) {
97 return q21;
98 }
99
100 if (equal(q12d, best)) {
101 return q12;
102 }
103
104 return q22;
105 }
106
107 STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
108 {
109 vec2 pixel = vec2(1.0, 1.0) / output_resolution;
110 // 4-pixel super sampling
111
112 vec4 q11 = omniScale(image, position + pixel * vec2(-0.25, -0.25), input_resolution, output_resolution);
113 vec4 q21 = omniScale(image, position + pixel * vec2(+0.25, -0.25), input_resolution, output_resolution);
114 vec4 q12 = omniScale(image, position + pixel * vec2(-0.25, +0.25), input_resolution, output_resolution);
115 vec4 q22 = omniScale(image, position + pixel * vec2(+0.25, +0.25), input_resolution, output_resolution);
116
117 return (q11 + q21 + q12 + q22) / 4.0;
118 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.