146 lines
9.4 KiB
YAML
146 lines
9.4 KiB
YAML
project:
|
|
name: Fensalir
|
|
root: E:\Projects\Fensalir
|
|
upstream: https://github.com/GameCult/Fensalir.git
|
|
purpose: >
|
|
Native C# runtime and renderer dependency for Aquarium-style clients. The
|
|
engine owns Win32 hosting, D3D12 rendering, input, hot reload, debug UI,
|
|
audio output, client contracts, fractal/field machinery, and engine demos.
|
|
|
|
current_model:
|
|
solution: Fensalir.sln
|
|
host:
|
|
implementation: src/Aquarium.Engine
|
|
contracts: src/Aquarium.Engine.Contracts
|
|
renderer: src/Aquarium.Engine/Render
|
|
shaders: src/Aquarium.Engine/Render/Shaders
|
|
assets: src/Aquarium.Engine/Assets
|
|
scripts: scripts
|
|
fractal:
|
|
implementation: src/Aquarium.Engine.Fractal
|
|
tests: tests/Aquarium.Engine.Fractal.Tests
|
|
receipt_tool: tools/Aquarium.Fractal.Receipt
|
|
demos:
|
|
fensalir_splash: src/Aquarium.Fensalir
|
|
minimal: src/Aquarium.Sample.Minimal
|
|
zyphos: src/Aquarium.Zyphos
|
|
external_clients:
|
|
epiphany_aquarium: E:\Projects\Aquarium-Engine
|
|
mimir: owns the sensor-fusion app/adapter surface formerly prototyped here
|
|
dependencies:
|
|
cult_math: E:\Projects\CultMath
|
|
cult_lib: E:\Projects\CultLib
|
|
aqua_synth_faust: repo-local NuGet package feed under packages
|
|
|
|
invariants:
|
|
- Fensalir owns reusable host, renderer, audio, reload, contracts, and engine mechanisms.
|
|
- Fensalir is not a traditional rendering pipeline. It is a field/evidence
|
|
machine: contributors emit bounded Form, Appearance, and Transport claims
|
|
with identity, travel/depth, metadata, control, and reservoir-guide lanes.
|
|
Treating a pass as "just drawing pixels" violates the engine invariant
|
|
unless it is explicitly marked as a fallback/debug draw with no authority.
|
|
- Client repos own policy, role names, narrative semantics, app state, and client shaders.
|
|
- Epiphany Aquarium depends on Fensalir; Fensalir must not depend on Epiphany.
|
|
- Demo projects inside this repo are allowed to exercise engine features but must not become hidden engine policy.
|
|
- Public `Aquarium.*` assembly names remain for continuity until a deliberate namespace/package migration.
|
|
- Spline/tube visibility is owned by shader SDF evaluation. CPU geometry may
|
|
place conservative sampling envelopes and endpoint/neighbor packets, but
|
|
quad-local strip UVs must not decide visible line coverage.
|
|
- Reservoir splat rendering must not impose large minimum billboard radii on
|
|
transparent buffer-field/tube samples. Sample envelopes should stay tied to
|
|
authored field radius so clients can reduce reservoir sample count without
|
|
turning sparse probes into visible plates.
|
|
- Reservoir contents are not forced to be pixel-sized. Pixel-level resolve
|
|
samples bounded claims; it does not define their native support. Broad,
|
|
smooth surfaces may be represented by few large surface claims. Heightfield
|
|
terrain should be a quadtree of brush-painted surface tiles, subdivided by
|
|
projected footprint, curvature, brush/material detail, silhouettes, and
|
|
temporal uncertainty before SDF probes emit detail-adaptive surface splats.
|
|
- Rendering backends are lowerings, not truth owners. Heightfields, splines,
|
|
direct SDF proxies, meshes, volumes, fractal probes, and Mimir sensor
|
|
observations must publish bounded Form/Appearance/Transport field claims
|
|
before they can participate in reusable field evidence.
|
|
- Field packet payload handles are not authority. Resource-backed claims and
|
|
packets must reference declared AquariumFieldResourceDeclaration rows with
|
|
kind, GPU residency, shader access, format, shape, validity, version, and
|
|
native handle metadata. Missing, CPU-only, or backend-incompatible resources
|
|
defer lowering instead of becoming visible evidence.
|
|
- Rendering-relevant field buffers move to GPU residency as early as possible
|
|
and stay there. Fensalir must pass GPU resource handles/SRVs/UAVs between
|
|
compute and render lowerings; CPU readback or CPU tessellation is a
|
|
diagnostic-only escape hatch, not the live TubeField path.
|
|
|
|
next_actions:
|
|
- Keep origin pointed at https://github.com/GameCult/Fensalir.git.
|
|
- Keep `dotnet build Fensalir.sln` green after the split.
|
|
- Cut the rendering rebuild through explicit field-domain/field-claim
|
|
contracts before adding another backend-specific visual path.
|
|
- Extend the D3D12 field packet/resource resolver beyond its first
|
|
structured/curve-buffer cut. Current contracts, DSL, and renderer registry
|
|
can validate and plan resource-backed TubeField packets, import shared GPU
|
|
structured buffers by handle, and allocate Fensalir-owned GPU-resident
|
|
slots only when Fensalir is the producer. The TubeField DSL can now express
|
|
a 2D rolling float buffer as Catmull-Rom XY tubes with modulo column
|
|
addressing, amplitude power/normalization, radius, ramp texture path, and
|
|
emission scale. D3D12 now has a TubeField compute/render lowering:
|
|
compute binds the rolling sample buffer as read-only GPU memory, emits
|
|
fixed-budget vertex/index buffers with endpoint-clamped Catmull-Rom tube
|
|
envelopes, honors declared sample stride with byte-address loads, and
|
|
records one draw batch per lowering so the TubeField pixel shader can bind
|
|
the right source row/column and resample material per pixel with the cheap
|
|
5-tap approximation. Texture2D local assets are now declared as first-class
|
|
field resources with source URI metadata, DSL aliases, lazy D3D12 upload,
|
|
SRV binding, and TubeField ramp lookup by resource key; missing/unresolved
|
|
ramps bind a Fensalir-owned linear fallback ramp. TubeField compute now
|
|
emits one GPU-resident D3D12 DrawIndexed indirect argument packet per
|
|
material/resource batch, and render binds the batch source/ramp state then
|
|
executes the packet with ExecuteIndirect. The first material is opaque field
|
|
geometry with squared normalized emission, fake Fresnel center-bright/
|
|
edge-dark shaping, and requested/dispatched/truncated/indirect-draw segment
|
|
reporting. The debug field-evidence summary exposes TubeField requested,
|
|
dispatched, truncated, upload, skipped-upload, and unplanned-lowering
|
|
counts so client-side subdivision budgets can be tuned from the live
|
|
renderer result instead of guessed. SurfacePage resources now have a first
|
|
resolver: contracts and DSL can declare GPU-resident 2D pages with width,
|
|
height, format, version,
|
|
and optional local source, and the D3D12 registry allocates/imports them as
|
|
shader-readable page textures. VolumeTexture resources now have the same
|
|
first resolver shape: contracts and DSL can declare GPU-resident 3D
|
|
textures with dimensions, depth, format, and version, and the D3D12 registry
|
|
allocates them as shader-readable volume textures. Mesh resources are now
|
|
first-class packages with `Mesh.Vertices` and `Mesh.Indices` buffer members,
|
|
topology, index format, bounds, submesh count, and version. The DSL can
|
|
declare a GPU-resident mesh package, and the D3D12 registry allocates and
|
|
reuses matching vertex/index GPU buffers under the mesh resource key. The
|
|
evidence DSL also has a generic resource-backed `claim` command, so Mesh,
|
|
Height/SurfacePage, and Density/VolumeTexture resources can be planned into
|
|
backend packets without pretending a render path exists. Remaining cuts are
|
|
render lowerings that consume those packets. Mesh layout authority is now
|
|
split intentionally: imported/user-facing meshes use the standard
|
|
`PositionNormalUvColor` layout, while generated meshes may declare
|
|
`PipelinePrivate` so the selected lowering owns the minimal bytes it emits
|
|
and consumes. Mesh rendering is now blocked on choosing the first selected
|
|
render lowering/material path, not on a generic imported-mesh ABI. The
|
|
first generated-mesh render cut is TubeField itself: compute emits
|
|
pipeline-private vertex/index/indirect buffers, render binds them through a
|
|
named `D3D12PipelinePrivateGeneratedMesh`, and TubeField material state
|
|
supplies the shader-specific source/ramp/constants. The DrawIndexed indirect
|
|
command signature is now owned by the generated-mesh lane rather than
|
|
TubeField, so future generated page/volume/surface lowerings can share that
|
|
draw ABI while owning their own producer buffers and materials. TubeField
|
|
dispatch now obeys selected packet authority: only lowerings whose claim has
|
|
a planned TubeField backend packet are expanded, and unplanned lowerings are
|
|
counted instead of rendered. Validation also rejects TubeSpline lowering
|
|
metadata whose claim is not Tube-encoded or whose resource does not match
|
|
the claim payload, so split authority is caught before render dispatch.
|
|
Field evidence now carries explicit Float32 resource uploads separate from
|
|
resource declarations. D3D12 uploads those frame samples into resolved
|
|
structured buffers before TubeField compute reads them, so a Fensalir-owned
|
|
GPU resource can be live data rather than paperwork. Structured buffer
|
|
declaration version is content freshness, not buffer-shape authority:
|
|
D3D12FieldResourceRegistry now reuses an existing structured buffer when
|
|
element count, stride, and access are unchanged, updating the recorded
|
|
version without reallocating GPU memory every frame.
|
|
- Move any remaining client-only Epiphany state found here back to `E:\Projects\Aquarium-Engine`.
|
|
- Keep Mimir app/adapters out of this repo; Fensalir may expose generic sensor-fusion contracts only.
|
|
- Package contracts/host deliberately before replacing sibling source references in client repos.
|