Lunar Eclipse Turquoise Band

This page is for the people who want to know exactly where every number came from.

Principles — A Deep Dive

Every pixel you saw on the homepage has its color traced through a single, unbroken physical chain. It starts with a measured solar spectrum. Light enters Earth's atmosphere, where refraction bends it toward a specific landing point on the Moon. Along that now-curved path, Rayleigh scattering, ozone absorption, and background aerosols strip the spectrum down layer by layer. The resulting spectrum is then mapped to color coordinates through CIE color matching functions. There are no texture maps anywhere in this pipeline, no hand-tuned color parameters, and no empirical correction terms. This page walks through the six key technical decisions behind the pipeline design, cross-checks the results against three independent research groups from the literature, and collects the model card's critical numbers — each one annotated with exactly what it's measuring and how. Finally, it provides reproducible commands for generating every production-quality image.

Three Principles That Run Through Everything

First, keep the physics calculation and the screen display as two separate stages. Everything produced by the ray tracing step is a linear radiometric quantity — this stage does no visual sweetening whatsoever. The final on-screen appearance is handed off to exposure and tone mapping, both of which we explicitly label as display-layer human choices rather than letting them leak into the physics. The single most expensive lesson in this entire project was learned right at this boundary: early renders boosted the exposure to bring out shadow detail, and in doing so turned a genuinely narrow turquoise band into a soft gradient stretching across nearly a third of the lunar disk. We stared at that wide band for a long time, deeply suspicious that something was wrong with the physics model. After turning it inside out, we finally realized the problem wasn't in the physics at all — the display layer was manufacturing an illusion. The current default exposure anchors to the brightest point on the lunar disk, which preserves the light–dark boundary and restores the band to its physically correct narrowness.

Second, the physics model is not steered by how things look. Every time something on screen seemed off — blues slightly the wrong shade, band width looking too broad, cyan not saturated enough — the choice in front of us was always to go back to the measurement method, the display parameters, or the literature conventions to find the cause, never to stuff a new mechanism into the model just to force the visual result. Satellite measurements later gave us point-by-point confirmation: the magnitude of the in-band red-to-blue ratio, the selenographic location of the colored band, and the overall pale cyan impression all matched the observations.

Third, if something can be solved by ray tracing, don't write an analytic formula for it. Focusing factors, chord-length weighting, effective path lengths — all of these are quantities that ray tracing produces naturally; the moment you package them into analytic formulas, errors creep in quietly. Take umbral center brightness as an example. A purely analytic approach gave −7.7 stops. After switching to ray casting with properly traced refraction, it corrected all the way to −13.5 stops. Every stop of exposure in between represents a debt that some analytic approximation owed to real physics. Four of the six decisions below are essentially repayments on that debt.

Six Key Technical Decisions

1. Refraction: No Lookup Tables — RK4 Integration Per Ray

Conventional analytic refraction formulas express the deflection angle as an exponential function of the ray's grazing height. According to such a formula, a ray skimming the surface would be deflected by about 70′. But after numerically integrating each ray individually using RK4, we found that in a real atmosphere this 70′ simply doesn't exist. Here's why: rays aimed at heights between 0 and 1 km get bent so strongly that their tangent point dips below the ground — they hit the Earth's surface and disappear, never reaching the Moon. The rays that actually manage to graze past the surface have an aiming height of about 1.7 km, and their deflection comes out to 63.5′. The pattern holds at middle and high altitudes too, with real deflections consistently larger than the analytic formula predicts: at 12 km altitude, 21′ versus 15.7′. Light bends toward the umbral center more aggressively than the formula expects. Refraction geometry is the skeleton of the entire model — any systematic shift in that skeleton would simultaneously throw off both the selenographic position of the color and the brightness at the dark end — so we didn't cut corners here.

2. Extinction Integrated Along the Curved Path, Using the True Tangent Height

