Give every star a limb-darkened surface in its own colour, and light its planets with it

Every star but the Sun was a flat disc of one colour, and the Sun wore the texture pack's orange
photograph, lit by the same white light as every other star's planets.

Every star now shares one TSL material (starSurfaceMaterial in the scene): the Sun's map in grey,
times the colour of a blackbody at the star's temperature, times a linear limb-darkening law,
1 - 0.6 (1 - mu), the Sun's coefficient in the visible. The temperature is the one the radius
uses: the archive's st_teff for a host, else the dwarf sequence at its colour or type, else
the Sun's.
The colour comes from blackbodyColor (stellar.ts): Kim et al.'s cubic fit to the Planckian locus,
then CIE XYZ to linear sRGB, brightest channel 1. At D65 it gives 2 900 K (255, 180, 103), 5 800 K
(255, 241, 235) and 9 600 K (208, 219, 255), against (255, 182, 98), (255, 241, 231) and
(211, 221, 255) in Charity's integrated blackbody table. The tint is a uniform, so the shader is
built once and not per system.

The star's PointLight takes the same colour against the Sun's, since the planets' photographs
were taken in sunlight: the Sun's light stays white at pi, TRAPPIST-1's (2 566 K) is
(1, 0.44, 0.10) and Proxima's (2 900 K) (1, 0.52, 0.17), Sirius's (0.52, 0.67, 1). The intensity
stays pi. No halo comes back.

sun.jpg was 2048 by 1024 and 822 427 bytes for a disc that reaches 216 px across at the Sun's
closest approach on a 1080-line screen. It is now 1024 by 512 in grey, 31 306 bytes, which covers
the disc to a 1440-line screen. Its brightness varied by 56 % rms, which made every star a mottled
rock; it is rescaled to 14 % rms about the display's white, of the order of the Sun's granulation
contrast, the brighter half clipped as in a photograph exposed for the disc (6 % rms remains).

Measured on the dev server (1600 by 1000, the camera at its closest approach):
- the disc's brightness against the law, from r/R 0.52 to 0.97: Sun 0.970/0.841/0.763/0.657/0.560
  against 0.927/0.829/0.755/0.645/0.554, ups And and Sirius the same to within 0.05;
- the disc's centre in sRGB: Sun (245, 233, 226), ups And (F8V, 6 157 K) (249, 239, 239),
  Sirius (199, 209, 243);
- the first system entry of a fresh page, three runs each in alternating blocks against the
  previous commit: Sol's longest task 90 ms before, 86 ms after, two tasks over 50 ms in every
  run either way; Proxima Centauri's none over 50 ms after, one run of six with a 53 ms task
  before. The long tasks on Sol's first entry predate this change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-25 15:10:52 +02:00
