Published
Edited
Nov 20, 2021
9 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function planet(color, dem) {
const height = width / 2;
const context = DOM.context2d(width, height);
const w = context.canvas.width;
const dpr = w / width;

// get the DEM data
context.drawImage(dem, 0, 0, width, height);
const d = context.getImageData(0, 0, w, height * dpr).data;

// get the COLOR data
context.drawImage(color, 0, 0, width, height);
const c = context.getImageData(0, 0, w, height * dpr).data;

// create the destination ImageData
const E = context.getImageData(0, 0, w, height * dpr);
const e = E.data;
const n = c.length / 4;

const stepX = 4;
const stepY = 4 * w;

function update(elevation, azimuth, strength = 0.3) {
const r = elevation * (Math.PI / 180);
const a = -azimuth * (Math.PI / 180);
const cr = Math.cos(r);
const sr = Math.sin(r);
const ca = Math.cos(a);
const sa = Math.sin(a);

// light!
const lz = sr;
const lx = cr * ca;
const ly = cr * sa;

// pixels
for (let j = 0; j < n; j++) {
const i = 4 * j;

// hill-shading factor = dot product of light and normal vectors
const dzx = d[i + stepX] - d[i - stepX];
const dzy = d[i + stepY] - d[i - stepY];
const norm = Math.hypot(1, dzx, dzy);
const dot = (lz + dzx * lx + dzy * ly) / norm;

// the pivot is dot == cr, i.e. the flat plains
// this way we don't alter the global illumination
const factor = 1 + strength * (dot - cr);

// lighten/darken the color
// RGB model is not ideal but fastest… and since the Moon is almost grey, it's working
e[i + 0] = c[i + 0] * factor; // r
e[i + 1] = c[i + 1] * factor; // g
e[i + 2] = c[i + 2] * factor; // b
}

context.putImageData(E, 0, 0);
}

update(45, 315, 0.5);

return Object.assign(context.canvas, { update });
}
Insert cell
moon.update(elevation, azimuth, strength)
Insert cell
Insert cell
Insert cell
color = d3.image(
"https://observable-cors.glitch.me/" +
"https://svs.gsfc.nasa.gov/vis/a000000/a004700/a004720/lroc_color_poles_1k.jpg",
{ crossOrigin: "anonymous" }
)
Insert cell
dem = d3.image(
"https://observable-cors.glitch.me/" +
"https://svs.gsfc.nasa.gov/vis/a000000/a004700/a004720/ldem_3_8bit.jpg",
{ crossOrigin: "anonymous" }
)
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more