fuzzyworld

tower / commit

fix(exterior): an opaque sun with a soft halo

2edbf4728a966ef81d2c64ed964ded93a3df4bf8 · Pavel Safronov · 2026-09-27 16:40:17 -0700 · parents 28896dabbe2b

Claude Code usage: this commit ≈0 out / ≈0 cached · cost unknown (no per-model trailer) · session 2 tally 744 in / 324.4K out / 79.7M cached · usage by commit and session

fix(exterior): an opaque sun with a soft halo

The sun was a beige sphere at half opacity, so it looked muted and the
stars behind it showed through. It is now an opaque near-white disc with
an additive radial-gradient halo.

Usage: 744 in / 324.4K out / 79.7M cached (session tally)
rtk:   905.3K saved, 15.2% over 2657 cmds (global/lifetime)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
 src/views/exterior.ts | 33 ++++++++++++++++++++++++++++-----
 1 file changed, 28 insertions(+), 5 deletions(-)

diff --git a/src/views/exterior.ts b/src/views/exterior.ts
index e76a9bd..f670805 100644
--- a/src/views/exterior.ts
+++ b/src/views/exterior.ts
@@ -12,7 +12,8 @@ import {
   DirectionalLight, DoubleSide, Float32BufferAttribute, FrontSide, Group, LineBasicMaterial,
   LineSegments, Matrix4, Mesh, MeshBasicMaterial, MeshStandardMaterial, PerspectiveCamera,
   Raycaster, RepeatWrapping, RingGeometry, SRGBColorSpace, Scene, ShaderMaterial,
-  SphereGeometry, CanvasTexture, Vector2, Vector3, WebGLRenderer, AdditiveBlending,
+  SphereGeometry, CanvasTexture, Sprite, SpriteMaterial, Vector2, Vector3, WebGLRenderer,
+  AdditiveBlending,
 } from 'three'
 import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
 import {
@@ -479,11 +480,33 @@ export class ExteriorView {
     sky.frustumCulled = false
     this.scene.add(sky)
 
-    const glow = new Mesh(
+    /**
+     * The sun: an opaque, near-white disc, so the stars behind it are hidden as they
+     * would be. At half opacity it read as a beige plate with stars showing through it.
+     * A soft halo round it, fading to nothing, makes it read as a light rather than a
+     * paper disc.
+     */
+    const sun = new Mesh(
       new SphereGeometry(300, 24, 24),
-      new MeshBasicMaterial({ color: 0xffe9bd, transparent: true, opacity: 0.5, side: BackSide }))
-    glow.position.z = -14_000
-    this.scene.add(glow)
+      new MeshBasicMaterial({ color: 0xfff7e6, side: BackSide }))
+    sun.position.z = -14_000
+    this.scene.add(sun)
+    const c = document.createElement('canvas')
+    c.width = c.height = 128
+    const ctx = c.getContext('2d')!
+    const g = ctx.createRadialGradient(64, 64, 0, 64, 64, 64)
+    g.addColorStop(0, 'rgba(255, 240, 210, 0.9)')
+    g.addColorStop(0.25, 'rgba(255, 226, 170, 0.35)')
+    g.addColorStop(0.6, 'rgba(255, 210, 140, 0.08)')
+    g.addColorStop(1, 'rgba(255, 200, 120, 0)')
+    ctx.fillStyle = g
+    ctx.fillRect(0, 0, 128, 128)
+    const halo = new Sprite(new SpriteMaterial({
+      map: new CanvasTexture(c), blending: AdditiveBlending, depthWrite: false,
+    }))
+    halo.scale.setScalar(2400)
+    halo.position.z = -14_000
+    this.scene.add(halo)
   }
 
   /**