MapLibre Native Core
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
line_pattern.hpp
Go to the documentation of this file.
1 // Generated code, do not modify this file!
2 // Generated on 2023-04-05T16:25:15.886Z by mwilsnd using shaders/generate_shader_code.js
3 
4 #pragma once
6 
7 namespace mbgl {
8 namespace shaders {
9 
11  static constexpr const char* vertex = R"(// floor(127 / 2) == 63.0
12 // the maximum allowed miter limit is 2.0 at the moment. the extrude normal is
13 // stored in a byte (-128..127). we scale regular normals up to length 63, but
14 // there are also "special" normals that have a bigger length (of up to 126 in
15 // this case).
16 // #define scale 63.0
17 #define scale 0.015873016
18 
19 // We scale the distance before adding it to the buffers so that we can store
20 // long distances for long segments. Use this value to unscale the distance.
21 #define LINE_DISTANCE_SCALE 2.0
22 
23 layout (location = 0) in vec2 a_pos_normal;
24 layout (location = 1) in vec4 a_data;
25 
26 uniform mat4 u_matrix;
27 uniform vec2 u_units_to_pixels;
28 uniform mediump float u_ratio;
29 uniform lowp float u_device_pixel_ratio;
30 
31 out vec2 v_normal;
32 out vec2 v_width2;
33 out float v_linesofar;
34 out float v_gamma_scale;
35 
36 #ifndef HAS_UNIFORM_u_blur
37 uniform lowp float u_blur_t;
38 layout (location = 2) in lowp vec2 a_blur;
39 out lowp float blur;
40 #else
41 uniform lowp float u_blur;
42 #endif
43 #ifndef HAS_UNIFORM_u_opacity
44 uniform lowp float u_opacity_t;
45 layout (location = 3) in lowp vec2 a_opacity;
46 out lowp float opacity;
47 #else
48 uniform lowp float u_opacity;
49 #endif
50 #ifndef HAS_UNIFORM_u_offset
51 uniform lowp float u_offset_t;
52 layout (location = 4) in lowp vec2 a_offset;
53 #else
54 uniform lowp float u_offset;
55 #endif
56 #ifndef HAS_UNIFORM_u_gapwidth
57 uniform lowp float u_gapwidth_t;
58 layout (location = 5) in mediump vec2 a_gapwidth;
59 #else
60 uniform mediump float u_gapwidth;
61 #endif
62 #ifndef HAS_UNIFORM_u_width
63 uniform lowp float u_width_t;
64 layout (location = 6) in mediump vec2 a_width;
65 #else
66 uniform mediump float u_width;
67 #endif
68 #ifndef HAS_UNIFORM_u_pattern_from
69 uniform lowp float u_pattern_from_t;
70 layout (location = 7) in lowp vec4 a_pattern_from;
71 out lowp vec4 pattern_from;
72 #else
73 uniform lowp vec4 u_pattern_from;
74 #endif
75 #ifndef HAS_UNIFORM_u_pattern_to
76 uniform lowp float u_pattern_to_t;
77 layout (location = 8) in lowp vec4 a_pattern_to;
78 out lowp vec4 pattern_to;
79 #else
80 uniform lowp vec4 u_pattern_to;
81 #endif
82 
83 void main() {
84  #ifndef HAS_UNIFORM_u_blur
85 blur = unpack_mix_vec2(a_blur, u_blur_t);
86 #else
87 lowp float blur = u_blur;
88 #endif
89  #ifndef HAS_UNIFORM_u_opacity
90 opacity = unpack_mix_vec2(a_opacity, u_opacity_t);
91 #else
92 lowp float opacity = u_opacity;
93 #endif
94  #ifndef HAS_UNIFORM_u_offset
95 lowp float offset = unpack_mix_vec2(a_offset, u_offset_t);
96 #else
97 lowp float offset = u_offset;
98 #endif
99  #ifndef HAS_UNIFORM_u_gapwidth
100 mediump float gapwidth = unpack_mix_vec2(a_gapwidth, u_gapwidth_t);
101 #else
102 mediump float gapwidth = u_gapwidth;
103 #endif
104  #ifndef HAS_UNIFORM_u_width
105 mediump float width = unpack_mix_vec2(a_width, u_width_t);
106 #else
107 mediump float width = u_width;
108 #endif
109  #ifndef HAS_UNIFORM_u_pattern_from
110 pattern_from = a_pattern_from;
111 #else
112 mediump vec4 pattern_from = u_pattern_from;
113 #endif
114  #ifndef HAS_UNIFORM_u_pattern_to
115 pattern_to = a_pattern_to;
116 #else
117 mediump vec4 pattern_to = u_pattern_to;
118 #endif
119 
120  // the distance over which the line edge fades out.
121  // Retina devices need a smaller distance to avoid aliasing.
122  float ANTIALIASING = 1.0 / u_device_pixel_ratio / 2.0;
123 
124  vec2 a_extrude = a_data.xy - 128.0;
125  float a_direction = mod(a_data.z, 4.0) - 1.0;
126  float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE;
127  // float tileRatio = u_scale.y;
128  vec2 pos = floor(a_pos_normal * 0.5);
129 
130  // x is 1 if it's a round cap, 0 otherwise
131  // y is 1 if the normal points up, and -1 if it points down
132  // We store these in the least significant bit of a_pos_normal
133  mediump vec2 normal = a_pos_normal - 2.0 * pos;
134  normal.y = normal.y * 2.0 - 1.0;
135  v_normal = normal;
136 
137  // these transformations used to be applied in the JS and native code bases.
138  // moved them into the shader for clarity and simplicity.
139  gapwidth = gapwidth / 2.0;
140  float halfwidth = width / 2.0;
141  offset = -1.0 * offset;
142 
143  float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
144  float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + (halfwidth == 0.0 ? 0.0 : ANTIALIASING);
145 
146  // Scale the extrusion vector down to a normal and then up by the line width
147  // of this vertex.
148  mediump vec2 dist = outset * a_extrude * scale;
149 
150  // Calculate the offset when drawing a line that is to the side of the actual line.
151  // We do this by creating a vector that points towards the extrude, but rotate
152  // it when we're drawing round end points (a_direction = -1 or 1) since their
153  // extrude vector points in another direction.
154  mediump float u = 0.5 * a_direction;
155  mediump float t = 1.0 - abs(u);
156  mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);
157 
158  vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);
159  gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;
160 
161  // calculate how much the perspective view squishes or stretches the extrude
162  float extrude_length_without_perspective = length(dist);
163  float extrude_length_with_perspective = length(projected_extrude.xy / gl_Position.w * u_units_to_pixels);
164  v_gamma_scale = extrude_length_without_perspective / extrude_length_with_perspective;
165 
166  v_linesofar = a_linesofar;
167  v_width2 = vec2(outset, inset);
168 }
169 )";
170  static constexpr const char* fragment = R"(uniform lowp float u_device_pixel_ratio;
171 uniform vec2 u_texsize;
172 uniform float u_fade;
173 uniform mediump vec4 u_scale;
174 
175 uniform sampler2D u_image;
176 
177 in vec2 v_normal;
178 in vec2 v_width2;
179 in float v_linesofar;
180 in float v_gamma_scale;
181 
182 #ifndef HAS_UNIFORM_u_pattern_from
183 in lowp vec4 pattern_from;
184 #else
185 uniform lowp vec4 u_pattern_from;
186 #endif
187 #ifndef HAS_UNIFORM_u_pattern_to
188 in lowp vec4 pattern_to;
189 #else
190 uniform lowp vec4 u_pattern_to;
191 #endif
192 #ifndef HAS_UNIFORM_u_blur
193 in lowp float blur;
194 #else
195 uniform lowp float u_blur;
196 #endif
197 #ifndef HAS_UNIFORM_u_opacity
198 in lowp float opacity;
199 #else
200 uniform lowp float u_opacity;
201 #endif
202 
203 void main() {
204  #ifdef HAS_UNIFORM_u_pattern_from
205 mediump vec4 pattern_from = u_pattern_from;
206 #endif
207  #ifdef HAS_UNIFORM_u_pattern_to
208 mediump vec4 pattern_to = u_pattern_to;
209 #endif
210 
211  #ifdef HAS_UNIFORM_u_blur
212 lowp float blur = u_blur;
213 #endif
214  #ifdef HAS_UNIFORM_u_opacity
215 lowp float opacity = u_opacity;
216 #endif
217 
218  vec2 pattern_tl_a = pattern_from.xy;
219  vec2 pattern_br_a = pattern_from.zw;
220  vec2 pattern_tl_b = pattern_to.xy;
221  vec2 pattern_br_b = pattern_to.zw;
222 
223  float pixelRatio = u_scale.x;
224  float tileZoomRatio = u_scale.y;
225  float fromScale = u_scale.z;
226  float toScale = u_scale.w;
227 
228  vec2 display_size_a = vec2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio);
229  vec2 display_size_b = vec2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio);
230 
231  vec2 pattern_size_a = vec2(display_size_a.x * fromScale / tileZoomRatio, display_size_a.y);
232  vec2 pattern_size_b = vec2(display_size_b.x * toScale / tileZoomRatio, display_size_b.y);
233 
234  // Calculate the distance of the pixel from the line in pixels.
235  float dist = length(v_normal) * v_width2.s;
236 
237  // Calculate the antialiasing fade factor. This is either when fading in
238  // the line in case of an offset line (v_width2.t) or when fading out
239  // (v_width2.s)
240  float blur2 = (blur + 1.0 / u_device_pixel_ratio) * v_gamma_scale;
241  float alpha = clamp(min(dist - (v_width2.t - blur2), v_width2.s - dist) / blur2, 0.0, 1.0);
242 
243  float x_a = mod(v_linesofar / pattern_size_a.x, 1.0);
244  float x_b = mod(v_linesofar / pattern_size_b.x, 1.0);
245 
246  // v_normal.y is 0 at the midpoint of the line, -1 at the lower edge, 1 at the upper edge
247  // we clamp the line width outset to be between 0 and half the pattern height plus padding (2.0)
248  // to ensure we don't sample outside the designated symbol on the sprite sheet.
249  // 0.5 is added to shift the component to be bounded between 0 and 1 for interpolation of
250  // the texture coordinate
251  float y_a = 0.5 + (v_normal.y * clamp(v_width2.s, 0.0, (pattern_size_a.y + 2.0) / 2.0) / pattern_size_a.y);
252  float y_b = 0.5 + (v_normal.y * clamp(v_width2.s, 0.0, (pattern_size_b.y + 2.0) / 2.0) / pattern_size_b.y);
253  vec2 pos_a = mix(pattern_tl_a / u_texsize, pattern_br_a / u_texsize, vec2(x_a, y_a));
254  vec2 pos_b = mix(pattern_tl_b / u_texsize, pattern_br_b / u_texsize, vec2(x_b, y_b));
255 
256  vec4 color = mix(texture(u_image, pos_a), texture(u_image, pos_b), u_fade);
257 
258  fragColor = color * alpha * opacity;
259 
260 #ifdef OVERDRAW_INSPECTOR
261  fragColor = vec4(1.0);
262 #endif
263 }
264 )";
265 };
266 
267 } // namespace shaders
268 } // namespace mbgl
@ OpenGL
The OpenGL API backend.
BuiltIn
This enum is used with the ShaderSource template to select source code for the desired program and gr...
Definition: actor.hpp:15
Select shader source based on a program type and a desired graphics API.