Permalink
Cannot retrieve contributors at this time
# with optimization assistance from Patricio Gonzalez Vivo | |
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 standard deviation | |
// adapted from https://www.shadertoy.com/view/XdfGDH | |
// set some constants, to reduce math operations later | |
const int mSize = 5; // kernel width | |
const int kSize = (mSize-1)/2; // 2 | |
const int mSize2 = mSize*mSize; // 25 | |
// store the reciprocal for later (multiplications are faster than divisions in glsl) | |
const float mSize2reciprocal = 1./float(mSize2); // .25 | |
// 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),float(j)))).rgb; | |
} | |
} | |
// find the mean of the sampled values (a simple box blur) | |
// by dividing by the number of samples | |
// aka multiplying by the reciprocal of the kernel width squared | |
vec3 mean = final * mSize2reciprocal; | |
// 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),float(j)))).rgb; | |
vec3 difference = sample - mean; | |
squares += difference*difference; | |
} | |
} | |
// find the mean of the squares by dividing by the number of samples | |
// aka multiplying by the reciprocal of the kernel width squared | |
squares *= mSize2reciprocal; | |
// take the square root of the mean | |
vec3 stdev = vec3(0.); | |
stdev = vec3(sqrt(squares)); | |
// finally, find the magnitude^2 of the standard deviation with dot() | |
stdev = vec3(dot(stdev,stdev)); | |
// scale to taste | |
stdev *= 80.; | |
// clamp range to 0-1 (only matters with extreme stdev scales) | |
stdev = clamp(stdev, 0., 1.); | |
// mix between the blurred and unblurred normals, using stdev as a mask | |
normal = mix(mean, normal, stdev); // comment this out to disable the effect | |
// normalize it | |
normal = normalize(normal); | |
// uncomment this to see the mask | |
// normal = stdev; | |
layers: | |
terrain: | |
data: { source: normals, layer: _default } | |
draw: | |
hillshade: | |
order: 0 |