diag: ACDREAM_PROBE_LIGHT — log dungeon ambient/sun/active-light state (#133 A7)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a40c38e8bd
commit
d6fb788c96
2 changed files with 90 additions and 0 deletions
|
|
@ -7625,6 +7625,24 @@ public sealed class GameWindow : IDisposable
|
|||
|
||||
_sceneLightingUbo?.Upload(ubo);
|
||||
|
||||
// #133 A7 (2026-06-13): objective dungeon-lighting probe. One
|
||||
// rate-limited [light] line — insideCell / ambient / sun /
|
||||
// registered-point-lights / active-slot-count / player cell — so
|
||||
// the dungeon-dim question is self-verifiable from launch.log
|
||||
// without a screenshot. RegisteredCount is point/spot lights only
|
||||
// (the sun lives in LightManager.Sun, never in the _all list);
|
||||
// ubo.CellAmbient.W is the shader active-slot count, which counts
|
||||
// the (zeroed) sun slot indoors. Inert unless ACDREAM_PROBE_LIGHT=1.
|
||||
AcDream.Core.Rendering.RenderingDiagnostics.EmitLight(
|
||||
insideCell: playerInsideCell,
|
||||
ambientR: Lighting.CurrentAmbient.AmbientColor.X,
|
||||
ambientG: Lighting.CurrentAmbient.AmbientColor.Y,
|
||||
ambientB: Lighting.CurrentAmbient.AmbientColor.Z,
|
||||
sunIntensity: Lighting.Sun?.Intensity ?? 0f,
|
||||
registeredLights: Lighting.RegisteredCount,
|
||||
activeLights: (int)ubo.CellAmbient.W,
|
||||
playerCellId: playerRoot?.CellId ?? 0u);
|
||||
|
||||
// Never cull the landblock the player is currently on.
|
||||
uint? playerLb = null;
|
||||
if (_playerMode && _playerController is not null)
|
||||
|
|
|
|||
|
|
@ -243,6 +243,34 @@ public static class RenderingDiagnostics
|
|||
public static bool ProbePhantomEnabled { get; set; } =
|
||||
Environment.GetEnvironmentVariable("ACDREAM_PROBE_PHANTOM") == "1";
|
||||
|
||||
/// <summary>
|
||||
/// #133 A7 (2026-06-13) dungeon-lighting objective probe. When true,
|
||||
/// the per-frame scene-lighting build emits ONE <c>[light]</c> line
|
||||
/// roughly every second (wall-clock rate-limited like WB-DIAG) via
|
||||
/// <see cref="EmitLight"/>:
|
||||
/// <code>
|
||||
/// [light] insideCell=<bool> ambient=(r,g,b) sun=<intensity>
|
||||
/// registeredLights=<N> activeLights=<uCellAmbient.w> playerCell=0x<id>
|
||||
/// </code>
|
||||
/// This is the self-verification signal for the dungeon-dim question:
|
||||
/// <list type="bullet">
|
||||
/// <item><description><c>insideCell=true ambient=(0.20,0.20,0.20) sun=0</c>
|
||||
/// confirms the indoor branch fired (retail flat ambient, sun killed).</description></item>
|
||||
/// <item><description><c>registeredLights</c> is the count of dat-baked
|
||||
/// point/spot lights (<c>Setup.Lights</c>) registered with the
|
||||
/// <c>LightManager</c> — if this is 0 in a dungeon, the cell's static
|
||||
/// objects carry no baked torches (so the only illumination IS the
|
||||
/// 0.2 ambient → dim).</description></item>
|
||||
/// <item><description><c>activeLights</c> is <c>uCellAmbient.w</c> — the
|
||||
/// shader's active-slot count, which INCLUDES the (zeroed) sun slot
|
||||
/// indoors. So <c>activeLights=1 registeredLights=0</c> = "only the dead
|
||||
/// sun slot, no torches in range".</description></item>
|
||||
/// </list>
|
||||
/// Output-only, inert when off. Initial state from <c>ACDREAM_PROBE_LIGHT=1</c>.
|
||||
/// </summary>
|
||||
public static bool ProbeLightEnabled { get; set; } =
|
||||
Environment.GetEnvironmentVariable("ACDREAM_PROBE_LIGHT") == "1";
|
||||
|
||||
// Cell-change gate for EmitVis. The probe fires once per distinct root cell
|
||||
// so launch.log stays readable under motion (the per-frame call is a no-op
|
||||
// when the root is unchanged). Sentinel 0 = "no root yet" — the first real
|
||||
|
|
@ -336,6 +364,50 @@ public static class RenderingDiagnostics
|
|||
/// </summary>
|
||||
internal static void ResetVisibilityProbeForTests() => _lastVisRootCellId = 0;
|
||||
|
||||
// Wall-clock rate-limit gate for EmitLight. Ticks (100 ns) is plenty —
|
||||
// we only need ~1 Hz and avoid a Stopwatch allocation/field. Sentinel 0
|
||||
// = "never emitted" so the first call always fires.
|
||||
private static long _lastLightEmitTicks;
|
||||
private const long LightEmitIntervalTicks = 10_000_000; // 1 s in 100-ns ticks
|
||||
|
||||
/// <summary>
|
||||
/// #133 A7 — emit ONE rate-limited <c>[light]</c> line describing the
|
||||
/// current scene-lighting state. Cheap no-op when
|
||||
/// <see cref="ProbeLightEnabled"/> is false; otherwise fires at most
|
||||
/// once per second. Pull the values from the spot where
|
||||
/// <c>GameWindow.UpdateSunFromSky</c> set <c>Lighting.CurrentAmbient</c>
|
||||
/// / <c>Lighting.Sun</c> and where <c>SceneLightingUbo.Build</c> computed
|
||||
/// the active-slot count.
|
||||
/// </summary>
|
||||
/// <param name="insideCell">The <c>playerInsideCell</c> value driving the indoor branch.</param>
|
||||
/// <param name="ambientR">Cell ambient red (xyz of <c>uCellAmbient</c>).</param>
|
||||
/// <param name="ambientG">Cell ambient green.</param>
|
||||
/// <param name="ambientB">Cell ambient blue.</param>
|
||||
/// <param name="sunIntensity">The sun <c>LightSource.Intensity</c> (0 indoors).</param>
|
||||
/// <param name="registeredLights">Total point/spot lights registered with the LightManager.</param>
|
||||
/// <param name="activeLights"><c>uCellAmbient.w</c> — shader active-slot count (includes the zeroed sun slot indoors).</param>
|
||||
/// <param name="playerCellId">The player's current cell id (0 if unresolved → outside).</param>
|
||||
public static void EmitLight(bool insideCell,
|
||||
float ambientR, float ambientG, float ambientB,
|
||||
float sunIntensity,
|
||||
int registeredLights,
|
||||
int activeLights,
|
||||
uint playerCellId)
|
||||
{
|
||||
if (!ProbeLightEnabled) return;
|
||||
|
||||
long now = DateTime.UtcNow.Ticks;
|
||||
if (_lastLightEmitTicks != 0 && (now - _lastLightEmitTicks) < LightEmitIntervalTicks)
|
||||
return;
|
||||
_lastLightEmitTicks = now;
|
||||
|
||||
var ci = System.Globalization.CultureInfo.InvariantCulture;
|
||||
Console.WriteLine(string.Format(ci,
|
||||
"[light] insideCell={0} ambient=({1:0.###},{2:0.###},{3:0.###}) sun={4:0.###} registeredLights={5} activeLights={6} playerCell=0x{7:X8}",
|
||||
insideCell, ambientR, ambientG, ambientB, sunIntensity,
|
||||
registeredLights, activeLights, playerCellId));
|
||||
}
|
||||
|
||||
private static bool _probeEnvCellEnabled =
|
||||
Environment.GetEnvironmentVariable("ACDREAM_PROBE_ENVCELL") == "1";
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue