feat(sky): the night sky wheels with the Dereth clock; uniform time fade with a scoped twilight band
Rotation (user-directed): the procedural starfield rotates once per Dereth day (~2 real hours - constellations visibly wheel through a night) about a celestial pole ~41 deg above the northern horizon, plus dayOfYear/360 of seasonal drift so the 360-day year changes the night sky. One SkyParams float (272-byte block, layout test re-pinned) carries dayFraction + dayOfYear/360 from the world clock; sky.frag applies a Rodrigues rotation to the sample direction so stars and mottle turn together. Impossible with retail's static stretched layer. Fade rework (the 2026-08-23 two-screenshot gate finding): the per-vertex vTint signal carried the sun-facing product and blanked stars across the entire twilight half of the sky. The fade now reads the UNIFORM ambient term - identical star visibility in every compass direction, same dusk-to-dawn schedule - with one deliberate exception: a thin suppression band hugging the low sky toward the sun's azimuth while the sun term is strong, so stars still wash out inside the actual twilight glow. Guards updated (rotation anchor, uniform-fade anchor, 272-byte layout); both sky SPIR-V hashes re-pinned. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
91084b9a83
commit
0dac024cdb
10 changed files with 98 additions and 15 deletions
|
|
@ -106,6 +106,13 @@ public sealed partial class SkyRenderer : IDisposable
|
|||
/// </summary>
|
||||
internal Func<bool>? EnhancedNightSkyActive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dereth-clock rotation source for the enhanced night sky, in turns
|
||||
/// (dayFraction + dayOfYear/360). Composition wires it to the world
|
||||
/// time service; evaluated once per sky pass.
|
||||
/// </summary>
|
||||
internal Func<float>? NightSkyRotationTurns { get; set; }
|
||||
|
||||
/// <summary>Deterministic seed for the procedural sky's hash grids —
|
||||
/// the approved-look generator's seed (gen_starfield2.py, 2026-08-23).</summary>
|
||||
private const float NightSkySeed = 11f;
|
||||
|
|
@ -209,6 +216,8 @@ public sealed partial class SkyRenderer : IDisposable
|
|||
// that FOV here, including the near-180-degree teleport transition.
|
||||
var skyProj = SkyProjection.WithDepthRange(camera.Projection, Near, Far);
|
||||
|
||||
_params.NightSkyRotationTurns = NightSkyRotationTurns?.Invoke() ?? 0f;
|
||||
|
||||
// View with translation zeroed — keeps the sky at camera origin
|
||||
// regardless of camera position in the world.
|
||||
var skyView = camera.View;
|
||||
|
|
@ -726,9 +735,20 @@ public sealed partial class SkyRenderer : IDisposable
|
|||
public Vector2 UvScroll; // 240
|
||||
public float ApplyFog; // 248
|
||||
public float SurfOpacity; // 252
|
||||
/// <summary>
|
||||
/// Whole-sky rotation in TURNS for the enhanced night sky (IA-26):
|
||||
/// dayFraction + dayOfYear/360, so the procedural starfield wheels
|
||||
/// once per Dereth day about the celestial pole and drifts ~1 degree
|
||||
/// per night through the 360-day year (seasonal constellations).
|
||||
/// Zero when the pack is inactive; the retail path never reads it.
|
||||
/// </summary>
|
||||
public float NightSkyRotationTurns; // 256
|
||||
public float NsPadA; // 260
|
||||
public float NsPadB; // 264
|
||||
public float NsPadC; // 268
|
||||
|
||||
/// <summary>256 — the std140 size of the block, a whole number of vec4s.</summary>
|
||||
public const int SizeInBytes = 256;
|
||||
/// <summary>272 — the std140 size of the block, a whole number of vec4s.</summary>
|
||||
public const int SizeInBytes = 272;
|
||||
}
|
||||
|
||||
private sealed class SubMeshGpu
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue