Test the star's disc itself: its photograph, its colour and its darkening toward the limb

2242fe0 gave every star the Sun's photograph in grey, tinted at its temperature and limb-darkened
as 1 - 0.6(1 - mu), and nothing tested any of the three: with the coefficient at 0, the tint
dropped from the material, or the photograph replaced by the tint alone, all 817 tests passed. The
one colour test read scene.starTint, a uniform the scene sets whether or not the material uses it.

The new test enters Proxima and walks the disc material's colour node graph for the tint uniform,
the texture loaded from SUN_TEXTURE_PATH and the coefficient 0.6. Controls, each failing it alone
(1 of 820): the coefficient at 0; at -0.6, a limb brighter than the centre; the tint dropped; the
photograph replaced by the tint. A mutant that keeps the texture node in the graph but multiplies
it by nothing is not caught; the test checks the parts, not the arithmetic between them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-30 15:57:52 +02:00
co-authored by Claude Opus 5.5
parent 368fcfb6f0
commit f8582b78d0
@@ -19,6 +19,7 @@ import { closestApproachAu, SUN_RADIUS_AU } from './system-framing';
import { blackbodyColor, SOLAR_EFFECTIVE_TEMPERATURE_K } from '../../shared/astro/stellar'; import { blackbodyColor, SOLAR_EFFECTIVE_TEMPERATURE_K } from '../../shared/astro/stellar';
import { appearanceForExoplanet } from '../../shared/astro/body-appearance'; import { appearanceForExoplanet } from '../../shared/astro/body-appearance';
import { planetTexture } from '../../shared/rendering/procedural-planet-texture'; import { planetTexture } from '../../shared/rendering/procedural-planet-texture';
import { loadCachedTexture, SUN_TEXTURE_PATH } from '../../shared/rendering/texture-catalog';
import { JumpLinkRenderer } from './jump-link-renderer'; import { JumpLinkRenderer } from './jump-link-renderer';
import { StarFieldRenderer } from './star-field-renderer'; import { StarFieldRenderer } from './star-field-renderer';
import { LabeledPoint, StarLabelOverlay } from './star-label-overlay'; import { LabeledPoint, StarLabelOverlay } from './star-label-overlay';
@@ -1016,6 +1017,27 @@ describe('GalaxySystemSceneComponent camera-flight transitions', () => {
expect(scene.hudReadouts().find((readout) => readout.label === 'Radius')?.value).toBe('0.141 solar radii'); expect(scene.hudReadouts().find((readout) => readout.label === 'Radius')?.value).toBe('0.141 solar radii');
}); });
it("draws the disc as the Sun's photograph in the star's colour, darkened towards the limb", async () => {
// The disc's three parts, read off the material's node graph: the tint the star's temperature
// sets, the photograph, and the limb-darkening coefficient, 0.6 as the Sun's. Before, only the
// tint uniform was read, which the scene sets whether or not the material uses it.
const scene = await enter(PROXIMA);
const nodes = new Set<THREE.Node>();
const walk = (node: THREE.Node): void => {
if (!nodes.has(node)) {
nodes.add(node);
for (const child of node.getChildren()) {
walk(child);
}
}
};
walk((scene as unknown as { starMarkerMaterial: THREE.MeshBasicNodeMaterial }).starMarkerMaterial.colorNode!);
const values = [...nodes].map((node) => (node as { value?: unknown }).value);
expect(values).toContain(scene.starTint.value);
expect(values).toContain(loadCachedTexture(SUN_TEXTURE_PATH));
expect(values).toContain(0.6);
});
it('tints a host in the star field the colour its disc is drawn in, at the temperature the archive gives it', async () => { it('tints a host in the star field the colour its disc is drawn in, at the temperature the archive gives it', async () => {
// Proxima's B−V 1.8 reads 3 070 K; its disc is drawn at the archive's 2 900. // Proxima's B−V 1.8 reads 3 070 K; its disc is drawn at the archive's 2 900.
const scene = await enter(PROXIMA); const scene = await enter(PROXIMA);