Once a ray is refracted, its actual path through the atmosphere is longer than a straight line, and the column density of gas along that path cannot be estimated from straight-line geometry — it has to be accumulated segment by segment along the true curved trajectory. This one bit us through a terminology mismatch: at one point the pipeline was feeding a ray's aiming height (impact parameter) directly into the extinction integrator, treating it as the tangent height. But refraction pushes the true tangent point lower. A ray aimed at 2.7 km, for example, has a true tangent height of only 1.1 km, where the atmospheric density is far higher. Using the wrong height produced a systematic underestimate of extinction. After the fix, the umbral center dimmed by an additional 0.68 stops. This lesson shares a root with the third principle: even inside a pipeline that has largely avoided analytic shortcuts, let a single analytic quantity slip in and it will still bite you.

3. Focusing and Defocusing: No Formulas — They Emerge from Landing-Point Density

After refraction, some rays entering the umbra converge while others spread apart. Early analytic pipelines handled this with a focusing-factor formula, but that formula blows up at the umbral center — it heads toward infinity — forcing you to clamp it with a regularization floor, which then produces a spurious bright spot right where things should be darkest. The correct approach is to go back to the most basic meaning of ray tracing: randomly cast millions of rays, observe where their landing points cluster on the lunar disk, and the number of rays landing in each area is, by definition, that area's brightness. Focusing and defocusing require no formulas at all — they simply emerge from the landing-point distribution. The record of numbers preserves this evolutionary path cleanly: analytic chord-length weighting gave −7.7 stops for the umbral center; ray casting with analytic refraction still used gave −11 stops; switching to fully traced refraction brought it to −13.1 stops (measured in photopic, molecular atmosphere, 0 stops = uneclipsed full Moon). The single most decisive diagnostic is this: a single ray passing through the umbral center experiences a one-way transmission loss of only −7.9 stops, but the bin-averaged surface brightness there comes out to −13.1 stops. The 5.2-stop gap in between is entirely geometric defocusing: the deepest refracted light that grazed the Earth's surface gets spread thin across the entire lunar disk. No analytic formula had ever accounted for this.

4. Penumbral Direct Light Uses the Same Ray-Casting Run

As the Moon moves out of the umbra, the Sun gradually peeks out from behind the Earth's limb and direct sunlight incrementally returns. Early pipeline runs only traced refracted rays, which produced a spurious jump in the light curve just outside the umbral boundary — it looked like brightness suddenly leaping upward, when in reality the direct-light contribution was simply missing. Rather than smoothing over the artifact, we extended the ray-casting aiming range outward to 5500 km above the atmosphere. Beyond the atmosphere, rays travel in straight lines with no attenuation, and the gradual brightening of penumbral direct light emerges naturally from the same ray-casting machinery — the light curve climbs smoothly all the way to full-Moon brightness at 73′. There's also an engineering lesson here: insufficient ray coverage producing a false dimming has appeared in this project three times in different guises — the moving shadow at the end of the video, the downturn at the tail of the light curve, and the missing direct light described above. The coverage calculation is now computed by working backward from the maximum angular distance needed on the consumer side plus the solar radius. This rule has been written into the checklist and won't be missed again.

5. Stratified Sampling: The Concentric Ring Incident

When the ray-casting range was expanded, a hidden landmine came along with it. The refractive shell occupies only about 1.1% of the total casting area — meaning that out of 4 million rays, only a few tens of thousands follow a refractive path. When those few tens of thousands are then distributed across over a hundred radial bins inside the umbra, each bin ends up with sample counts in the low hundreds. Statistical noise at these sample levels, amplified through lookup table (LUT) interpolation, ultimately produced concentric ring artifacts visible to the naked eye on the lunar disk render, with matching sawtooth jitter in the light curve. A user spotted this with their eyes while reviewing the images. We initially classified it as inherent Monte Carlo noise and planned to accept it honestly. Re-investigation changed the diagnosis: this was uneven sampling allocation, not something unavoidable — it could be eliminated by improving the sampling strategy. The fix used a standard unbiased variance-reduction approach: the refractive shell and the direct-light shell each normalize their own flux by their respective areas, and the ray budget is split 50/50 between the two shells. After the fix, the median brightness jump between adjacent umbral bins dropped from 0.158 stops to 0.085 stops. The lesson: uniform ray casting starves small but critical regions when the area ratios are extreme. Stratified sampling is a tax that any physics-first pipeline should pay upfront.

6. Two-Component Background Aerosol and Solar Limb Darkening

