Revert "feat(sky): the night sky wheels with the Dereth clock; uniform time fade with a scoped twilight band"
This reverts commit 0dac024cdb.
This commit is contained in:
parent
0dac024cdb
commit
9fcc3f4870
10 changed files with 15 additions and 98 deletions
|
|
@ -333,18 +333,6 @@ internal sealed class FrameRootCompositionPhase
|
||||||
skyForNightSky.EnhancedNightSkyActive = () =>
|
skyForNightSky.EnhancedNightSkyActive = () =>
|
||||||
nightSkyController.ActiveRuntime?.Descriptor.Id
|
nightSkyController.ActiveRuntime?.Descriptor.Id
|
||||||
== AcDream.App.Rendering.Packs.BuiltInAtmosphericRenderPack.Id;
|
== AcDream.App.Rendering.Packs.BuiltInAtmosphericRenderPack.Id;
|
||||||
// The starfield wheels with the Dereth clock: one turn per
|
|
||||||
// day about the celestial pole plus ~1 degree/night of
|
|
||||||
// seasonal drift (dayOfYear/360) — sky.frag's rotation block.
|
|
||||||
var nightSkyTime = d.WorldTime;
|
|
||||||
skyForNightSky.NightSkyRotationTurns = () =>
|
|
||||||
{
|
|
||||||
var cal = nightSkyTime.CurrentCalendar;
|
|
||||||
int dayOfYear = (int)cal.Month
|
|
||||||
* AcDream.Core.World.DerethDateTime.DaysInAMonth
|
|
||||||
+ (cal.Day - 1);
|
|
||||||
return (float)(nightSkyTime.DayFraction + dayOfYear / 360.0);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,6 @@ layout(std140, ACDREAM_UBO_SET binding = 4) uniform SkyParams {
|
||||||
vec2 uUvScroll;
|
vec2 uUvScroll;
|
||||||
float uApplyFog;
|
float uApplyFog;
|
||||||
float uSurfOpacity;
|
float uSurfOpacity;
|
||||||
float uNightSkyRotationTurns; // enhanced night sky (IA-26): sky rotation
|
|
||||||
float uNsPadA;
|
|
||||||
float uNsPadB;
|
|
||||||
float uNsPadC;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Light {
|
struct Light {
|
||||||
|
|
@ -190,50 +186,18 @@ vec3 nightSky(vec3 dir, uint seed)
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
if (uParamA > 0.5) {
|
if (uParamA > 0.5) {
|
||||||
// Day/night fade from the UNIFORM ambient term only — the first
|
// The star layer's own retail lighting product (Emissive 0 ->
|
||||||
// gate's vTint signal carried the per-vertex sun-facing product and
|
// ambient + diffuse) is the day/night signal: ~0.1 at deep night,
|
||||||
// blanked stars across the whole twilight half of the sky
|
// ~1.0 at noon. Stars at full strength only under a dark sky.
|
||||||
// (2026-08-23 screenshots). Ambient is one value for the sky, so
|
float dayL = dot(vTint, vec3(0.299, 0.587, 0.114));
|
||||||
// star visibility is even everywhere; the twilight glow gets its
|
float night = 1.0 - smoothstep(0.18, 0.45, dayL);
|
||||||
// own tightly-scoped suppression below.
|
|
||||||
float dayL = dot(uAmbientColor, vec3(0.299, 0.587, 0.114));
|
|
||||||
float night = 1.0 - smoothstep(0.10, 0.32, dayL);
|
|
||||||
if (night < 0.004) {
|
if (night < 0.004) {
|
||||||
// Daytime: the whole lattice would multiply to zero — skip it
|
// Daytime: the whole lattice would multiply to zero — skip it
|
||||||
// so the enhanced sky costs nothing outside dusk-to-dawn.
|
// so the enhanced sky costs nothing outside dusk-to-dawn.
|
||||||
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
fragColor = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
vec3 sky = nightSky(normalize(vDir), uint(uParamB));
|
||||||
vec3 d = normalize(vDir);
|
|
||||||
|
|
||||||
// Subtle twilight suppression: only the low sky (bottom ~19 deg)
|
|
||||||
// toward the sun's azimuth, and only while the sun term is strong
|
|
||||||
// (dusk/dawn) — stars near the bright horizon wash out, the rest
|
|
||||||
// of the sky keeps its full carpet.
|
|
||||||
vec3 dflat = normalize(vec3(d.xy, 0.0) + vec3(1e-5, 0.0, 0.0));
|
|
||||||
vec3 sflat = normalize(vec3(uSunDir.xy, 0.0) + vec3(1e-5, 0.0, 0.0));
|
|
||||||
float glowSide = max(dot(dflat, sflat), 0.0);
|
|
||||||
float lowSky = 1.0 - clamp(d.z * 3.0, 0.0, 1.0);
|
|
||||||
float twilight = clamp(
|
|
||||||
dot(uSunColor, vec3(0.299, 0.587, 0.114)) * uDiffuseFactor,
|
|
||||||
0.0, 1.0);
|
|
||||||
night *= 1.0 - 0.85 * twilight * glowSide * glowSide * lowSky;
|
|
||||||
|
|
||||||
// The sky wheels: one revolution per Dereth day about a celestial
|
|
||||||
// pole ~41 deg above the northern horizon (+Y north, +Z up), plus
|
|
||||||
// ~1 deg/night of seasonal drift folded into the turns value
|
|
||||||
// (dayFraction + dayOfYear/360). Rodrigues rotation of the sample
|
|
||||||
// direction; stars and mottle turn together.
|
|
||||||
const vec3 NS_POLE = vec3(0.0, 0.6598, 0.7514);
|
|
||||||
float ang = 6.28318530718 * fract(uNightSkyRotationTurns);
|
|
||||||
float ca = cos(ang);
|
|
||||||
float sa = sin(ang);
|
|
||||||
vec3 rdir = d * ca
|
|
||||||
+ cross(NS_POLE, d) * sa
|
|
||||||
+ NS_POLE * dot(NS_POLE, d) * (1.0 - ca);
|
|
||||||
|
|
||||||
vec3 sky = nightSky(rdir, uint(uParamB));
|
|
||||||
// Additive pipeline (forced for this draw): rgb adds over the dome.
|
// Additive pipeline (forced for this draw): rgb adds over the dome.
|
||||||
fragColor = vec4(sky * night, 1.0);
|
fragColor = vec4(sky * night, 1.0);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -67,10 +67,6 @@ layout(std140, ACDREAM_UBO_SET binding = 4) uniform SkyParams {
|
||||||
vec2 uUvScroll;
|
vec2 uUvScroll;
|
||||||
float uApplyFog; // 1 for foggable layers; raw-additive keeps fog off
|
float uApplyFog; // 1 for foggable layers; raw-additive keeps fog off
|
||||||
float uSurfOpacity; // final surface opacity multiplier from the CPU
|
float uSurfOpacity; // final surface opacity multiplier from the CPU
|
||||||
float uNightSkyRotationTurns; // enhanced night sky (IA-26): sky rotation
|
|
||||||
float uNsPadA;
|
|
||||||
float uNsPadB;
|
|
||||||
float uNsPadC;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Shared SceneLighting UBO — we need uFogParams.xy (fog start/end) to
|
// Shared SceneLighting UBO — we need uFogParams.xy (fog start/end) to
|
||||||
|
|
|
||||||
|
|
@ -311,12 +311,12 @@
|
||||||
"stages": [
|
"stages": [
|
||||||
{
|
{
|
||||||
"stage": "vert",
|
"stage": "vert",
|
||||||
"sourceSha256": "80c190d5544433bd6b08810c1e5040cec5090fe91839f436728d5454ed7f3c31",
|
"sourceSha256": "9102b156bd4fd667831353640b2feee2ddde66e88579a4e425566c9b67304b64",
|
||||||
"compiled": true
|
"compiled": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"stage": "frag",
|
"stage": "frag",
|
||||||
"sourceSha256": "76481dcc1a321c65308bf9c081254978ee7f12413166df5d32a1606228bdc768",
|
"sourceSha256": "e7ccdb4d5fece2ceeb48eb43aaa827424df2b68614987eeb3dfb7880dff8ea83",
|
||||||
"compiled": true
|
"compiled": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -106,13 +106,6 @@ public sealed partial class SkyRenderer : IDisposable
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal Func<bool>? EnhancedNightSkyActive { get; set; }
|
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 —
|
/// <summary>Deterministic seed for the procedural sky's hash grids —
|
||||||
/// the approved-look generator's seed (gen_starfield2.py, 2026-08-23).</summary>
|
/// the approved-look generator's seed (gen_starfield2.py, 2026-08-23).</summary>
|
||||||
private const float NightSkySeed = 11f;
|
private const float NightSkySeed = 11f;
|
||||||
|
|
@ -216,8 +209,6 @@ public sealed partial class SkyRenderer : IDisposable
|
||||||
// that FOV here, including the near-180-degree teleport transition.
|
// that FOV here, including the near-180-degree teleport transition.
|
||||||
var skyProj = SkyProjection.WithDepthRange(camera.Projection, Near, Far);
|
var skyProj = SkyProjection.WithDepthRange(camera.Projection, Near, Far);
|
||||||
|
|
||||||
_params.NightSkyRotationTurns = NightSkyRotationTurns?.Invoke() ?? 0f;
|
|
||||||
|
|
||||||
// View with translation zeroed — keeps the sky at camera origin
|
// View with translation zeroed — keeps the sky at camera origin
|
||||||
// regardless of camera position in the world.
|
// regardless of camera position in the world.
|
||||||
var skyView = camera.View;
|
var skyView = camera.View;
|
||||||
|
|
@ -735,20 +726,9 @@ public sealed partial class SkyRenderer : IDisposable
|
||||||
public Vector2 UvScroll; // 240
|
public Vector2 UvScroll; // 240
|
||||||
public float ApplyFog; // 248
|
public float ApplyFog; // 248
|
||||||
public float SurfOpacity; // 252
|
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>272 — the std140 size of the block, a whole number of vec4s.</summary>
|
/// <summary>256 — the std140 size of the block, a whole number of vec4s.</summary>
|
||||||
public const int SizeInBytes = 272;
|
public const int SizeInBytes = 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class SubMeshGpu
|
private sealed class SubMeshGpu
|
||||||
|
|
|
||||||
|
|
@ -52,8 +52,8 @@ public sealed class VulkanShaderManifestTests
|
||||||
// override, retail's GameSky::Draw @0x00506FF0 rule (see
|
// override, retail's GameSky::Draw @0x00506FF0 rule (see
|
||||||
// SkyFogRuleTests). A deliberate default-path change, reviewed
|
// SkyFogRuleTests). A deliberate default-path change, reviewed
|
||||||
// with the world-fog-range fix in the same commit.
|
// with the world-fog-range fix in the same commit.
|
||||||
["sky.frag.spv"] = "83a7b4e265f7df4726d716a812ebaa74ba31ea47036bc31005cd8dc1d8981967",
|
["sky.frag.spv"] = "e307a7f3cf84aada86db7c2859c55841a650b46732f12149986562cef0a90ca8",
|
||||||
["sky.vert.spv"] = "988eff4e106422ca483d665ba25818e8394737a247e9bae346db3220ac31fd28",
|
["sky.vert.spv"] = "3b51945fa4ff1be1604144df92866bdd47aade22f9dd90267591ef36adb28cde",
|
||||||
["terrain_modern.frag.spv"] = "7b3cdb01b837ed77ee20559a81c1ce5c9d5395300efcc072560ab0be3c5a1af9",
|
["terrain_modern.frag.spv"] = "7b3cdb01b837ed77ee20559a81c1ce5c9d5395300efcc072560ab0be3c5a1af9",
|
||||||
["terrain_modern.vert.spv"] = "9f4cb221ea6aed94a8d23af6cb8e3f3ed96c3cce6e50d135a72d3b55667b1557",
|
["terrain_modern.vert.spv"] = "9f4cb221ea6aed94a8d23af6cb8e3f3ed96c3cce6e50d135a72d3b55667b1557",
|
||||||
["ui_text.frag.spv"] = "37a281bf80441cb425eaa3ad8e0b3a43cfa21b74b60973ed4201718b9dc102df",
|
["ui_text.frag.spv"] = "37a281bf80441cb425eaa3ad8e0b3a43cfa21b74b60973ed4201718b9dc102df",
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,7 @@ public sealed class EnhancedNightSkyRuleTests
|
||||||
string code = StripLineComments(frag);
|
string code = StripLineComments(frag);
|
||||||
|
|
||||||
Assert.Contains("if (uParamA > 0.5)", code, StringComparison.Ordinal);
|
Assert.Contains("if (uParamA > 0.5)", code, StringComparison.Ordinal);
|
||||||
Assert.Contains("nightSky(rdir, uint(uParamB))", code, StringComparison.Ordinal);
|
Assert.Contains("nightSky(normalize(vDir), uint(uParamB))", code, StringComparison.Ordinal);
|
||||||
// The fade must stay UNIFORM across the sky (the first gate's
|
|
||||||
// per-vertex vTint signal blanked the whole twilight half) and the
|
|
||||||
// starfield must wheel with the Dereth clock.
|
|
||||||
Assert.Contains("dot(uAmbientColor, vec3(0.299, 0.587, 0.114))", code, StringComparison.Ordinal);
|
|
||||||
Assert.Contains("fract(uNightSkyRotationTurns)", code, StringComparison.Ordinal);
|
|
||||||
// Screen-pixel star sizing is the reason this exists — the stretched
|
// Screen-pixel star sizing is the reason this exists — the stretched
|
||||||
// texture flaw must not creep back in via a fixed-size grid, and the
|
// texture flaw must not creep back in via a fixed-size grid, and the
|
||||||
// cube-face fwidth seams must not return (the 2026-08-23 gate's
|
// cube-face fwidth seams must not return (the 2026-08-23 gate's
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ namespace AcDream.App.Tests.Rendering;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Campaign V slice V6e: the sky's dozen loose uniforms became one std140
|
/// Campaign V slice V6e: the sky's dozen loose uniforms became one std140
|
||||||
/// uniform block, and this is the test that keeps the CPU struct and the GLSL
|
/// uniform block, and this is the test that keeps the CPU struct and the GLSL
|
||||||
/// block describing the same 272 bytes.
|
/// block describing the same 256 bytes.
|
||||||
///
|
///
|
||||||
/// <para>It exists because the failure mode is silent. std140 gives a
|
/// <para>It exists because the failure mode is silent. std140 gives a
|
||||||
/// <c>vec3</c> 16-byte alignment while only using 12, so the block deliberately
|
/// <c>vec3</c> 16-byte alignment while only using 12, so the block deliberately
|
||||||
|
|
@ -45,12 +45,6 @@ public sealed class SkyParamsLayoutTests
|
||||||
[InlineData("UvScroll", 240)]
|
[InlineData("UvScroll", 240)]
|
||||||
[InlineData("ApplyFog", 248)]
|
[InlineData("ApplyFog", 248)]
|
||||||
[InlineData("SurfOpacity", 252)]
|
[InlineData("SurfOpacity", 252)]
|
||||||
// IA-26: the enhanced night sky's rotation turns plus its three pad
|
|
||||||
// words, filling the seventeenth vec4 exactly.
|
|
||||||
[InlineData("NightSkyRotationTurns", 256)]
|
|
||||||
[InlineData("NsPadA", 260)]
|
|
||||||
[InlineData("NsPadB", 264)]
|
|
||||||
[InlineData("NsPadC", 268)]
|
|
||||||
public void EveryMemberSitsWhereStd140PutsIt(string member, int expectedOffset)
|
public void EveryMemberSitsWhereStd140PutsIt(string member, int expectedOffset)
|
||||||
{
|
{
|
||||||
Assert.Equal(
|
Assert.Equal(
|
||||||
|
|
@ -66,7 +60,7 @@ public sealed class SkyParamsLayoutTests
|
||||||
?.GetRawConstantValue()
|
?.GetRawConstantValue()
|
||||||
?? throw new InvalidOperationException("SkyParams.SizeInBytes is missing."));
|
?? throw new InvalidOperationException("SkyParams.SizeInBytes is missing."));
|
||||||
|
|
||||||
Assert.Equal(272, declared);
|
Assert.Equal(256, declared);
|
||||||
Assert.Equal(declared, Marshal.SizeOf(SkyParamsType));
|
Assert.Equal(declared, Marshal.SizeOf(SkyParamsType));
|
||||||
// std140 rounds a block up to its largest member's alignment (16).
|
// std140 rounds a block up to its largest member's alignment (16).
|
||||||
Assert.Equal(0, declared % 16);
|
Assert.Equal(0, declared % 16);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue