--- title: Khufu · Great Pyramid of Giza emoji: 🔺 colorFrom: yellow colorTo: red sdk: static app_port: 8080 pinned: false license: mit short_description: Interactive to-scale 3D model of the Great Pyramid tags: - threejs - webgl - education - egypt --- # Khufu — interactive 3D model of the Great Pyramid of Giza Live: · Source: A single self-contained `index.html`: an orbitable, to-scale 3D model of the pyramid of Khufu (Cheops) at Giza, built with three.js. The pyramid is rebuilt from its design dimensions as a **stepped limestone core of ~203 visible courses**, and can be switched to the **restored smooth Tura-limestone casing with capstone**, at full original height, under a movable sun with shadows. A 2 m human figure stands at the foot to keep the scale honest. ## Open it No build step, no bundler, no assets to download — three.js r185 and `OrbitControls` are loaded as ES modules from jsDelivr through an import map inside the file. ```sh cd kheops-pyramid python3 -m http.server ``` then open **http://localhost:8000/** in any WebGL2 browser. (`python3 -m http.server 8080` for another port; `--directory /path/to/kheops-pyramid` from elsewhere.) Opening `index.html` directly from disk usually works too, since the modules come over HTTPS, but a local HTTP server is the reliable way. Network access is required the first time. ## Controls | Interaction | | |---|---| | drag | orbit · wheel = zoom · right-drag = pan | | C | restored casing & capstone on/off (the stepped core is shown by default) | | D | dimension guides: original base outline, corner pegs, height + slant section lines, 20 m rings | | G | Khafre and Menkaure on the Giza plateau | | A / H / R | auto-rotate · hide the interface · reset everything | | 14 | cameras: three-quarter SE (start) · aerial N · due east · eye level at 1.7 m | | | move the sun in azimuth / elevation | The **View** panel exposes the same toggles plus sun elevation/azimuth sliders, dawn/noon/dusk presets, shadow quality (auto-lowered on software renderers) and collapsible panels. Every number in the **legend** is printed by the same constants that build the geometry, so the drawing and the text cannot drift apart. State can also be set through the URL, e.g. `?casing=1&el=6&az=255&view=3`. ## Dimensions modelled Design values, in metres (they reproduce the quoted Egyptological figures when rounded): | | | |---|---| | Base side | 230.3 m (230.33 m modelled = 440 royal cubits of 0.5236 m) | | Original height | 146.6 m (146.57 m modelled = 280 cubits) | | Face slope | 51.84° (51° 50′) — a seked of 5½ palms | | Slant height | 186.4 m face apothem | | Alignment | faces due N/S/E/W (within ≈ 0.05° of true north; the model is exactly cardinal) | | Courses | ≈ 203, risers tapering 1.05 m at the base to 0.40 m near the top, mean 0.72 m, each set back 0.31–0.82 m | | Today | ~138.5 m high, ~227.5 m of base, casing stripped | | Perimeter / base area / volume | 921.3 m · 53,052 m² · ≈ 2.59 million m³ (≈ 6 Mt of limestone) | | Human figure | 2.00 m tall (3.82 cubits), standing east of the south-east corner | The stepped core is generated as a genuine staircase **inscribed a few centimetres inside** the original 51.84° envelope, so switching on the casing shows the smooth facing exactly where it should be, covering the steps and reaching the true apex height. Desert ground, sky, haze and the sun's shadow volume are procedural and generated in-page. ## Files & checks ``` index.html the whole app (markup, UI, shaders, geometry, three.js via import map) scripts/check-html.mjs static sanity check ``` ```sh node scripts/check-html.mjs index.html # add --net to also ping the CDN entry points ``` It verifies the doctype and balanced markup, that the import map is valid JSON with the `three` and `three/addons/` entries pinned to a version, that the inline ES-module script imports `three/addons/controls/OrbitControls.js`, parses cleanly under `node --check`, that every element id used by the script exists, that no local `