MONKEY (fix-sky): day-long f64 sky clock; twinkle rates whole cycles per wrap
Review B2: the f32 clock wrapped hourly and every star's twinkle jumped at the wrap. It now accumulates in f64 and wraps at 86400 s; the shader rounds each twinkle rate to whole cycles per wrap, so the stars are seamless. The High cloud detail drift still re-patterns once per 24 h (noted). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
499fdd935f
commit
474b641499
@@ -7,6 +7,15 @@
|
||||
#define_import_path benilla_world::sky_fx
|
||||
|
||||
const TAU: f32 = 6.2831853;
|
||||
// MONKEY (fix-sky): the sky clock's wrap (`sky_fx::SKY_CLOCK_WRAP_S`, a day). Twinkle rates are
|
||||
// whole cycles per wrap, so the stars never jump at the wrap.
|
||||
const SKY_WRAP: f32 = 86400.0;
|
||||
|
||||
// The phase of a `rate` rad/s oscillator, rounded to whole cycles per wrap.
|
||||
fn wrap_phase(t: f32, rate: f32) -> f32 {
|
||||
let cycles = round(rate * SKY_WRAP / TAU);
|
||||
return fract(cycles * (t / SKY_WRAP)) * TAU;
|
||||
}
|
||||
|
||||
fn srgb_to_linear(c: vec3<f32>) -> vec3<f32> {
|
||||
let lo = c / 12.92;
|
||||
@@ -201,7 +210,8 @@ fn star_field(dir: vec3<f32>, t: f32, px: f32, band: f32) -> vec3<f32> {
|
||||
let sigma = px * (0.55 + 0.7 * mag);
|
||||
let spot = exp(-d * d / (2.0 * sigma * sigma));
|
||||
let tw_amp = 0.18 + 0.3 * (1.0 - clamp(dir.y, 0.0, 1.0));
|
||||
let tw = 1.0 + tw_amp * sin(t * (1.3 + 3.1 * j.x) + TAU * j.y) * sin(t * (0.6 + 1.7 * j.z) + TAU * h.z);
|
||||
let tw = 1.0 + tw_amp * sin(wrap_phase(t, 1.3 + 3.1 * j.x) + TAU * j.y)
|
||||
* sin(wrap_phase(t, 0.6 + 1.7 * j.z) + TAU * h.z);
|
||||
// Star colour: mostly white, a few warm and a few blue-white.
|
||||
let tint = mix(vec3<f32>(0.78, 0.86, 1.0), vec3<f32>(1.0, 0.88, 0.72), h.z);
|
||||
acc += tint * (b * spot * tw);
|
||||
|
||||
@@ -36,14 +36,23 @@ impl SkyQuality {
|
||||
}
|
||||
}
|
||||
|
||||
/// The sky's own animation clock (star twinkle, cloud detail drift), seconds wrapped to an hour so
|
||||
/// the shader's `sin` keeps its precision. Frozen in capture mode, at `$WOW_CAPTURE_SKY_T` or 0.
|
||||
/// The sky's own animation clock (star twinkle, cloud detail drift), seconds wrapped to a day.
|
||||
/// Frozen in capture mode, at `$WOW_CAPTURE_SKY_T` or 0.
|
||||
///
|
||||
/// MONKEY (fix-sky): it wrapped hourly in f32, and every star's twinkle jumped at the wrap. Now it
|
||||
/// accumulates in f64 and wraps at [`SKY_CLOCK_WRAP_S`]; the shader's twinkle rates are whole
|
||||
/// cycles per wrap (seamless). The High cloud-detail drift still re-patterns at the wrap, once
|
||||
/// per 24 h of continuous play.
|
||||
#[derive(Resource, Default)]
|
||||
pub struct SkyClock {
|
||||
pub secs: f32,
|
||||
acc: f64,
|
||||
frozen: Option<f32>,
|
||||
}
|
||||
|
||||
/// The sky clock's wrap in seconds; `sky_fx.wgsl`'s `SKY_WRAP` must match.
|
||||
pub const SKY_CLOCK_WRAP_S: f64 = 86_400.0;
|
||||
|
||||
/// How strongly the glow shows: a broad halo at `GLOW_GAIN` × the sun colour at the sun itself.
|
||||
pub(crate) const GLOW_GAIN: f32 = 0.22;
|
||||
|
||||
@@ -77,6 +86,7 @@ impl Plugin for SkyFxPlugin {
|
||||
});
|
||||
app.insert_resource(SkyClock {
|
||||
secs: frozen.unwrap_or(0.0),
|
||||
acc: 0.0,
|
||||
frozen,
|
||||
});
|
||||
let quality = SkyQuality(SkyQuality::env_override().unwrap_or(0));
|
||||
@@ -92,7 +102,8 @@ fn tick_sky_clock(time: Res<Time>, mut clock: ResMut<SkyClock>) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
clock.secs = (clock.secs + time.delta_secs()) % 3600.0;
|
||||
clock.acc = (clock.acc + time.delta_secs_f64()) % SKY_CLOCK_WRAP_S;
|
||||
clock.secs = clock.acc as f32;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user