The last two pieces of real physics added to the model use parameters taken entirely from climatology observations — not a single one was tuned to fit. Background aerosol is split into two components: the first is a tropospheric marine background (AOD550 = 0.07, exponential profile, Ångström exponent 0.7); the second is stratospheric sulfate fine particles (sAOD550 = 0.005, profile anchored at the tropopause with an exponential tail, Ångström exponent 2.0). The stratospheric profile is not drawn arbitrarily — it has to simultaneously satisfy three hard constraints from observations: the extinction coefficients at 20 km and 25 km, and the total column amount, all three must check out together. Solar limb darkening uses the quadratic law for the Allen V band, normalized to the mean. The cost is recorded honestly too: stratospheric aerosol raises scattering at short wavelengths, and limb darkening makes the solar disk center brighter — the two effects combined wash out the band's red-to-blue ratio from 0.715 in a pure molecular atmosphere to 0.814 (measured in raw sRGB). The turquoise band therefore appears paler. This is an objective physical outcome, and the rendering end did not go back to boost saturation.

Three-Way Reconciliation with the Literature

Geometry: Mallama's Refraction Mapping Table

We compared our refractive mapping — the conversion from ray grazing height to selenographic angular distance — line by line against the corresponding entries in Mallama 2021/2022 tables. Agreement across all mid- and high-altitude ranges is within 2%. This match is foundational: only when the refraction mapping holds up does the discussion of color position along the radial direction have firm ground to stand on.

The Dark End: Two Clear-Sky Models, Several Stops Apart

Our model gives an umbral center brightness of −15.1 stops (default physics, photopic), while the theoretical upper bound for a pure molecular atmosphere — with all aerosols and limb darkening switched off — is −13.5 stops. Mallama's clear-sky empirical extinction model, by comparison, yields −18.7 stops for disk-integrated brightness and −20.5 stops for disk-resolved V-band, both of which are consistent with actual observations of normal lunar eclipses. Two models, both labeled "clear-sky," produce outputs that differ by 3.6 to 5.4 stops. A gap that large means that, despite sharing the same label, they are measuring different things. The key reason is that the slant-path distance for grazing rays is equivalent to 40 to 60 standard air masses — any tiny calibration difference in the extinction parameters, after being stretched across such an extreme path length, gets magnified by a factor of dozens. We used sensitivity experiments to isolate the source of the discrepancy to deep-penetration rays with tangent heights below 8 km: these rays affect only the dark-end brightness, not the color or ribbon of the band. The most likely explanation is that there are extinction sources in this altitude region that remain unmodeled. This is our largest open question. Our conclusion is honest: our dark-end numbers represent the brightness upper bound for the clearest possible conditions; real deep eclipses will be darker.

Color: Shu 2024 Satellite Narrowband Conventions and GOES-16

The term "red-to-blue ratio" demands caution when reading across different papers — it corresponds to at least three conventions that cannot be directly interconverted. The first is the linear sRGB channel ratio used in rendering; the second is the transmission ratio after normalizing to the solar spectrum; the third is the direct division of satellite-band radiances, which also requires multiplying by a lunar albedo ratio of 1.35, with a systematic uncertainty in the ±15% range. After aligning all these conventions, the reconciliation results split into two halves. The matching half: the broadband blueward trend is robust, and the in-band red-to-blue ratio falls into the same 0.8 to 1.0 pale-cyan range as the GOES-16 measurements. It's important to note that the conventions are not the same, so this does not constitute a strict quantitative match. The non-matching half involves a feature detected by Shu 2024 using the GF-4 satellite: a boundary ribbon where R/B < 1, with a radial full width between 120 and 190 km. Our 1D model does not reproduce this structure: the single-layer ozone dip, once convolved with the 32′ solar disk and combined with lateral red light inflow within the umbra, gets smoothed down to the noise level. Sensitivity matrix analysis has ruled out aerosol parameters and deep red light as suspects. The remaining candidates, ranked by the strength of evidence, are: possible unmodeled red-end extinction in the 8–19 km tangent height range, with thin cirrus near the tropopause being a candidate not yet incorporated; the actual spectral response curves of the satellite sensors; systematic effects from lunar surface albedo; and the inherent convention gap between a 2D boundary measurement and a 1D radial average. We have never adjusted any model parameter to try to reproduce the ribbon — all open items are documented honestly as they stand.

