acdream/docs/plans/2026-08-21-atmospheric-rendering.md

938 lines
55 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Campaign AR — Atmospheric Rendering / Shader Packs
**Date:** 2026-08-21
**Status:** MACHINE-LOCAL STAGE 2 COMPLETE — the authored sun-and-moon
shadow-source extension, Stage 1 owner gate, connected ACE matrix, dense A/B,
long lifetime, graphical package lifecycle, shader, locked-restore, Release,
and complete-test gates pass. A second-client remote-player row, unavailable
physical GPU classes, and final project-owner pack-off/pack-on acceptance remain
external closeout gates; the campaign is not yet declared shipped.
**Phase id:** **Campaign AR** — assigned by the project owner on 2026-08-22
**Scheduling:** originally held for the post-M7 rendering-polish pass; the
project owner explicitly authorized implementation on 2026-08-21. This
owner-directed campaign is now Campaign AR and does not displace the active M4
gameplay work. The previously referenced #268 + TS-8 stat-chain package is
already complete and retired, so it is no longer a scheduling dependency.
## Goal
Add an opt-in enhanced-graphics system whose headline feature is **real-time
directional shadows cast by trees, monsters, players, and buildings as
Dereth's authored sun and moons move across the sky**. The same system can add
bloom, filmic tonemapping, colour grading, vignette, sun rays, and later
volumetric shafts, with useful quality levels on weak through high-end
hardware. Sun rays and volumetric shafts remain sun-only effects; the approved
moon scope applies to Tier 2 directional shadows.
Campaign AR executes in two stages. Stage 1 fixed the dense-scene transform
ceiling and shadow quality, completed authored sun/dominant-moon/secondary-moon
source selection, and finished every automated gate that did not require the
project owner's physical-display judgment. The owner accepted the subsequent
live visual/performance round on 2026-08-22 after the default Atmospheric
exposure was corrected from 1.0 to 0.80. The machine-local Stage 2 rows are now
complete. Remaining closeout is limited to a second connected remote player,
unavailable physical-hardware rows, and final owner acceptance; it does not add
another renderer feature tier.
Stage 1's dense-scene regression is pinned by the connected failures already
captured on 2026-08-22: Atmospheric fell back at 68,395, 67,581, and even
65,538 combined world matrices against the old 65,536-matrix binding ceiling.
The corrected connected launch must exceed that historical workload without
persisting acdream-default fallback or splitting the authoritative pose data.
The enhancement is a shader pack, not a rewrite of acdream's renderer or AC's
art. **acdream's current retail-faithful renderer** remains the default,
authoritative path. References below to the “default” or “retail-faithful” path
always mean acdream—not the original retail executable.
The evidence and constraints for this design are recorded in the
[terrain and atmospheric rendering findings](../research/2026-08-21-terrain-and-atmospheric-rendering-findings.md),
especially [the measured renderer baseline](../research/2026-08-21-terrain-and-atmospheric-rendering-findings.md#5-renderer-state-relevant-to-atmospheric-work)
and [the requested tier model](../research/2026-08-21-terrain-and-atmospheric-rendering-findings.md#6-wanted-work--atmospheric-rendering-user-stated).
The approved celestial identity, priority, transform, and direction-versus-
energy contract are pinned by the
[Dereth celestial shadow-source research](../research/2026-08-22-dereth-celestial-shadow-sources.md).
## Opt-in contract
1. **acdream's current renderer is the default.** With no pack selected, the current render graph,
shaders, render targets, submissions, lighting, colours, and screenshots
remain authoritative. No enhancement resource or pass is created.
2. **Selection is explicit.** Installing a pack does not enable it. The user
selects one pack and one quality preset in Display settings. `acdream
default (retail-faithful)` is always present and cannot be removed.
3. **One pack owns the enhancement graph.** Packs do not stack. This prevents
ambiguous pass ordering, incompatible HDR conventions, and unbounded GPU
cost.
4. **The renderer owns the RHI.** A pack declares assets, semantic pass hooks,
capabilities, resources, and quality variants. It never receives Vulkan
handles or mutates the authoritative scene, streaming, gameplay, or
physics owners.
5. **Failure returns to acdream's default renderer.** Unsupported capabilities,
malformed assets, shader/pipeline candidate-creation failure, or an invalid
pass graph disables the complete pack and restores acdream's default path
with a visible reason. A half-enabled pack is never rendered. A terminal
`VK_ERROR_DEVICE_LOST` cannot render either path on the lost device; it tears
down that renderer/device lifetime, and retail remains authoritative while a
fresh renderer/device is constructed and the pack is validated again.
6. **Divergence is honest.** Enhanced screenshots are intentionally not retail
parity evidence. The default path remains the comparison oracle and the
enhancement choice is recorded in diagnostics and screenshot metadata.
7. **No scheduling claim.** Rendering phases stay frozen until the M7 polish
pass unless the project owner explicitly reprioritizes this work.
## Capability tiers
The costs below are **planning estimates**, not measurements. They are
incremental GPU p50 targets for a representative discrete GPU at 1920x1080;
every slice must replace them with physical-hardware measurements. Tier-1
pixel effects scale with output resolution, so 4K has roughly four times the
1080p fragment workload. Shadow-map cost depends more on caster count, map
resolution, and cascade count than on output resolution.
| Tier | Contents | Prerequisite | Rough incremental GPU cost at 1080p |
|---|---|---|---:|
| acdream default | Current authoritative retail-faithful rendering | Current mandatory Vulkan/RHI capabilities | 0 ms |
| 1 | Bloom, ACES filmic tonemap, colour grade, vignette | Main-world colour intermediate and fullscreen passes | 0.350.80 ms |
| 1 | Screen-space sun rays (crepuscular) | Authored sun screen position plus an occlusion mask; **no shadow maps** | 0.200.50 ms |
| 2 | **Moving authored sun-and-moon cascaded directional shadows from trees, monsters, players, and houses/buildings** | A second scene pass, selected-celestial view/projection matrices, sampled depth maps, caster pipeline variants | 1.503.00 ms |
| 2+ | Sun-only volumetric light shafts | Reuse Tier-2 shadow infrastructure only while the selected source is the authored sun, plus authored weather | 0.150.40 ms |
| Later | SSAO and water reflections | Scene depth plus normal inputs and separate designs | Not budgeted here |
| Out | True PBR | AC lacks authored per-texture normal/roughness/metalness maps | Not planned |
Tier numbers express prerequisites, not a forced bundle. A pack may offer
Tier 1 without shadows. Tier 2 always includes the complete shadow-caster
classes; weak-hardware presets reduce range, cascade count, and resolution
rather than silently dropping monsters, trees, or buildings.
## Tier 2 headline: Dereth's moving authored sun-and-moon shadows
The [measured renderer state](../research/2026-08-21-terrain-and-atmospheric-rendering-findings.md#5-renderer-state-relevant-to-atmospheric-work)
already supplies retail's single directional colour/energy channel from
`SkyStateProvider`. Tier 2 augments it with the visible authored celestial
positions documented in the
[Dereth celestial shadow-source research](../research/2026-08-22-dereth-celestial-shadow-sources.md).
The camera-relative cascaded map selects, in order, the visible above-horizon
sun (`0x01001348`), dominant haloed moon (`0x01001F6A`), or secondary moon
(`0x01001F67`). The selected mesh's exact rendered transform supplies shadow
direction; retail's one interpolated `DirColor * DirBright` channel supplies
colour/energy. Moon texture brightness and mesh luminosity never manufacture a
second world light. As those authored bodies move, tree branches, monsters,
players, houses, and other eligible world geometry cast correspondingly moving
shadows.
This source selection is an explicit opt-in pack enhancement. It is not a
claim that the retail executable rendered real-time moon shadows, and it does
not alter acdream's default retail-faithful scene lighting. Screen-space sun
rays and volumetric shafts continue to use only the authored sun; they do not
switch to either moon.
The required behavior is:
- Terrain and opaque world geometry receive shadows. Terrain, buildings,
statics, procedural scenery, the local player, remote players, and creatures
cast them when resident and visible to the main outdoor world.
- Foliage and other cutout materials use an alpha-sampling shadow fragment
shader. An empty depth fragment shader would turn each tree plane into a
solid rectangular shadow.
- Animated casters reuse the exact per-part transforms already published in
the N.5 SSBO. The shadow pass must not create a second animation pose or
gameplay entity projection.
- Cascades follow the camera and are texel-stabilized. Their reach is clamped
to the resident two-tier streaming window; the pack does not extend world
streaming or issue speculative loads.
- The celestial directional-shadow pass is outdoor-only. Dungeon and EnvCell lighting remains
authored per-cell lighting. Entering an interior retires or idles outdoor
shadow work without leaving stale maps on screen.
- Shadow direction follows the selected visible above-horizon sun, dominant
moon, or secondary moon. The authored directional colour/energy remains
`DirColor * DirBright`; active day/weather pack policy may soften or reduce
it without inventing a second celestial clock, light-energy channel, or
weather system. A time with no eligible above-horizon body has no
directional shadow; night is not itself a disable condition.
- Transparent blend materials do not cast an opaque silhouette by default.
Only existing opaque and cutout classifications participate until a
material-specific transparent-shadow contract is designed.
The pass reuses the retained resident scene. It must not run PView, portal
traversal, or per-object CPU visibility classification once per cascade.
Initially, each cascade draws the bounded resident caster set through the
existing batched/MDI ownership. If that is too expensive, the next permitted
step is GPU culling—not repeated CPU culling or per-object submissions.
## Pack API surface sketch
The public declarations belong in the BCL-only
`AcDream.Plugin.Abstractions` assembly. The graphical App supplies the
implementation and translates the declarations to the Vulkan RHI. Headless
hosts expose no render-pack registry and never load pack assets.
This is an API shape, not code committed by this design:
```csharp
public interface IRenderPackPlugin
{
void Register(IRenderPackRegistry registry);
}
public interface IRenderPackRegistry
{
IDisposable Register(RenderPackDescriptor descriptor, IRenderPackAssets assets);
}
public interface IRenderPackAssets
{
Stream OpenRead(string assetKey);
}
public sealed record RenderPackDescriptor(
string Id,
string DisplayName,
Version PackVersion,
int PackApiVersion,
RenderPackTier HighestTier,
IReadOnlyList<RenderCapability> RequiredCapabilities,
IReadOnlyList<RenderCapability> OptionalCapabilities,
IReadOnlyList<RenderResourceDeclaration> Resources,
IReadOnlyList<RenderPassDeclaration> Passes,
IReadOnlyList<SceneReplayDeclaration> SceneReplays,
IReadOnlyList<PipelineVariantDeclaration> PipelineVariants,
IReadOnlyList<RenderQualityPreset> QualityPresets,
IReadOnlyList<RenderSettingDeclaration> Settings,
AtmospherePolicyDeclaration? AtmospherePolicy);
```
A pack declares:
- a stable ID, display name, pack version, and pack-API version;
- its highest tier and a human-readable feature summary;
- mandatory and optional GPU capabilities and per-preset limits;
- shader assets and fixed renderer semantic inputs, including world colour,
scene depth, optional normals, selected celestial shadow direction/energy,
sun direction/screen position for sun-only effects, active weather, camera
matrices, shadow-caster transforms, and frame time;
- intermediate images/buffers by relative or absolute extent, format class,
usage, lifetime, and estimated bytes;
- passes at renderer-owned hooks such as `ShadowDepthBeforeWorld`,
`AtmosphereBeforeToneMap`, `ToneMap`, and
`AfterToneMapBeforePrivateViewports`;
- renderer-owned scene replays such as `OutdoorDirectionalShadowCasters`, with
requested cascade views and existing caster/material classes
(`Terrain`, `OpaqueWorld`, `AlphaCutoutWorld`, `AnimatedOpaque`, and
`AnimatedAlphaCutout`); the renderer resolves those classes from its
retained scene and records their existing batched draws;
- fixed pipeline variants for shadow-caster depth and main-world shadow
receivers. A variant names its base semantic (`Terrain`, `WorldMesh`, or
`EnvCell`), shader asset, compatible material classes, and declared inputs
such as cascade matrices, directional depth maps, and sampler state; it does
not replace visibility, batching, mesh ownership, or draw submission code;
- quality presets, user-visible settings with bounded ranges, and declared
incremental GPU/VRAM budgets; and
- an atmosphere policy: explicit directional-source/sun-elevation response
curves and a mapping from AC's categorical `activeDayGroup` values to effect
multipliers. These values live in the visible pack declaration, not as hidden
renderer constants; AC remains the owner of celestial position, directional
energy, and weather state.
The renderer—not the pack—defines descriptor layouts, validates SPIR-V and
resource declarations, resolves semantic scene-replay and pipeline-variant
requests, builds pipelines, schedules barriers, owns frame-flight and teardown,
and supplies immutable frame inputs. Packs cannot add arbitrary draw callbacks,
read gameplay owners, submit command buffers, retain borrowed frame views, or
address resources outside their registration. The built-in pack's Tier-2
caster pass and receiver shaders must be expressible entirely through these
same public declarations.
### Selection and fail-safe lifecycle
1. Discover manifests and descriptors without creating GPU objects.
2. Show compatibility and estimated cost in Display settings. Unsupported
packs remain visible with the exact missing capability; they cannot be
selected.
3. On explicit selection, validate the whole descriptor, all assets, resource
ceilings, hooks, and shader interfaces; then build a complete candidate
pipeline set off to the side.
4. Atomically activate the candidate only after every required object exists.
Until then acdream's default path continues rendering.
5. Persist `pack id + pack version + preset`, never a positional index. If the
pack disappears or becomes incompatible, select `acdream default` and
retain the failure notice.
6. On runtime validation or post-recreation candidate failure, withdraw all
pack passes/resources at a frame boundary and resume acdream's default
renderer. Do not repeatedly retry a failing pack during the session.
7. Unload and reconnect use the normal render-generation and GPU-flight
retirement rules. No pack object may retain a world generation, scene
entity, or collectible plugin load context.
In this campaign, **device recreation** means disposing the complete old
renderer, Vulkan context, and device, then constructing a fresh context/device,
re-probing capabilities, and validating selection again with retail active
until the candidate is complete. It does **not** mean live, in-process recovery
from `VK_ERROR_DEVICE_LOST`; device loss remains terminal to that renderer and
device lifetime.
The built-in Atmospheric Rendering pack should be the first consumer of this
same API. It must not receive private renderer shortcuts that third-party packs
cannot express.
The public v1 authoring surface, manifest schema, shader semantic bindings,
failure guidance, validator command, and external no-op sample are indexed by
the [render-pack SDK](../render-packs/README.md).
## Frame-graph placement
With the pack off, the frozen retail graph is unchanged. With a pack selected,
the renderer builds a separate enhancement graph:
1. Update the existing immutable world frame, including authored sky objects,
the retail directional colour/energy channel, and weather.
2. Outdoors, select the visible above-horizon sun/dominant moon/secondary moon
direction and render Tier-2 cascaded shadow depth from the resident caster
set.
3. Render the main world to the pack's world-colour intermediate, using
pack-selected pipeline variants to sample the shadow map where requested.
4. Preserve the established PView, punch/seal depth discipline, shared-alpha
ordering, particle ordering, and world transparency boundaries.
5. Generate screen-space sun occlusion/rays or, only while the shadow source is
the sun, shadow-map volumetrics.
6. Composite rays/shafts **before tonemapping**, so bloom sees them and the
filmic curve rolls them off instead of clipping them.
7. Apply tonemap, colour grade, and vignette to the main world image.
8. Continue with private portal/paperdoll/appraisal viewports and retained UI
on their existing path. They are not accidentally post-processed with the
main world.
## Delivery slices and acceptance
The slice labels below are local to this document. They are not phase IDs.
### Pre-moon checkpoint, Stage 1 acceptance, and Stage 2 start — 2026-08-22
Before the approved moon extension, all seven local slices (06) had production
implementations in the current worktree. A source-identical isolated clean
snapshot closed that sun-only reference-GPU physical matrix, and one physical
integrated-AMD Auto safe-fallback row was also present. Those artifacts remain
valid evidence for the exact binaries and sun-only scope they measured; they
are not moon-alignment, source-transition, current-worktree, or final user-
acceptance evidence.
Stage 1's automated implementation and validation are complete. The authored
sun/dominant-moon/secondary-moon resolver and its direction-versus-energy
handoff are present and covered without inferring physical quality from unit
tests, screenshots, or historical sun-only rows. The subsequent live ACE round
covered the owner-reported shadow visibility/configuration, temporal
pixelation/shimmer, frame-pacing/desktop responsiveness, selection/fullscreen
regressions, and matched indoor/outdoor exposure. After the exposure correction
the owner accepted the live result. The exact evidence and limits are recorded
in the [Stage 1 live-gate report](../research/2026-08-22-atmospheric-stage1-live-gate.md).
Current authored-celestial Stage 1 automated gate (2026-08-22):
- The shader compiler reports **24/24** Vulkan shader pairs ready. Incremental
regeneration expands only pack includes and preserves all 18 pre-campaign
retail SPIR-V artifacts byte-for-byte; the exact SHA-256 oracle and complete
source-manifest checks pass. All selected-celestial binding-6 modules expose
the 336-byte ABI v1 layout, including source kind at offset 320.
- Focused Release validation passes **344/344** App renderer tests, **30/30**
standalone SDK/pack-validator tests, **14/14** Core sky-loader tests, and
**48/48** MossTank tests. Both external Tier-2 samples embed and validate the
current selected-celestial shader ABI without App or Vulkan dependencies.
- The repository's forced locked restore passes. The complete Release solution,
including all source, tests, tools, and SDK samples, builds with **0 warnings
and 0 errors** after that restore.
- The repository-owned fresh-process hermetic gate passes
**14,928/14,928** tests with zero skips or failures across 14 assemblies;
`AcDream.App.Tests` contributes **5,823/5,823**. Evidence is under
`artifacts/atmospheric-rendering/stage1-moon-release-gate/`.
- The App total includes the 9,500-caster 256-frame zero-managed-allocation
steady-state fixture, warmed CPU/GPU sampling allocation gates, the complete
12-cycle Low/Medium/High/retail/resize/failure/recovery/frame-flight/
generation convergence fixture, and independent renderer/context/device
recreation. These prove the non-physical performance and lifetime contracts;
they do not claim physical frame pacing or image quality.
- A final path audit finds no source changes under `src/AcDream.Runtime`, no
physics or collision changes, and no changes to the retail GLSL sources or
tracked retail SPIR-V binaries. Pack-off production integration remains the
strict authoritative-path oracle.
The command-level record and evidence boundary are in the
[Stage 1 automated gate report](../research/2026-08-22-atmospheric-stage1-automated-gate.md).
Recorded pre-moon automated checkpoint (not a current moon-scope completion
claim):
- The repository-owned fresh-process Release test stage passes
**14,880/14,880** tests with zero skips or failures across 14 assemblies.
`AcDream.App.Tests` contributes **5,783/5,783**; campaign-focused App cases
cover descriptor/asset/SPIR-V
validation, pack-off/no-op invariants, atomic asynchronous candidate swaps,
runtime fallback, declared settings, Tier-1/Tier-2/Tier-2+ graph execution,
all headline caster classes, topology caching, exact animated transforms,
Low/Medium/High/Auto policy, diagnostics, and the pack UI.
- Headless plugin-session tests pass **6/6**, including rejection of a
render-pack-only request before its DLL is loaded.
- The SDK validator suite passes **26/26** and builds/validates the external
`AcDream.RenderPacks.NoOp`, `AcDream.RenderPacks.AtmosphericTier2`, and
`AcDream.RenderPacks.ShadowsOnlyTier2` samples without App or Vulkan
references.
- The production catalog is revisioned rather than frozen at startup. The same
composed controller/UI observes external registration, withdrawal, and
corrected re-registration; an active withdrawn pack retires at the next
frame boundary, persists retail fallback, releases its asset/context owners,
and does not retry the removed registration. Runtime package admission now
matches the SDK: exactly one public constructible render-pack entry point and
at least one live registration, with transactional rollback for malformed,
multiple, internal, zero-registration, and partially failing packages.
- The retained 9,500-caster warmed-frame fixture performs no second-frame
scene-index copy, topology rebuild, sort, or classification and allocates
zero managed bytes. Animated-static, live-dynamic, and equipped-child root
and part transforms refresh through cached IDs/slots with exact float bits.
- Render and screenshot diagnostics now publish exact accepted counts for
terrain commands, outdoor statics, buildings, animated statics, local
players, remote players, non-player creatures, other live dynamics, and
equipped children. These labels stop at the authoritative evidence boundary:
static DAT publication does not distinguish a tree from other outdoor
scenery, and create-object render metadata does not distinguish a hostile
monster from a non-hostile NPC creature. Diagnostics therefore report
`OutdoorStatics` and `NonPlayerCreatures`; they never infer tree or monster
identity from a mesh or ID.
- The recording-RHI long-cycle gate repeatedly crosses Low, Medium, High, and
retail selection; resize; injected candidate failure and explicit recovery;
both frame-flight slots; render-generation replacement; and final renderer
disposal. Pack resources, pipeline-format leases, texture slots, retained
transforms, receiver candidates, and registrations converge exactly. A
second fixture proves that device recreation is old-renderer/context/device
teardown followed by an independent fresh device and activation generation.
- Therefore the deterministic lifecycle implementation, recording-RHI
convergence, and fresh-device recreation definition are locally closed. The
executable connected route and its contract assertions are implemented for
select/disable/re-enable, exact resize, authored time/weather changes, and
fresh-process recreation, but a contract-tested route is not connected-world
evidence; its ACE-backed execution and artifacts remain open below.
- The complete Release solution, including all three SDK samples, the
validator, shader compiler/generated manifest, and repository tools, builds
with **0 warnings and 0 errors**. The current managed workspace could not
repeat the gate's locked-restore stage because it denies NuGet access to the
user-profile `NuGet.Config`; the explicit no-restore build and complete test
stage above are current, while locked-restore verification remains a
closeout-environment requirement rather than being reported as green here.
The corresponding durable source/test entry points are:
- public contracts and SDK:
`src/AcDream.Plugin.Abstractions/Rendering/`, `docs/render-packs/`,
`tools/RenderPackValidator/`, `samples/AcDream.RenderPacks.*`, and
`tests/AcDream.RenderPackValidator.Tests/`;
- activation, compatibility, Auto, diagnostics, and built-in graph:
`src/AcDream.App/Rendering/Packs/` and
`tests/AcDream.App.Tests/Rendering/Packs/`;
- moving authored-celestial cascades, casters, receivers, and retained topology:
`src/AcDream.App/Rendering/DirectionalShadow*.cs`,
`src/AcDream.App/Rendering/Packs/AuthoredCelestialShadowSource.cs`,
`src/AcDream.App/Rendering/Scene/DirectionalShadowCasterFrame.cs`,
`src/AcDream.App/Rendering/Wb/WbDrawDispatcher.DirectionalShadows.cs`, and
`tests/AcDream.App.Tests/Rendering/DirectionalShadow*` plus
`tests/AcDream.App.Tests/Rendering/Packs/AuthoredCelestialShadowSourceResolverTests.cs`;
- retained Display UI and headless boundary:
`src/AcDream.App/UI/Layout/ConfigOptionsPageController.cs`,
`tests/AcDream.App.Tests/UI/Layout/ConfigOptionsPageControllerTests.cs`, and
`tests/AcDream.Headless.Tests/HeadlessPluginSessionTests.cs`.
Machine-local offline/physical evidence currently present under
`artifacts/atmospheric-rendering/` is gate evidence, but it is not a substitute
for connected-world or project-owner acceptance:
- `smoke-retail-720p/` records the pack-off `retail/off` path with zero pack
resources, casters, cascades, or classification calls;
- `accept-shadow-morning-200m/`, `accept-shadow-afternoon-200m/`, and
`accept-shadow-morning-close/` contain fixed-camera moving-sun shadow
screenshots plus metadata for 9,498 resident casters and three cascades;
these pre-moon captures do not prove moon alignment or source transitions;
- `volumetric-valid-camera-500m/` contains a High-preset volumetric diagnostic
capture; it is not a performance acceptance row;
- `matrix-clean-snapshot-dense-linear-v20/` is the current complete AMD Radeon
RX 9070 XT physical matrix: **30/30 rows pass** across
retail/Low/Medium/High/Auto, 1080p/1440p/4K, and capped/uncapped pacing. The
actual worktree's 4,397 source files were copied and hash-verified into an
isolated clean snapshot at commit `4876c970`; the Release App product version
names that exact commit, source and binary identities match, and tracked
status is empty. Its 18 active enhanced rows each own exact 2,048-sample
CPU/receiver/GPU windows, 9,498 casters, and zero warmed classification calls.
Six rows are retail and six 4K Low/Medium/Auto rows are accepted
resource-unavailable fail-safe outcomes;
- `matrix-final-v16-exact-auto/` and the two `current-low-1080p-*-v20/`
captures retain the optimization's predecessor/reference trail; the clean
snapshot matrix above supersedes them as current reference-adapter evidence;
- all six retail rows record zero pack resources, passes, casters, cascades,
draws, or dispatches. The six unavailable 4K Low/Medium/Auto rows likewise
record zero pack work and pass their strict paired-default framebuffer
comparisons instead of rendering a half-enabled graph;
- `igpu-auto-safe-fallback-v7-paired/` records physical Auto behavior on the
integrated **AMD Radeon(TM) Graphics** adapter (Vulkan 1.4.315, driver
2.0.353). After 180 stable Low samples, Auto failed safe with the exact reason
`GPU p99 19.308 ms (budget 3.000 ms), CPU p99 0.534 ms (budget 0.500 ms),
resident GPU bytes 41648404 (budget 67108864)`. The published state is
`retail/off`, has zero pack resources or work, and retains that visible
reason. Its comparison against the paired time-matched retail artifact
`igpu-retail-current-v6-time-matched/`, using `sky-mask.png`, differs in only
**56 / 1,536,000 compared pixels**, a **0.003645833% (0.00365%) sky-masked
pixel difference**, below the 0.1% gate. This closes physical weak-adapter
safe fallback, not active Low performance on that adapter or the remaining
GPU matrix;
- `compare-retained-transform.json` records the retained-transform image
comparison used by the 9,500-caster steady-state gate.
Stage 1 project-owner gate:
- **PASS — accepted by the project owner on 2026-08-22.** The acceptance closes
Stage 1's physical-display and desktop-performance stop. It authorizes Stage
2; it is not a substitute for Stage 2's connected scenario, long-lifetime,
package lifecycle, additional physical-GPU, or final pack-off/pack-on rows.
Stage 2 machine-local closeout result (2026-08-22):
The exact commands, commits, metrics, artifacts, and evidence limits are in the
[Stage 2 connected and closeout report](../research/2026-08-22-atmospheric-stage2-connected-gate.md).
1. **PASS, except the external second-client row.** The connected graphical
route covered moving local players, known monster encounters
reported under the authoritative `NonPlayerCreatures` category, and equipped
children; landblock publication/demotion; clear, overcast and rain;
outdoor/interior/dungeon transitions; portal travel and reconnect. Capture
the implemented select/disable/re-enable, resize, authored sun/moon source
transitions and weather, and
fresh-process renderer/context/device-recreation assertions against a real
ACE session, proving exact resource convergence and no stale maps/owners.
Remote-player diagnostics remained zero because only one account/client was
available; a second connected client must close that evidence row.
2. **EXTERNAL HARDWARE GATE.** Repeat the current clean-source RX 9070 XT
pack-off/Low/Medium/High/Auto × 1080p/1440p/4K × capped/uncapped matrix on
every other supported physical GPU class. The integrated-AMD Auto-to-retail
artifact proves weak-adapter safe fallback only; it does not prove active Low
or the complete matrix on that adapter. Automated weak-GPU fixtures, one
fallback row, and one high-end reference adapter do not prove the remaining
physical rows.
3. **FINAL OWNER GATE.** Complete the visual matrix for Tier-1 neutral values and private-view/UI
isolation; rays at dawn/noon/dusk, behind-camera and occluded states;
foliage cutouts; moving animated shadows under sun and moon; indoor gating;
source-transition continuity; temporal pixelation/shimmer; bias/cascade seam
review; sun-only volumetric weather/occluder behavior; and pack-off
restoration.
4. **PASS.** External install/select/update/remove/fail/recover flows passed in
six fresh connected graphical processes. The nine-stop Medium lifetime route
passed with graceful shutdown, as did the deterministic 12-cycle and
fresh-device convergence fixtures.
5. **FINAL OWNER GATE.** Obtain explicit project-owner acceptance of the final pack-off and pack-on
visual/performance matrix before changing this document to shipped.
### Slice 0 — Contract, capability probe, and acdream-default no-op
**Implementation:** complete. The BCL-only v1 ABI, live revisioned plugin
discovery/catalog, retained Display selection, compatibility/cost summaries,
strict SDK-equivalent entry admission, asynchronous candidate preparation,
frame-boundary activation/withdrawal/fallback, registration-scoped no-retry,
stable diagnostics, no-op sample, and headless exclusion are present and
automated. The checked-in default-path oracle and RX 9070 XT physical pack-off
rows pass; connected lifetime evidence and the remaining supported physical GPU
classes stay open.
Define the versioned BCL-only descriptor/registry, manifest fields, semantic
bindings, pack discovery, Display selection, diagnostics, and atomic
activation/fallback transaction. Implement a no-op conformance pack only.
**Acceptance:** `acdream default (retail-faithful)` remains selected on clean and upgraded
installs; pack discovery allocates no GPU resources; the disabled run has the
same pass list, pipeline set, draw/dispatch counts, deterministic framebuffer
digests, and resource ledger as the pre-campaign baseline; malformed,
unsupported, missing, and shader-invalid fixtures all report one precise
reason and render acdream's default path without partial resources or retry loops; headless
hosts load no render assemblies or pack assets.
### Slice 1 — Tier-1 world-colour and filmic stack
**Implementation:** complete. The pack-owned main-world target, bloom chain,
ACES filmic pass, colour grade, vignette, declared neutral settings, resize
recreation, and private-viewport/UI placement are implemented and automated.
The RX 9070 XT 1080p/1440p/4K physical budget rows pass. Project-owner visual
acceptance and the remaining supported physical GPU classes stay open.
Add the main-world intermediate and implement bloom, ACES filmic tonemapping,
colour grade, and vignette through the pack API. Supply half/quarter-resolution
variants and preserve private viewports/UI.
**Acceptance:** every effect can be independently set to its neutral value;
the preset is deterministic across resize/recreate; UI, paperdoll, portal, and
appraisal surfaces retain their accepted colours; 1080p/1440p/4K captures show
no clipping, haloing at the world/UI edge, stale frame, or resource leak; the
slice meets its preset GPU/VRAM budget.
### Slice 2 — Tier-1 screen-space sun rays
**Implementation:** complete. Authored sun projection, the screen-space
occlusion mask, declared sun/day-group/weather policy, pre-tonemap ray
composition, and deterministic disabled gates are implemented and automated.
The connected dawn/noon/dusk, weather, behind-camera, occlusion, and edge-
flicker visual matrix remains open.
Project the existing authored sun position, build a screen-space occlusion
mask, and composite weather-driven crepuscular rays before tonemapping. This
slice deliberately has no shadow-map dependency.
**Acceptance:** clear dawn/dusk produces visible raking rays, noon makes them
vanish, overcast/rain mutes them, the sun behind the camera or fully occluded
produces none, and camera edges do not streak or flicker. The pack descriptor's
sun-elevation and `activeDayGroup` policy deterministically produces those
states without a second weather/clock owner. The exact same scene with Tier 1
disabled returns to the Slice-0 digest from acdream's default
retail-faithful renderer.
### Slice 3 — Tier-2 moving authored sun-and-moon dynamic shadows
**Implementation:** Stage 1 automated and project-owner live gates complete.
Camera-relative stabilized cascades,
outdoor gating, opaque and alpha-cutout casters, terrain/world receivers,
headline caster membership, exact current animated transforms, bounded
resident replay, GPU-flight ownership, and cached topology/dynamic-transform
refresh were present at the sun-only checkpoint. The approved authored
sun/dominant-moon/secondary-moon resolver and direction-versus-energy handoff
are now present, and focused plus complete fresh-process automated validation
pass. The project owner's 2026-08-22 live round accepted source alignment,
temporal stability, desktop responsiveness, and the final exposure correction.
Per-class diagnostics cover
terrain commands, outdoor
statics, buildings, animated statics, local/remote players, non-player
creatures, other live dynamics, and equipped children without inventing tree
or hostile-monster identity. Fixed-camera morning/afternoon artifacts are not
moon evidence; the live-gate result and its exact boundary are recorded in the
[Stage 1 live-gate report](../research/2026-08-22-atmospheric-stage1-live-gate.md).
The machine-local Stage 2 connected and closeout matrix passes. The external
second-client, additional-GPU, and final owner rows above remain open.
This is the campaign's headline slice. Add camera-relative cascades, opaque
and alpha-cutout caster variants, animated SSBO transforms, shadow receivers,
texel stabilization, outdoor gating, and weather/authored-directional-energy
control. Select the exact rendered direction of the visible above-horizon sun,
dominant haloed moon, or secondary moon according to the
[celestial source contract](../research/2026-08-22-dereth-celestial-shadow-sources.md),
while retaining retail's one `DirColor * DirBright` energy channel. Trees,
monsters, players, houses/buildings, terrain, and ordinary outdoor statics
participate through existing scene ownership.
**Acceptance:** in fixed-camera and live dawn/noon/dusk/night captures, shadows
align with and change direction/length under Dereth's authored sun and selected
dominant/secondary moon; overlap and no-source transitions are stable and do
not snap to an unrelated body. Walking players and monsters cast and
self-shadow from their current animated poses; foliage casts leaf/branch
cutouts rather than rectangles; houses and procedural trees retain shadows
through landblock publication/demotion without popping outside the chosen
cascade transition tolerance; indoor/dungeon captures have no outdoor
celestial directional shadow; portal/reconnect/device recreation leaves zero
stale maps or owners. Acne, Peter-panning, cascade seams, distant depth-bias
leaks, temporal pixelation/shimmer, and desktop performance pass the live user
gate and subsequent Stage 2 matrix; the dense-Arwic CPU submission and GPU
budgets pass.
### Slice 4 — Quality scaling and automatic compatibility
**Implementation:** complete. Low/Medium/High declarations, capability and
memory admission, preset cost summaries, retained Display controls, the
built-in Automatic checkbox, hysteretic Auto, diagnostics, asynchronous
off-side candidate preparation, and atomic stable-boundary swaps are present
and automated. The source-identical clean-snapshot RX 9070 XT matrix passes all
30 current rows after the Low dense-pose CPU optimization. The integrated-AMD
physical row proves that persistently over-budget Low returns Auto atomically to
retail with a visible reason and a paired-retail framebuffer match. Active Low
on that adapter and additional supported-adapter matrices remain open.
Land the Low/Medium/High presets, memory ceilings, capability-based preset
availability, stable cascade fitting, resize handling, and optional hysteretic
Auto selection. Auto may change resolution/range only at a stable frame
boundary and must expose its current choice.
**Acceptance:** every supported preset retains all headline caster classes;
weak-hardware fixtures select a valid lower preset or fail safely to acdream's
default renderer;
changing preset cannot leak, stall the render thread, invalidate streaming, or
leave mixed-resolution resources; the quality/performance table is populated
with measured physical-hardware results.
### Slice 5 — Tier-2+ volumetric shafts
**Implementation:** complete for the recorded sun-only scope. The declared
volumetric pass reuses directional-shadow depth only when the selected source
is the authored sun, consumes authored sun/weather/indoor inputs, composites
before tonemapping, and has independent quality/step settings and automated
failure gates. The reference-GPU low-sun 2,048-sample enabled/neutral A/B passes
its incremental cost target. Moon selection does not enable moon shafts. The
connected occluder/weather visual matrix and additional physical GPU classes
remain open.
Reuse the directional shadow map for world-space light shafts only while its
source is the authored sun. Drive density, strength, and colour from authored
sun/weather inputs and composite before tonemapping. A selected moon produces
directional shadows but no rays or volumetric shafts.
**Acceptance:** shafts respect terrain, trees, houses, and moving creatures;
clear low sun is strongest, overcast and indoor scenes are muted/off; disabling
shafts leaves Tier-2 shadow output unchanged; the incremental cost stays within
the Tier-2+ budget.
### Slice 6 — Pack SDK and campaign closeout
**Implementation:** SDK deliverables complete and the Stage 1 project-owner
gate passed on 2026-08-22. The v1
manifest schema, semantic binding table, compatibility/failure guide,
validator, built-in pack, and three buildable external samples are present and
automated. Connected graphical package lifecycle and long-run convergence pass.
The second-client remote-player row, remaining physical GPU classes, and final
project-owner acceptance remain open; the 30-row RX 9070 XT reference matrix is
complete.
Publish the manifest/schema, semantic binding table, sample no-op pack,
Atmospheric pack, compatibility diagnostics, authoring/validation tool, and
failure-handling guidance. Run the full automated, connected, physical-display,
performance, lifetime, portal, and screenshot matrix.
**Acceptance:** a clean external sample builds without App or Vulkan
references; install/select/update/remove/fail/recover flows work; pack-off
evidence from acdream's default retail-faithful renderer remains authoritative
and unchanged; all resource ledgers
converge after long play, reconnect, portal travel, pack disable, and device
recreation; the project owner accepts the visual matrix before the campaign is
declared shipped.
## Performance budget and measurement
The [measured pre-campaign baseline](../research/2026-08-21-terrain-and-atmospheric-rendering-findings.md#performance-baseline-and-the-binding-constraint)
is **519.7 FPS with CPU/GPU p50 of 1.869/1.096 ms**, and dense towns are
CPU-submission-bound. Fullscreen work may occupy currently idle GPU time, but
it is not treated as free. Shadow cascades must protect the CPU submission
path.
| Preset | Incremental GPU p50 / p99 at 1080p | Incremental render-CPU p50 / p99 | Pack-owned resident GPU memory |
|---|---:|---:|---:|
| Low | ≤ 2.0 / 3.0 ms | ≤ 0.15 / 0.50 ms | ≤ 64 MiB |
| Medium | ≤ 3.25 / 4.50 ms | ≤ 0.25 / 0.75 ms | ≤ 128 MiB |
| High | ≤ 4.50 / 6.00 ms | ≤ 0.35 / 1.00 ms | ≤ 256 MiB |
The current physical reference matrix is
`artifacts/atmospheric-rendering/matrix-clean-snapshot-dense-linear-v20/` on an
AMD Radeon RX 9070 XT (Vulkan 1.4.349, driver 2.0.395). The source-identical
isolated commit and Release binary both identify `4876c970`; tracked source
status is empty. All 30 rows pass. At capped 1080p, the exact 2,048-sample
windows are:
| Selection | Incremental render-CPU p50 / p99 | Inclusive GPU p50 / p99 | Resident pack memory |
|---|---:|---:|---:|
| Low | 0.108 / 0.164 ms | 0.900 / 1.002 ms | 39.719 MiB |
| Medium | 0.116 / 0.144 ms | 1.001 / 1.023 ms | 73.590 MiB |
| High | 0.121 / 0.145 ms | 1.240 / 1.273 ms | 113.556 MiB |
| Auto (settled High) | 0.122 / 0.146 ms | 1.211 / 1.222 ms | 113.556 MiB |
Every uncapped active row also passes. Across capped and uncapped active rows,
the maximum measured p50/p99 and resident memory are: Low 0.108/0.164 ms CPU,
1.070/1.080 ms GPU, 60.868 MiB; Medium 0.117/0.194 ms CPU, 1.152/1.163 ms GPU,
103.583 MiB; High 0.121/0.159 ms CPU, 2.237/2.252 ms GPU, 238.141 MiB; and Auto
0.122/0.166 ms CPU, 1.482/1.494 ms GPU, 145.856 MiB. All six retail rows record
zero pack resources/work. At 4K, Low needs 131,302,400 bytes and Medium/initial
Auto need 198,440,960 bytes, so those six capped/uncapped rows correctly report
`ResourceUnavailable`, create no pack resources/work, and pass their strict
paired-default framebuffer comparisons. This closes the current reference
adapter, not the connected receiver A/B route or other supported/weak physical
GPU classes.
Tier 2+'s separate low-sun physical A/B is recorded in
`artifacts/atmospheric-rendering/volumetric-performance-ab-1080p.json`. Both
runs pin High, 1080p uncapped, clear weather, 16.667° sun elevation, the same
50 m / 180° / 10° camera, 9,498 casters, four cascades, and exact 2,048-sample
windows. Enabling one volumetric draw over the neutral-strength run adds
**0.189 ms GPU p50 / 0.219 ms p99**, **0.009 ms CPU p50 / 0.007 ms p99**, and
4,147,200 resident bytes. The measured GPU p50 passes the Tier-2+ ≤0.40 ms
reference target; connected weather/occluder behavior and other adapters still
require their own rows.
acdream's default path has a stricter gate: zero new enhancement passes,
images, buffers, submissions, or shader variants, with CPU/GPU deltas within
the existing run-to-run noise envelope and deterministic reference captures
unchanged. `NoOpRenderPackProductionIntegrationTests` pins the pre-campaign
pass list, pipeline set, draw/dispatch tuple, framebuffer SHA-256, and complete
resource ledger; the matrix's six physical retail rows independently record
zero pack work at all three resolutions and both pacing modes.
Measurement protocol:
- Use existing asynchronous GPU timestamps and frame diagnostics. Never add a
`glFinish`/device-idle-style measurement fence to the frame loop.
- Runtime Auto compares the declared incremental CPU budget with pack-added
target-preparation, shadow, post, and volumetric recording only. The complete
enhanced main-world receiver recording is retained separately as an absolute
CPU diagnostic; it is not itself an incremental delta. GPU accounting remains
conservatively inclusive of the complete enhanced receiver pass and every
resolved pack pass, exactly once after asynchronous resolution. Identical
pack-off/on runs remain the authority for the final receiver CPU delta and
the complete physical incremental A/B result.
- Run capped and uncapped Release builds; record CPU/GPU p50, p95, and p99,
FPS, draw/dispatch submissions, shadow-caster count, cascade draw count,
transient/retained GPU bytes, and process working/private memory.
- Compare pack off, Low, Medium, and High with identical camera paths, render
resolution, active day group, authored celestial/time keyframe, entity set,
and warmed residency.
- Cover pinned dense Arwic, a foliage-heavy outdoor route, a building cluster,
moving-player/monster combat, dawn/noon/dusk/night plus sun/moon/no-source
transitions, clear/overcast/rain, a dungeon, portal travel, resize, reconnect,
and a long lifetime run.
- Measure 1920x1080, 2560x1440, and 3840x2160 on each supported physical GPU
class. Report—not hide—unavailable presets.
- No cascade may rerun CPU PView/portal traversal or issue per-object draws.
The pass records CPU classification calls and submission counts so this is
an enforced gate, not an architectural hope.
- Pipeline creation and pack validation occur before atomic activation. Normal
play may not hitch on first shadow, weather, caster, or quality use.
## Quality scaling for weak hardware
These are starting envelopes to validate, not asset or world guarantees.
Distances are metres and are always clamped to current resident world data.
| Setting | Bloom/rays | Directional shadows | Volumetric shafts | Approx. depth-map memory at 32-bit depth |
|---|---|---|---|---:|
| Off / acdream default | Off | Off | Off | 0 MiB |
| Low | Quarter resolution | 2 × 768² cascades, about 72 m maximum reach | Off by default | 4.5 MiB |
| Medium | Half resolution | 3 × 1536² cascades, about 144 m maximum reach | Quarter resolution | 27 MiB |
| High | Half/full as measured | 4 × 2048² cascades, about 240 m maximum reach | Half resolution | 64 MiB |
Additional scaling rules:
- Prefer reducing cascade count, shadow resolution, reach, bloom/ray
resolution, and sample count before removing a feature's semantic
correctness.
- Preserve alpha-tested foliage and animated transforms at every shadow
quality. A cheaper preset may look softer or end sooner; it may not turn a
tree into a rectangle or freeze a monster's shadow.
- Clamp resource dimensions and bytes before allocation. A capability probe
that cannot support Low disables the pack and explains why.
- Preset availability uses the selected Vulkan adapter's probed 2-D image and
array-layer limits. Optional pack memory receives at most one eighth of its
device-local heap, capped at 256 MiB resident and 512 MiB transient; Auto
starts at Low when Medium is unavailable and acdream's default remains the fallback if
Low cannot fit.
- Optional Auto quality uses long hysteresis and stable frame-boundary swaps;
it never oscillates cascade layouts frame to frame. If Low stays over its
declared runtime GPU/CPU/resident budgets for 180 stable samples, Auto
retires the complete pack and returns to acdream's default with the measured
and declared limits in the visible failure reason.
- 4K defaults may choose lower post-process resolution because Tier 1 pays
approximately four times the 1080p pixel workload.
## Constraints and traps
This list carries forward every item in the findings' measured
[shadow-specific constraints](../research/2026-08-21-terrain-and-atmospheric-rendering-findings.md#shadow-specific-constraints)
and adds the current renderer's ownership and lifecycle boundaries.
1. **The renderer is the shipped pass-based Vulkan RHI.** Design against
`IGpuDevice` / `IGpuFrame` / `IGpuPassEncoder` and explicit pass/pipeline
descriptions. Do not revive an OpenGL backend or build a parallel renderer.
2. **The current PView graph is authoritative.** Shadow and atmosphere passes
consume its retained scene; they do not introduce a competing visibility
owner or change punch/seal, shared-alpha, particle, or private-viewport
ordering.
3. **CPU submission is the limiting dimension.** Reusing the full bounded
resident caster set is preferable to CPU-reculling it per cascade. GPU
culling is the only planned escalation.
4. **Alpha-tested foliage needs sampling and discard.** Reusing the existing
empty `portal_depth` fragment shader would cast solid tree rectangles.
5. **Animated casters use the existing N.5 SSBO transforms.** A second pose,
animation tick, or entity owner is forbidden.
6. **Indoors has no outdoor celestial directional shadow.** Dungeon/EnvCell
authored ambient and local lighting wins; outdoor sun/moon directional
shadows, sun rays, and sun shafts are gated off.
7. **Cascades are camera-relative and streaming-bounded.** They may not use a
fixed Dereth-wide extent, request landblocks, retain retired generations, or
draw stale portal destinations.
8. **Depth bias is specified in meaningful eye/world units.** A constant NDC
bias spans approximately `b*d²/near` metres of eye depth at distance and can
recreate issue #129's door-shaped holes through hills. Bias, normal offset,
cascade projection, near/far fitting, and reversed-depth conventions must be
tested together at near and far ranges.
9. **“Shadow” is an overloaded project term.** Existing `shadow_objects` and
`CPhysicsObj::add_shadows_to_cells` are collision registration, not light
shadows. New names use `DirectionalShadowMap`, `ShadowCaster`, or
`CelestialDirectionalShadow`; never generic `ShadowObject`.
10. **Authored celestial position, directional energy, and weather are
inputs.** Do not invent another celestial clock, light-energy channel,
weather state, or hard-coded dawn/noon schedule. The directional map uses
the visible above-horizon sun/dominant moon/secondary moon's exact rendered
direction but retail's single interpolated `DirColor * DirBright` colour/
energy channel, per the
[celestial source research](../research/2026-08-22-dereth-celestial-shadow-sources.md).
Rays and shafts remain sun-only and use the pack's declared sun-elevation
curve and categorical `activeDayGroup` mapping. The decomp evidence proves
the category reaches the frame, not an authored numeric ray intensity, so
the enhancement mapping must remain explicit pack policy.
11. **Atmosphere ordering is deliberate.** Rays/shafts composite before
tonemapping; retained UI and private viewports remain outside main-world
post-processing.
12. **Transparency remains ordered.** The pack cannot flatten the retail
world-alpha queue into an unordered shadow/post pass. Truly translucent
surfaces cast no opaque shadow until separately designed.
13. **Generation and GPU-flight lifetimes remain exact.** Pack images,
descriptors, and pipelines retire through existing fences and converge on
disable, resize, portal, reconnect, reset, failure, and device recreation.
14. **4K is a distinct performance row.** Tier-1 effects scale with pixels;
passing at 1080p is not evidence for 4K.
15. **Do not repeat closed investigations.** High-res DAT precedence is not
dropping overrides, AC detail textures are colour/alpha rather than normal
maps, and the engine's historical DOT3 capability does not turn those
assets into PBR inputs; these points are already falsified in the findings.
16. **Caster evidence must not exceed source identity.** Diagnostics separately
count terrain commands, outdoor statics, buildings, animated statics,
local/remote players, non-player creatures, other live dynamics, and
equipped children. Outdoor statics include trees but have no authoritative
tree discriminator; non-player creatures include monsters but have no
render-only hostile-monster-versus-NPC discriminator. Visual/connected
acceptance must name those limits instead of fabricating narrower counts.
## What this does NOT do
- It does **not** change acdream's default retail-faithful rendering path, its
expected output, or its authority in fidelity tests.
- The Atmospheric shader pack does **not** own or depend on #226 detail
texturing or the terrain-normal parity correction. Those remain separate
Track A ports even though the project owner authorized their implementation
in the same worktree.
- It does **not** add PBR or fabricate normal, roughness, metalness, or material
maps that AC's assets do not contain.
- It does **not** change terrain vertices, collision triangles, walkability,
slope response, physics shadow lists, movement, projectiles, or any Runtime
physics/collision owner.
- It does **not** change gameplay rules/state, network messages or ordering, or
any Runtime gameplay/network owner.
- It does **not** extend view distance, streaming radius, landblock residency,
or PView visibility to find more shadow casters.
- It does **not** add an indoor sun or replace authored EnvCell/local lights.
- It does **not** turn moon texture brightness or mesh luminosity into another
world-light energy channel, and it does not produce moon rays or moon shafts.
- It does **not** post-process retained UI or silently restyle private
paperdoll, appraisal, or portal viewports.
- It does **not** promise that every pack or quality preset runs on unsupported
hardware; compatibility failure is explicit and safely returns to acdream's default renderer.
- Campaign AR does **not** outrank active M4 gameplay work. The project owner's
explicit reprioritization authorizes this campaign without changing M4's
milestone priority; #268 + TS-8 are already complete and retired.
## Completion gate
The design, implementation, Stage 1 owner gate, and every available
machine-local Stage 2 connected, performance, lifetime, package, shader, build,
and complete-test gate are complete. The campaign becomes **shipped** only
after the second-client remote-player row, remaining physical-hardware rows,
and final visual gates above pass and the project owner accepts both sides of
the final matrix:
- **pack off:** unchanged output, performance, ownership, and lifecycle from
acdream's authoritative default retail-faithful renderer; and
- **pack on:** moving authored sun-and-moon directional shadows from trees,
monsters, players, and buildings; sun-only rays/shafts; scalable atmosphere,
safe compatibility fallback, measured budgets, and clean long-lived resource
convergence.