co-authored by Claude Opus 5.5
parent 7213f987c4
commit 2242fe0a7f
7 changed files with 163 additions and 29 deletions
@@ -10,6 +10,7 @@ import {
} from '@angular/core'; } from '@angular/core';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import * as THREE from 'three/webgpu'; import * as THREE from 'three/webgpu';
import { normalView, positionViewDirection, texture, uniform } from 'three/tsl';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { import {
@@ -19,6 +20,7 @@ import {
galacticCentrePositionPc, galacticCentrePositionPc,
galacticToEquatorial, galacticToEquatorial,
} from '../../shared/astro/galaxy'; } from '../../shared/astro/galaxy';
import { blackbodyColor, SOLAR_EFFECTIVE_TEMPERATURE_K } from '../../shared/astro/stellar';
import { DataLoaderService } from '../../core/data/data-loader.service'; import { DataLoaderService } from '../../core/data/data-loader.service';
import { EngineService, SceneCamera } from '../../core/engine/engine.service'; import { EngineService, SceneCamera } from '../../core/engine/engine.service';
import { BodyRecord } from '../../shared/models/body.model'; import { BodyRecord } from '../../shared/models/body.model';
@@ -68,7 +70,6 @@ import { StarmapHudComponent } from './starmap-hud.component';
import { SystemObjectCardComponent } from './system-object-card.component'; import { SystemObjectCardComponent } from './system-object-card.component';
import { RoutingClient } from './routing-client'; import { RoutingClient } from './routing-client';
import { import {
colorIndexToRgb,
FOCUS_RADIUS_PC, FOCUS_RADIUS_PC,
StarFieldRenderer, StarFieldRenderer,
starRenderBudgetFromUrl, starRenderBudgetFromUrl,
@@ -85,11 +86,37 @@ import { LabeledPoint, LabelSide, StarLabelOverlay } from './star-label-overlay'
import { SystemOrbitsRenderer } from './system-orbits-renderer'; import { SystemOrbitsRenderer } from './system-orbits-renderer';
import { catalogueCensus, starReadouts, starSubtitle } from './star-readouts'; import { catalogueCensus, starReadouts, starSubtitle } from './star-readouts';
/** HYG catalog id for the Sun itself — the only star we have a real close-up photo of. */
const SOL_STAR_ID = 0;
/** Radius, in CSS pixels, below which a body in the system view is scaled up to be seen at all. */ /** Radius, in CSS pixels, below which a body in the system view is scaled up to be seen at all. */
const MIN_MARKER_PIXELS = 3; const MIN_MARKER_PIXELS = 3;
/**
* The linear limb-darkening coefficient: a star's surface is I(μ) = I(1) (1 − u (1 − μ)) bright,
* where μ is the cosine of the angle between the line of sight and the surface normal. The Sun's
* is about 0.6 in the visible, so its limb is 40 % as bright as its centre. Taken for every star,
* although a hotter star's limb is somewhat brighter and a cooler one's darker.
*/
const LIMB_DARKENING = 0.6;
/**
* The surface every star is drawn with: the Sun's photograph in grey, in `tint` — the colour of a
* blackbody at the star's temperature — and darkened towards the limb. Unlit: it is the source.
*
* The pattern is the Sun's, standing in for a surface no telescope resolves on another star, at a
* contrast turned down to the Sun's own (see `SUN_TEXTURE_PATH`). Its colour was taken out, so
* the tint says what colour the star is rather than which filter the Sun was photographed in: the
* Sun itself comes out the warm white of 5 772 K, not the pack's orange.
*
* The tint is a uniform, so every star shares one shader, compiled on the first system entry.
*/
function starSurfaceMaterial(tint: THREE.Node<'color'>): THREE.MeshBasicNodeMaterial {
const material = new THREE.MeshBasicNodeMaterial();
const mu = normalView.dot(positionViewDirection).clamp(0, 1);
material.colorNode = texture(loadCachedTexture(SUN_TEXTURE_PATH))
.rgb.mul(tint)
.mul(mu.sub(1).mul(LIMB_DARKENING).add(1));
return material;
}
/** /**
* How far from what the camera is looking at a star can be and still be named, as a fraction of * How far from what the camera is looking at a star can be and still be named, as a fraction of
* how far back the camera is — so the net widens as the view pulls out and closes as it dives * how far back the camera is — so the net widens as the view pulls out and closes as it dives
@@ -413,7 +440,10 @@ export class GalaxySystemSceneComponent implements AfterViewInit, OnDestroy {
private readonly raycaster = new THREE.Raycaster(); private readonly raycaster = new THREE.Raycaster();
private readonly galaxyGroup = new THREE.Group(); private readonly galaxyGroup = new THREE.Group();
private readonly systemGroup = new THREE.Group(); private readonly systemGroup = new THREE.Group();
private readonly starMarkerMaterial = new THREE.MeshBasicMaterial({ color: 0xffffff }); /** The colour of the system's star, set on entering it; see `starSurfaceMaterial`. */
private readonly starTint = uniform(new THREE.Color(1, 1, 1));
/** One for every star, built on the first system entry, so its pipeline is compiled once. */
private starMarkerMaterial?: THREE.MeshBasicNodeMaterial;
/** Rebuilt per system, since every star has its own radius. */ /** Rebuilt per system, since every star has its own radius. */
private starMarkerGeometry?: THREE.SphereGeometry; private starMarkerGeometry?: THREE.SphereGeometry;
@@ -599,9 +629,8 @@ export class GalaxySystemSceneComponent implements AfterViewInit, OnDestroy {
this.tethers?.dispose(); this.tethers?.dispose();
this.labelOverlay?.dispose(); this.labelOverlay?.dispose();
this.systemRenderer?.dispose(); this.systemRenderer?.dispose();
(this.starMarker?.material as THREE.Material | undefined)?.dispose();
this.starMarkerGeometry?.dispose(); this.starMarkerGeometry?.dispose();
this.starMarkerMaterial.dispose(); this.starMarkerMaterial?.dispose();
this.engine.dispose(); this.engine.dispose();
} }
@@ -2182,7 +2211,6 @@ export class GalaxySystemSceneComponent implements AfterViewInit, OnDestroy {
this.systemRenderer?.dispose(); this.systemRenderer?.dispose();
if (this.starMarker) { if (this.starMarker) {
this.systemGroup.remove(this.starMarker); this.systemGroup.remove(this.starMarker);
(this.starMarker.material as THREE.Material).dispose();
} }
const systemBodies = this.bodies.filter((body) => body.systemStarId === star.id); const systemBodies = this.bodies.filter((body) => body.systemStarId === star.id);
@@ -2195,19 +2223,21 @@ export class GalaxySystemSceneComponent implements AfterViewInit, OnDestroy {
// The star's luminosity, derived from its own catalogued magnitude and distance, is what // The star's luminosity, derived from its own catalogued magnitude and distance, is what
// decides how hot each body in the system is — and so what each of them looks like. // decides how hot each body in the system is — and so what each of them looks like.
const hostLuminosity = luminosityOf(star); const hostLuminosity = luminosityOf(star);
// Every star at its own radius: the archive's for a planet host, otherwise derived from its
// colour and brightness — or the Sun's, for the 3 077 stars with no measured magnitude or with
// neither a colour nor a type, which the card then gives no radius. Its temperature is the
// colour of its disc and of the light it casts.
this.currentStarSurface = starSurfaceOf(star, systemExoplanets);
this.systemRenderer = new SystemOrbitsRenderer( this.systemRenderer = new SystemOrbitsRenderer(
systemBodies, systemBodies,
systemExoplanets, systemExoplanets,
{ x: star.x, y: star.y, z: star.z }, { x: star.x, y: star.y, z: star.z },
hostLuminosity, hostLuminosity,
this.currentStarSurface.temperatureK,
); );
this.systemGroup.add(this.systemRenderer.object); this.systemGroup.add(this.systemRenderer.object);
this.applyDisplay(this.display()); this.applyDisplay(this.display());
// Every star at its own radius: the archive's for a planet host, otherwise derived from its
// colour and brightness — or the Sun's, for the 3 077 stars with no measured magnitude or with
// neither a colour nor a type, which the card then gives no radius.
this.currentStarSurface = starSurfaceOf(star, systemExoplanets);
const starRadiusAu = (this.currentStarSurface.radiusSolar ?? 1) * SUN_RADIUS_AU; const starRadiusAu = (this.currentStarSurface.radiusSolar ?? 1) * SUN_RADIUS_AU;
// Framed against the grid's outer ring rather than the outermost orbit — the ring is always // Framed against the grid's outer ring rather than the outermost orbit — the ring is always
@@ -2225,20 +2255,15 @@ export class GalaxySystemSceneComponent implements AfterViewInit, OnDestroy {
this.starMarkerGeometry?.dispose(); this.starMarkerGeometry?.dispose();
this.starMarkerGeometry = new THREE.SphereGeometry(starRadiusAu, 64, 32); this.starMarkerGeometry = new THREE.SphereGeometry(starRadiusAu, 64, 32);
const starMarkerMaterial = this.starMarkerMaterial.clone(); this.starMarkerMaterial ??= starSurfaceMaterial(this.starTint);
const starColor = colorIndexToRgb(star.colorIndex, star.spectralType); this.starTint.value.setRGB(
if (star.id === SOL_STAR_ID) { ...blackbodyColor(this.currentStarSurface.temperatureK ?? SOLAR_EFFECTIVE_TEMPERATURE_K),
// The Sun is the only star we have (and could ever have) a real photograph of; every THREE.LinearSRGBColorSpace,
// other point in the galaxy view is far too distant to be resolved as a disk. );
starMarkerMaterial.map = loadCachedTexture(SUN_TEXTURE_PATH);
starMarkerMaterial.color.set(0xffffff);
} else {
starMarkerMaterial.color.copy(starColor);
}
// No halo. It was a sprite sized against the arrival frame — 1.12 AU for the Sun — so it // No halo. It was a sprite sized against the arrival frame — 1.12 AU for the Sun — so it
// stayed put as the camera closed in and ended up filling the screen with the flat gradient // stayed put as the camera closed in and ended up filling the screen with the flat gradient
// that was meant to dress the star, over the photograph underneath it. // that was meant to dress the star, over the photograph underneath it.
this.starMarker = new THREE.Mesh(this.starMarkerGeometry, starMarkerMaterial); this.starMarker = new THREE.Mesh(this.starMarkerGeometry, this.starMarkerMaterial);
this.systemGroup.add(this.starMarker); this.systemGroup.add(this.starMarker);
this.galaxyGroup.visible = false; this.galaxyGroup.visible = false;
@@ -464,3 +464,29 @@ describe('exoplanet size without a measured radius', () => {
expect(radiusOf({ radiusEarth: 1.88, massEarth: 2829 }) / EARTH_AU).toBeCloseTo(1.88, 2); expect(radiusOf({ radiusEarth: 1.88, massEarth: 2829 }) / EARTH_AU).toBeCloseTo(1.88, 2);
}); });
}); });
describe("SystemOrbitsRenderer's star light", () => {
const lightOf = (renderer: SystemOrbitsRenderer): THREE.PointLight => {
let light: THREE.PointLight | undefined;
renderer.object.traverse((object) => (light ??= (object as THREE.PointLight).isPointLight ? (object as THREE.PointLight) : undefined));
return light!;
};
it("is white at π from the Sun, or from a star with no temperature", () => {
for (const renderer of [new SystemOrbitsRenderer([], [], undefined, 1, 5772), new SystemOrbitsRenderer([], [exoplanet()])]) {
expect(lightOf(renderer).color.toArray()).toEqual([1, 1, 1]);
expect(lightOf(renderer).intensity).toBe(Math.PI);
renderer.dispose();
}
});
it("lights an M dwarf's planets orange-red, at the same π", () => {
const renderer = new SystemOrbitsRenderer([], [exoplanet()], undefined, 5.5e-4, 2566);
const [r, g, b] = lightOf(renderer).color.toArray();
expect(r).toBe(1);
expect(g).toBeLessThan(0.5);
expect(b).toBeLessThan(0.15);
expect(lightOf(renderer).intensity).toBe(Math.PI);
renderer.dispose();
});
});
@@ -7,6 +7,7 @@ import { planetTexture } from '../../shared/rendering/procedural-planet-texture'
import { bodyTexturePath, loadCachedTexture } from '../../shared/rendering/texture-catalog'; import { bodyTexturePath, loadCachedTexture } from '../../shared/rendering/texture-catalog';
import { isPropagatableOrbit, orbitEllipsePoints, propagateOrbit, resolveGravitationalParameter, resolveOrbitalElements } from '../../shared/astro/kepler'; import { isPropagatableOrbit, orbitEllipsePoints, propagateOrbit, resolveGravitationalParameter, resolveOrbitalElements } from '../../shared/astro/kepler';
import { CartesianCoordinates, OBLIQUITY_J2000_DEG } from '../../shared/astro/coordinates'; import { CartesianCoordinates, OBLIQUITY_J2000_DEG } from '../../shared/astro/coordinates';
import { blackbodyColor, SOLAR_EFFECTIVE_TEMPERATURE_K } from '../../shared/astro/stellar';
import { BodyRecord, OrbitalElements } from '../../shared/models/body.model'; import { BodyRecord, OrbitalElements } from '../../shared/models/body.model';
import { bodyMarkerRadiusAu, systemGridRingsAu } from './system-framing'; import { bodyMarkerRadiusAu, systemGridRingsAu } from './system-framing';
import { PolarGridPlane, TetherField } from './grid-plane'; import { PolarGridPlane, TetherField } from './grid-plane';
@@ -157,12 +158,18 @@ function buildMarker(id: string | undefined, kind: SystemMemberKind, radiusKm: n
* floor makes for size. What the light does carry truthfully is which side is day: every body * floor makes for size. What the light does carry truthfully is which side is day: every body
* shows its lit face toward the star, and the terminator falls where it really falls. * shows its lit face toward the star, and the terminator falls where it really falls.
* *
* White, at π: a Lambertian surface returns intensity / π of its texture where the light falls * At π: a Lambertian surface returns intensity / π of its texture where the light falls square on
* square on it, so π gives back the photograph itself at the point facing the star, and less * it, so π gives back the photograph itself at the point facing the star, and less towards the
* towards the limb. A warm tint or a smaller figure darkened the photographs below what they are. * limb. A smaller figure darkened the photographs below what they are.
*
* In the star's own colour, against the Sun's: the photographs were taken in sunlight, so the
* Sun's light is white and gives them back as they are, and another star's shifts them as its
* spectrum differs from the Sun's — a 2 566 K M dwarf's is (1, 0.44, 0.10), orange-red, and a
* 9 600 K A star's (0.52, 0.67, 1), blue. A star with no temperature is lit as the Sun.
*/ */
function starLight(): THREE.PointLight { function starLight(temperatureK: number | null | undefined): THREE.PointLight {
const light = new THREE.PointLight(0xffffff, Math.PI, 0, 0); const light = new THREE.PointLight(0xffffff, Math.PI, 0, 0);
light.color.setRGB(...blackbodyColor(temperatureK ?? SOLAR_EFFECTIVE_TEMPERATURE_K, SOLAR_EFFECTIVE_TEMPERATURE_K), THREE.LinearSRGBColorSpace);
light.position.set(0, 0, 0); light.position.set(0, 0, 0);
return light; return light;
} }
@@ -296,7 +303,9 @@ export class SystemOrbitsRenderer {
* system is and therefore what it looks like. Omitted for a host that is not in the star * system is and therefore what it looks like. Omitted for a host that is not in the star
* catalogue, leaving its bodies classified on size and density alone. * catalogue, leaving its bodies classified on size and density alone.
*/ */
hostLuminositySolar?: number | null hostLuminositySolar?: number | null,
/** The host star's effective temperature, which is the colour of the light it casts. */
hostTemperatureK?: number | null
) { ) {
const members: SystemMember[] = []; const members: SystemMember[] = [];
const topLevelBodiesById = new Map<string, BodyRecord>(); const topLevelBodiesById = new Map<string, BodyRecord>();
@@ -394,7 +403,7 @@ export class SystemOrbitsRenderer {
} }
// The star lights its own system. The star marker itself is unlit — it is the source, not a // The star lights its own system. The star marker itself is unlit — it is the source, not a
// surface — so nothing here changes how it is drawn. // surface — so nothing here changes how it is drawn.
this.object.add(starLight()); this.object.add(starLight(hostTemperatureK));
} }
/** Recomputes every marker's position for the given Julian date. Call once per tick. */ /** Recomputes every marker's position for the given Julian date. Call once per tick. */
+27
View File
@@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest';
import { import {
absoluteMagnitude, absoluteMagnitude,
blackbodyColor,
bolometricCorrection, bolometricCorrection,
effectiveTemperatureK, effectiveTemperatureK,
luminositySolar, luminositySolar,
@@ -164,3 +165,29 @@ describe('radiusFromLuminositySolar', () => {
} }
}); });
}); });
describe('blackbodyColor', () => {
/** As the display shows it: sRGB-encoded, 0 to 255. */
const displayed = (rgb: readonly number[]) => rgb.map((v) => Math.round(255 * (v <= 0.0031308 ? 12.92 * v : 1.055 * v ** (1 / 2.4) - 0.055)));
it('gives the colours of the stars against the display white', () => {
// Charity's blackbody colour table (CIE 1931 2°, D65): 2 900 K #ffb662, 5 800 K #fff1e7, 9 600 K #d3ddff.
for (const [temperatureK, expected] of [[2900, [255, 182, 98]], [5800, [255, 241, 231]], [9600, [211, 221, 255]]] as const) {
displayed(blackbodyColor(temperatureK)).forEach((channel, i) => expect(Math.abs(channel - expected[i])).toBeLessThanOrEqual(5));
}
});
it("is white at the white point it is given, and an M dwarf's light orange-red against the Sun's", () => {
expect(blackbodyColor(SOLAR_EFFECTIVE_TEMPERATURE_K, SOLAR_EFFECTIVE_TEMPERATURE_K)).toEqual([1, 1, 1]);
const [r, g, b] = blackbodyColor(2566, SOLAR_EFFECTIVE_TEMPERATURE_K);
expect(r).toBe(1);
expect(g).toBeCloseTo(0.44, 2);
expect(b).toBeCloseTo(0.1, 2);
});
it('holds the ends of the fit, and never goes negative', () => {
expect(blackbodyColor(800)).toEqual(blackbodyColor(1667));
expect(blackbodyColor(60000)).toEqual(blackbodyColor(25000));
expect(Math.min(...blackbodyColor(1667))).toBe(0);
});
});
+38
View File
@@ -159,3 +159,41 @@ export function effectiveTemperatureK(star: StellarPhotometry): number | null {
export function radiusFromLuminositySolar(luminositySolar: number, temperatureK: number): number { export function radiusFromLuminositySolar(luminositySolar: number, temperatureK: number): number {
return Math.sqrt(luminositySolar) / (temperatureK / SOLAR_EFFECTIVE_TEMPERATURE_K) ** 2; return Math.sqrt(luminositySolar) / (temperatureK / SOLAR_EFFECTIVE_TEMPERATURE_K) ** 2;
} }
/** The range Kim et al.'s fit to the Planckian locus covers; a temperature outside it is clamped. */
const PLANCKIAN_LOCUS_MIN_K = 1667;
const PLANCKIAN_LOCUS_MAX_K = 25000;
/**
* The colour of a blackbody at `temperatureK`, in linear sRGB with its brightest channel at 1:
* its chromaticity off the Planckian locus (Kim et al. 2002, the cubic fit to CIE 1931), then
* CIE XYZ to sRGB. Against the display's own white, D65, unless `whitePointK` names the blackbody
* that is to read as white — as the Sun's does for the photographs of its planets, which were
* taken in its light.
*
* At D65, a 2 900 K M dwarf is sRGB (255, 180, 103), the Sun (255, 241, 234), a 9 600 K A star
* (208, 219, 255): Charity's table, which integrates the Planck spectrum, gives (255, 182, 98),
* (255, 241, 231) at 5 800 K and (211, 221, 255).
*/
export function blackbodyColor(temperatureK: number, whitePointK?: number): [number, number, number] {
const rgb = blackbodyLinearSrgb(temperatureK);
const white = whitePointK === undefined ? [1, 1, 1] : blackbodyLinearSrgb(whitePointK);
const relative = rgb.map((channel, i) => channel / white[i]);
const brightest = Math.max(...relative);
return relative.map((channel) => channel / brightest) as [number, number, number];
}
function blackbodyLinearSrgb(temperatureK: number): number[] {
const t = 1000 / Math.min(Math.max(temperatureK, PLANCKIAN_LOCUS_MIN_K), PLANCKIAN_LOCUS_MAX_K);
const x =
t >= 0.25 ? -0.2661239 * t ** 3 - 0.2343589 * t ** 2 + 0.8776956 * t + 0.17991 : -3.0258469 * t ** 3 + 2.1070379 * t ** 2 + 0.2226347 * t + 0.24039;
const y =
t >= 1000 / 2222
? -1.1063814 * x ** 3 - 1.3481102 * x ** 2 + 2.18555832 * x - 0.20219683
: t >= 0.25
? -0.9549476 * x ** 3 - 1.37418593 * x ** 2 + 2.09137015 * x - 0.16748867
: 3.081758 * x ** 3 - 5.8733867 * x ** 2 + 3.75112997 * x - 0.37001483;
const [X, Y, Z] = [x / y, 1, (1 - x - y) / y];
// Below 1 920 K the locus leaves the sRGB gamut, and blue comes out negative.
return [3.2406 * X - 1.5372 * Y - 0.4986 * Z, -0.9689 * X + 1.8758 * Y + 0.0415 * Z, 0.0557 * X - 0.204 * Y + 1.057 * Z].map((channel) => Math.max(channel, 0));
}
+10 -1
View File
@@ -32,7 +32,16 @@ const BODY_TEXTURE_PATHS: Record<string, string> = {
moon: 'assets/textures/bodies/moon.jpg' moon: 'assets/textures/bodies/moon.jpg'
}; };
/** The Sun isn't a `BodyRecord` (it's the system's star marker), so it's looked up separately. */ /**
* The Sun's surface, which every star's disc in the system view is drawn with, tinted to its own
* colour. Baked from the pack's 2048 by 1024 map (822 427 bytes) to 1024 by 512 in grey (31 306):
* the Sun reaches 216 px across at its closest approach on a 1080-line screen, and a sphere shows
* π times its diameter of the map round its equator, so this covers it to a 1440-line one. The
* tint supplies the colour. The map's brightness varied by 56 % rms, a mottled rock rather than a
* star; it is rescaled to 14 % rms about the display's white, of the order of the Sun's own
* granulation contrast, and the brighter half clipped there as in a photograph exposed for the
* disc, which leaves 6 %. Not a `BodyRecord`, so it is looked up separately.
*/
export const SUN_TEXTURE_PATH = 'assets/textures/bodies/sun.jpg'; export const SUN_TEXTURE_PATH = 'assets/textures/bodies/sun.jpg';
export const SATURN_RING_TEXTURE_PATH = 'assets/textures/bodies/saturn_ring.png'; export const SATURN_RING_TEXTURE_PATH = 'assets/textures/bodies/saturn_ring.png';
export const MILKY_WAY_SKYBOX_PATH = 'assets/textures/skybox/milkyway.jpg'; export const MILKY_WAY_SKYBOX_PATH = 'assets/textures/skybox/milkyway.jpg';
Binary file not shown.

Before

Width:  |  Height:  |  Size: 803 KiB

After

Width:  |  Height:  |  Size: 31 KiB