UNPKG

2.57 kBPlain TextView Raw
1#ifdef GL_ES
2precision highp float;
3#endif
4
5uniform sampler2D u_image;
6varying vec2 v_pos;
7uniform vec2 u_dimension;
8uniform float u_zoom;
9uniform vec4 u_unpack;
10
11float getElevation(vec2 coord, float bias) {
12 // Convert encoded elevation value to meters
13 vec4 data = texture2D(u_image, coord) * 255.0;
14 data.a = -1.0;
15 return dot(data, u_unpack) / 4.0;
16}
17
18void main() {
19 vec2 epsilon = 1.0 / u_dimension;
20
21 // queried pixels:
22 // +-----------+
23 // | | | |
24 // | a | b | c |
25 // | | | |
26 // +-----------+
27 // | | | |
28 // | d | e | f |
29 // | | | |
30 // +-----------+
31 // | | | |
32 // | g | h | i |
33 // | | | |
34 // +-----------+
35
36 float a = getElevation(v_pos + vec2(-epsilon.x, -epsilon.y), 0.0);
37 float b = getElevation(v_pos + vec2(0, -epsilon.y), 0.0);
38 float c = getElevation(v_pos + vec2(epsilon.x, -epsilon.y), 0.0);
39 float d = getElevation(v_pos + vec2(-epsilon.x, 0), 0.0);
40 float e = getElevation(v_pos, 0.0);
41 float f = getElevation(v_pos + vec2(epsilon.x, 0), 0.0);
42 float g = getElevation(v_pos + vec2(-epsilon.x, epsilon.y), 0.0);
43 float h = getElevation(v_pos + vec2(0, epsilon.y), 0.0);
44 float i = getElevation(v_pos + vec2(epsilon.x, epsilon.y), 0.0);
45
46 // Here we divide the x and y slopes by 8 * pixel size
47 // where pixel size (aka meters/pixel) is:
48 // circumference of the world / (pixels per tile * number of tiles)
49 // which is equivalent to: 8 * 40075016.6855785 / (512 * pow(2, u_zoom))
50 // which can be reduced to: pow(2, 19.25619978527 - u_zoom).
51 // We want to vertically exaggerate the hillshading because otherwise
52 // it is barely noticeable at low zooms. To do this, we multiply this by
53 // a scale factor that is a function of zooms below 15, which is an arbitrary
54 // that corresponds to the max zoom level of Mapbox terrain-RGB tiles.
55 // See nickidlugash's awesome breakdown for more info:
56 // https://github.com/mapbox/mapbox-gl-js/pull/5286#discussion_r148419556
57
58 float exaggerationFactor = u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;
59 float exaggeration = u_zoom < 15.0 ? (u_zoom - 15.0) * exaggerationFactor : 0.0;
60
61 vec2 deriv = vec2(
62 (c + f + f + i) - (a + d + d + g),
63 (g + h + h + i) - (a + b + b + c)
64 ) / pow(2.0, exaggeration + (19.2562 - u_zoom));
65
66 gl_FragColor = clamp(vec4(
67 deriv.x / 2.0 + 0.5,
68 deriv.y / 2.0 + 0.5,
69 1.0,
70 1.0), 0.0, 1.0);
71
72#ifdef OVERDRAW_INSPECTOR
73 gl_FragColor = vec4(1.0);
74#endif
75}