Key Numbers — All with Measurement Conventions

These numbers are all extracted from docs/MODEL_CARD.md in the repository and are auto-generated by band_profile.py with the --model-card flag. Generation conditions: 4 million rays × 2000 solar sub-samples, with a fixed random seed to guarantee reproducibility. The default physics combination is Rayleigh scattering plus ozone absorption plus two-component background aerosol plus solar limb darkening. Any time the physics code changes, the model card is regenerated so the numbers always match the current code.

QuantityValueConvention
Umbral center brightness−15.1 stopsphotopic, 0 stops = uneclipsed full Moon, default physics; independent pipeline cross-check gives −15.3 stops, difference within Poisson statistics for the central three bins
Umbral center brightness (molecular upper bound)−13.5 stopssame convention, but aerosols and limb darkening switched off: the theoretical brightness ceiling for pure Rayleigh + ozone
Red-to-blue ratio at bluest point of band0.814 (at 41.0′)raw sRGB linear channel ratio, includes measured solar spectrum, no normalization — the quantity actually presented in renders; molecular-atmosphere comparison is 0.715 (at 40.3′)
Brightness cliff width20.4′ (46.7′ to 67.1′)photopic surface brightness rising from 10% to 90% of full Moon, i.e. the entire penumbral ramp
Steepest gradient at umbral edge1.8 stops/arcmin35′ to 50′ window, 3-bin smoothing
Central B / V / R extinction16.6 / 11.8 / 9.2 magin-band normalization (uneclipsed full Moon = 0 mag per band), includes ~4.6 mag geometric dilution; I band is missing water vapor and oxygen absorption bands — absolute value not referenced
Reference anchors−18.7 to −20.5 stopsMallama clear-sky empirical model, disk-integrated and disk-resolved V-band respectively; the gap from our model is an open item

Reproduction Commands for Every Production Image

Run from the repository root directory, after activating the virtual environment with source .venv/bin/activate. A complete ray-tracing run takes on the order of seconds; video rendering takes minutes.

# Homepage hero: realistic eclipse moon disk (true ray-tracing LUT, default d=40')
python src/render_textured.py

# Six-step ablation sequence (enhanced preview + 16bit linear TIFF)
python src/render_ablation.py

# Photometric profile curve (fixed 16M-ray stratified sampling, page version is this output)
python scripts/render_photometric_profile.py

# Dual-perspective quad video (SDR + HDR)
python src/build_video.py

# Brightness cliff: two-exposure comparison
python src/diag_brightness_cliff.py

# Model card (source of all numbers on the page and table above)
python src/band_profile.py --model-card --n-rays 4000000

# Physics invariants and render smoke tests
python -m pytest src/tests/ -v

The point-source vs. disk comparison figure is rendered using the disk ray-tracing mode and its point-source degradation mode in src/brute_ray_trace.py. The trajectory-composite illustration comes from one-off scripts, with composition parameters recorded in docs/working.md.

Where to Find the Full Failure Log

This page shows you the pipeline in its final form, but the detours taken to get here are far more interesting than the end result. Two examples. First: we once invented an incorrect refraction formula to fix a bug that didn't actually exist. This formula moved the turquoise band to a position that felt intuitively more correct, and armed with the confidence of a problem apparently solved, it lived in the codebase for an entire day. We only discovered it was wrong during the line-by-line reconciliation with the literature, and deleted it on the spot. A wrong fix is far more dangerous than the original error. Second: for a while, the CIELAB hue angle was showing the turquoise band as strongly blue-shifted, and we nearly modified the physics model because of that signal. It turned out that the CIELAB color metric itself amplifies mild blue shifts — the physics model was fine. From that point on we adopted a principle: when the hue doesn't match, suspect the measurement tool first, then the physics model.

All the pitfalls, root-cause analyses, and corresponding fixes are in the repository at docs/PHYSICS_AND_PITFALLS.md. The day-by-day work log and every errata-correction process is recorded in docs/working.md. Literature references: Mallama 2021/2022 (arXiv:2112.08966), Shu et al. 2024 (Remote Sensing 16(22):4181), Serdyuchenko et al. 2014 ozone cross-sections, AFGL atmospheric profiles, SAO2010 solar spectrum.