SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
Shaders/FlatCRT.fsh
1 #define COLOR_LOW 0.45
2 #define COLOR_HIGH 1.0
3 #define VERTICAL_BORDER_DEPTH 0.6
4 #define SCANLINE_DEPTH 0.55
5
6 STATIC vec4 scale(sampler2D image, vec2 position, vec2 input_resolution, vec2 output_resolution)
7 {
8 /* Setting up common vars */
9 vec2 pos = fract(position * input_resolution);
10 vec2 sub_pos = pos * 6.0;
11
12 vec4 center = texture_relative(image, position, vec2(0, 0));
13 vec4 left = texture_relative(image, position, vec2(-1, 0));
14 vec4 right = texture_relative(image, position, vec2(1, 0));
15
16 /* Vertical blurring */
17 if (sub_pos.y < 1.0) {
18 center = mix(center, texture_relative(image, position, vec2( 0, -1)), 0.5 - sub_pos.y / 2.0);
19 left = mix(left, texture_relative(image, position, vec2(-1, -1)), 0.5 - sub_pos.y / 2.0);
20 right = mix(right, texture_relative(image, position, vec2( 1, -1)), 0.5 - sub_pos.y / 2.0);
21 }
22 else if (sub_pos.y > 5.0) {
23 center = mix(center, texture_relative(image, position, vec2( 0, 1)), (sub_pos.y - 5.0) / 2.0);
24 left = mix(left, texture_relative(image, position, vec2(-1, 1)), (sub_pos.y - 5.0) / 2.0);
25 right = mix(right, texture_relative(image, position, vec2( 1, 1)), (sub_pos.y - 5.0) / 2.0);
26 }
27
28 /* Scanlines */
29 float scanline_multiplier;
30 if (pos.y < 0.5) {
31 scanline_multiplier = (pos.y * 2.0) * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
32 }
33 else {
34 scanline_multiplier = ((1.0 - pos.y) * 2.0) * SCANLINE_DEPTH + (1.0 - SCANLINE_DEPTH);
35 }
36
37 center *= scanline_multiplier;
38 left *= scanline_multiplier;
39 right *= scanline_multiplier;
40
41 /* Vertical separator for shadow masks */
42 bool odd = bool(int((position * input_resolution).x) & 1);
43 if (odd) {
44 pos.y += 0.5;
45 pos.y = fract(pos.y);
46 }
47
48 if (pos.y < 1.0 / 3.0) {
49 float gradient_position = pos.y * 3.0;
50 center *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
51 left *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
52 right *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
53 }
54 else if (pos.y > 2.0 / 3.0) {
55 float gradient_position = (1.0 - pos.y) * 3.0;
56 center *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
57 left *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
58 right *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
59 }
60
61 /* Blur the edges of the separators of adjacent columns */
62 if (sub_pos.x < 1.0 || sub_pos.x > 5.0) {
63 pos.y += 0.5;
64 pos.y = fract(pos.y);
65
66 if (pos.y < 1.0 / 3.0) {
67 float gradient_position = pos.y * 3.0;
68 if (pos.x < 0.5) {
69 gradient_position = 1.0 - (1.0 - gradient_position) * (1.0 - (pos.x) * 6.0);
70 }
71 else {
72 gradient_position = 1.0 - (1.0 - gradient_position) * (1.0 - (1.0 - pos.x) * 6.0);
73 }
74 center *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
75 left *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
76 right *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
77 }
78 else if (pos.y > 2.0 / 3.0) {
79 float gradient_position = (1.0 - pos.y) * 3.0;
80 if (pos.x < 0.5) {
81 gradient_position = 1.0 - (1.0 - gradient_position) * (1.0 - (pos.x) * 6.0);
82 }
83 else {
84 gradient_position = 1.0 - (1.0 - gradient_position) * (1.0 - (1.0 - pos.x) * 6.0);
85 }
86 center *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
87 left *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
88 right *= gradient_position * VERTICAL_BORDER_DEPTH + (1.0 - VERTICAL_BORDER_DEPTH);
89 }
90 }
91
92
93 /* Subpixel blurring, like LCD filter*/
94
95 vec4 midleft = mix(left, center, 0.5);
96 vec4 midright = mix(right, center, 0.5);
97
98 vec4 ret;
99 if (sub_pos.x < 1.0) {
100 ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_HIGH * left.b, 1),
101 vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1),
102 sub_pos.x);
103 }
104 else if (sub_pos.x < 2.0) {
105 ret = mix(vec4(COLOR_HIGH * center.r, COLOR_LOW * center.g, COLOR_LOW * left.b, 1),
106 vec4(COLOR_HIGH * center.r, COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1),
107 sub_pos.x - 1.0);
108 }
109 else if (sub_pos.x < 3.0) {
110 ret = mix(vec4(COLOR_HIGH * center.r , COLOR_HIGH * center.g, COLOR_LOW * midleft.b, 1),
111 vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g, COLOR_LOW * center.b, 1),
112 sub_pos.x - 2.0);
113 }
114 else if (sub_pos.x < 4.0) {
115 ret = mix(vec4(COLOR_LOW * midright.r, COLOR_HIGH * center.g , COLOR_LOW * center.b, 1),
116 vec4(COLOR_LOW * right.r , COLOR_HIGH * center.g, COLOR_HIGH * center.b, 1),
117 sub_pos.x - 3.0);
118 }
119 else if (sub_pos.x < 5.0) {
120 ret = mix(vec4(COLOR_LOW * right.r, COLOR_HIGH * center.g , COLOR_HIGH * center.b, 1),
121 vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1),
122 sub_pos.x - 4.0);
123 }
124 else {
125 ret = mix(vec4(COLOR_LOW * right.r, COLOR_LOW * midright.g, COLOR_HIGH * center.b, 1),
126 vec4(COLOR_HIGH * right.r, COLOR_LOW * right.g , COLOR_HIGH * center.b, 1),
127 sub_pos.x - 5.0);
128 }
129
130 /* Anti alias the curve */
131 vec2 pixel_position = position * output_resolution;
132 if (pixel_position.x < 1.0) {
133 ret *= pixel_position.x;
134 }
135 else if (pixel_position.x > output_resolution.x - 1.0) {
136 ret *= output_resolution.x - pixel_position.x;
137 }
138 if (pixel_position.y < 1.0) {
139 ret *= pixel_position.y;
140 }
141 else if (pixel_position.y > output_resolution.y - 1.0) {
142 ret *= output_resolution.y - pixel_position.y;
143 }
144
145 return ret;
146 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.