/
green-stdev-adjusted.yaml
79 lines (69 loc) · 3.22 KB
/
green-stdev-adjusted.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
sources:
normals:
type: Raster
url: https://tile.nextzen.org/tilezen/terrain/v1/256/normal/{z}/{x}/{y}.png
url_params:
api_key: your-nextzen-api-key
max_zoom: 14
lights:
directional1:
type: directional
direction: [0.5,-0.7,-0.5]
diffuse: [1, 1.000, 0.75]
ambient: [0.2, 0.3, 0.3]
styles:
hillshade:
base: raster
raster: normal
shaders:
blocks:
normal: |
// box blur masked with a standard deviation
// blur adapted from https://www.shadertoy.com/view/XdfGDH
const int mSize = 5; // kernel width
const int kSize = (mSize-1)/2;
// this version samples in screen space instead of texture space,
// to minimize the artifacts across zoom boundaries
float fract = clamp(u_map_position.z - u_tile_origin.z, 0., 1.);
float zoom = 1. - fract * .5;
// loop over the kernel
vec3 final = vec3(0.0);
for (int i=-kSize; i <= kSize; ++i) {
for (int j=-kSize; j <= kSize; ++j) {
final += sampleRasterAtPixel(0, vec2(currentRasterPixel(0) + vec2(float(i)*zoom,float(j)*zoom))).rgb;
}
}
// find the mean of the sampled values (a simple box blur)
vec3 mean = final / vec3(mSize*mSize);
// loop over the kernel again, summing the squares of (samples - mean)
vec3 squares = vec3(0.0);
for (int i=-kSize; i <= kSize; ++i) {
for (int j=-kSize; j <= kSize; ++j) {
vec3 sample = sampleRasterAtPixel(0, vec2(currentRasterPixel(0) + vec2(float(i)*zoom,float(j)*zoom))).rgb;
vec3 difference = sample - mean;
squares += difference*difference;
}
}
// find the mean of the squares
squares /= vec3(mSize*mSize);
// take the square root of the mean
vec3 stdev = vec3(sqrt(squares));
// finally, take the magnitude of the vector standard deviation
stdev = vec3(dot(stdev,stdev));
// scale to taste
// account for brightness differences across a single zoom level
float scale = 80.;
stdev *= scale - (scale/2. - fract * scale/2.);
// mix between the blurred and unblurred normals, using stdev as a mask
normal = mix(mean, normal, stdev); // hide this to see the original
// normalize it
normal = normalize(normal);
// debugging
// normal = mean; // unhide this to see the blurred version
// normal = stdev; // unhide this to see the mask
layers:
terrain:
data: { source: normals, layer: _default }
draw:
hillshade:
order: 0