tower / commit
fix(exterior): an opaque sun with a soft halo
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) } /**