hillshade = (DEMData, az = 315, alt = 45, z = 1, multi = false, zt = false) => {
const { width, height, data } = DEMData;
const hillshade = new Uint8ClampedArray(width * height * 4);
const alpha = az * Math.PI / 180,
beta = alt * Math.PI / 180,
alphaM = [1.25, 1.5, 1.75, 2].map(a => a * Math.PI);
const parameters = multi
? alphaM.map(alpha => getParameters(alpha, beta))
: getParameters(alpha, beta);
for (let n = 0, i = 0, l = 0; n < data.length; n++, i += 4) {
let { dzdx, dzdy } = getDerivatives(n % width, Math.floor(n / width), z, DEMData, zt);
l = multi
? getWeightedReflectance(dzdx, dzdy, parameters, alphaM)
: getReflectance(dzdx, dzdy, parameters);
if (l < 0) l = 0;
l = brighten(l);
hillshade[i ] = l * 255;
hillshade[i + 1] = l * 255;
hillshade[i + 2] = l * 255;
hillshade[i + 3] = 255;
}
return hillshade;
}