feat(render): implement Campaign AR and terrain fidelity
This commit is contained in:
parent
99cf26e00c
commit
7a5f96ede5
368 changed files with 50611 additions and 950 deletions
|
|
@ -2070,6 +2070,8 @@ Native macOS graphical support is not committed by this track. The current
|
|||
mandatory renderer requires modern OpenGL capabilities beyond Apple's native
|
||||
OpenGL ceiling; revisit macOS only if a supported graphics backend is chosen.
|
||||
|
||||
**Future / unscheduled — Campaign AR:** the opt-in [Atmospheric Rendering / Shader Packs campaign](2026-08-21-atmospheric-rendering.md) makes moving authored sun-and-moon directional shadows from trees, monsters, players, and buildings its Tier-2 headline while preserving acdream's current retail-faithful renderer as the default and leaving physics, collision, gameplay, and network behavior unchanged; the project owner assigned Campaign AR on 2026-08-22 without displacing active M4 gameplay work. The [celestial source contract](../research/2026-08-22-dereth-celestial-shadow-sources.md) selects sun, dominant moon, then secondary moon by rendered direction while retaining AC's single authored directional-energy channel; sun rays and volumetrics remain sun-only. The previously referenced #268 + TS-8 package is complete and retired. Stage 1's automated correctness, performance, lifetime, locked-restore, Release, evidence, documentation, and project-owner live gates completed on 2026-08-22 after the opt-in exposure correction. Stage 2 connected, performance, lifetime, package-lifecycle, physical-hardware, and closeout evidence is active.
|
||||
|
||||
---
|
||||
|
||||
## Cross-cutting work tracked in parallel
|
||||
|
|
|
|||
931
docs/plans/2026-08-21-atmospheric-rendering.md
Normal file
931
docs/plans/2026-08-21-atmospheric-rendering.md
Normal file
|
|
@ -0,0 +1,931 @@
|
|||
# Campaign AR — Atmospheric Rendering / Shader Packs
|
||||
|
||||
**Date:** 2026-08-21
|
||||
**Status:** STAGE 2 ACTIVE — the approved authored sun-and-moon shadow-source
|
||||
extension and every non-physical Stage 1 correctness, performance, lifetime,
|
||||
Release, evidence, and documentation gate are complete. After the live
|
||||
sun/moon, source-transition, temporal-stability, desktop-performance, and
|
||||
exposure correction round, the project owner accepted Stage 1 on 2026-08-22.
|
||||
Stage 2 connected, lifetime, package-lifecycle, physical-hardware, and final
|
||||
closeout evidence is now active.
|
||||
**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. Stage 2 is active and limited to the
|
||||
remaining connected, lifetime, package-lifecycle, physical-hardware, evidence,
|
||||
and final owner-acceptance rows; 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.35–0.80 ms |
|
||||
| 1 | Screen-space sun rays (crepuscular) | Authored sun screen position plus an occlusion mask; **no shadow maps** | 0.20–0.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.50–3.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.15–0.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 (0–6) 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 and closeout gates, now active:
|
||||
|
||||
1. Execute the already-implemented connected graphical route and complete its
|
||||
remaining matrix: moving local/remote 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.
|
||||
The local recording/device-recreation semantics are closed; this connected
|
||||
execution and its user-visible evidence are not.
|
||||
2. Repeat the now-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. 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. Exercise external install/select/update/remove/fail/recover flows in the
|
||||
graphical host, then complete the long lifetime run. Automated SDK and
|
||||
lifecycle fixtures do not replace this connected evidence.
|
||||
5. 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).
|
||||
Stage 2 connected and closeout acceptance is active.
|
||||
|
||||
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, long-run convergence, the
|
||||
remaining physical GPU classes, and 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, Stage 1 implementation, automated validation, and project-owner
|
||||
live gate are complete. Stage 2 and closeout are active. The campaign becomes
|
||||
**shipped** only after the subsequent
|
||||
connected, full physical-hardware, lifetime, and 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue