Document temporal quality captures and 720p costs
@@ -52,3 +52,14 @@ World transparency and sprites use the scene depth/order and reject stale color
|
||||
their reactive pixels. TAA and Upscale are optional image-quality paths; compare
|
||||
them against Off on the actual game scene, especially thin geometry, slow pans,
|
||||
newly revealed surfaces and moving transparent content.
|
||||
|
||||
These are first-generation, opt-in reconstruction modes. They can reduce shimmer
|
||||
on a stationary edge while lowering the peak brightness of a subpixel line, and
|
||||
a newly revealed edge can differ by one pixel from its settled appearance. The
|
||||
amount depends on scene content, resolution and motion. Upscale also trades
|
||||
internal render resolution for resolve cost and extra images; it is not always
|
||||
faster. Compare Off, TAA and Upscale at the target output resolution with both
|
||||
still and moving cameras, and inspect thin objects and opening doors before
|
||||
choosing a mode for a game. The [P3 temporal validation record](https://github.com/emil28092005/Faset_Engine/blob/main/docs/validation/p3-temporal-2026-09-24/README.md)
|
||||
contains source captures, paired image measurements and a bounded 720p cost
|
||||
profile.
|
||||
|
||||
@@ -7,6 +7,7 @@ These files preserve bounded checks and their inputs. Each record states its sou
|
||||
- [P2 GPU visibility Linux evidence](p2-gpu-visibility-2026-09-23/README.md): Debug/Release GPU acceptance, lavapipe functional checks, relocated Player exports, and explicit platform/performance limits.
|
||||
- [P2 pinned SwiftShader compatibility](p2-swiftshader-2026-09-23/README.md): the Windows CI regression, shader capability fix, independent review closure, final native CI and relocated Player evidence.
|
||||
- [P3 lighting and shadows](p3-lighting-2026-09-24/README.md): implementation, Forward+ A/B and image parity, acceptance matrix, bounded Linux evidence, and remaining Windows/platform checks; temporal reconstruction is tracked separately.
|
||||
- [P3 temporal reconstruction](p3-temporal-2026-09-24/README.md): Off/TAA/Upscale source captures, edge and reveal measurements, and bounded 720p costs.
|
||||
- [Windows software Vulkan](windows-software-vulkan-2026-09-18/README.md): fresh native build, 35 tests, launcher/window/MCP workflows and both relocated Release games on SwiftShader.
|
||||
- [Checkpoint 5 Linux acceptance](checkpoint5-linux-2026-09-18/README.md): clean offline source build, first Editor launch, exact-candidate standalone games and live Blender checks.
|
||||
- [Final Linux source checks](final-linux-2026-09-18/README.md): `4cb8255` integrated test results and both Release games after the asset-relocation correction, including package manifests and standalone captures.
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
# P3 temporal reconstruction: image quality and cost, 2026-09-24
|
||||
|
||||
This record covers Faset's first-generation, opt-in TAA and temporal upscaler.
|
||||
The temporal shader source under test is
|
||||
`1a1f69f7e88b3ea69986931dfcf6baf9b43a431c` on
|
||||
`feat/p3-temporal-integration`; the combined integration source revision is
|
||||
`4a3453e`. Final CI results are tracked with that integration branch. The
|
||||
physical Vulkan device was an
|
||||
NVIDIA GeForce RTX 2080 Ti with proprietary driver 595.84 on Linux. Both
|
||||
fixtures requested Vulkan validation and every recorded frame reported zero
|
||||
validation errors. These observations do not establish physical Windows GPU
|
||||
behavior or high-end reconstruction quality.
|
||||
|
||||
## Raw artifacts and method
|
||||
|
||||
- [Lossless PNG example](captures/wire-static-taa-15.png) and
|
||||
[frame-level CSV linking every capture](frames.csv) cover
|
||||
the Direct visibility path at 160×120, except the 319×241 resize frame.
|
||||
The sequences are static subpixel wire (16 phases), slow camera pan (16),
|
||||
moving cube (16), unobstructed background (16), opening door (4), camera cut
|
||||
(2), resize (2), and translucent world geometry plus sharp UI (2). Each has
|
||||
Off, jittered current-only TAA, accumulated TAA, current-only Upscale, and
|
||||
accumulated Upscale captures. The current-only controls mark each frame as a
|
||||
camera cut: they retain the same 16-phase jitter and internal extent while
|
||||
rejecting history. Upscale uses render scale 0.67. Off has no jitter.
|
||||
- [Computed metrics](metrics.json) contain every sample, fixed ROI coordinates,
|
||||
steady-state timing distributions and paired image errors. The
|
||||
[contact sheet](contact-sheet.png) shows representative source frames without
|
||||
artistic retouching. The [door edge detail](door-edge-nearest-5x.png) crops
|
||||
phase 3 and enlarges pixels 5× with nearest-neighbor sampling; its second row
|
||||
is the same-jitter unobstructed reference.
|
||||
`tools/analyze_temporal_quality.py` converts the raw PPM output of
|
||||
`faset_render_temporal_acceptance_tests --capture-quality DIR` to PNG
|
||||
losslessly and computes the metrics. It needs Python with NumPy and Pillow.
|
||||
- [720p raw profile](profile-720p-debug.csv) contains 30 measured frames per
|
||||
Off/TAA/Upscale mode after 10 warm-up frames, with rotating mode order.
|
||||
`faset_render_temporal_acceptance_tests --profile-720p CSV` reproduces this
|
||||
fixed Direct scene: one opaque cube and one thin wire, output 1280×720,
|
||||
Upscale internal 858×483. It was a Linux Debug run with validation requested,
|
||||
not a Release or gameplay frame-rate result. GPU timestamps include submitted
|
||||
work and the synchronous image-to-buffer capture; renderer CPU time includes
|
||||
the wait and host readback.
|
||||
|
||||
Reproduction from a configured build:
|
||||
|
||||
```sh
|
||||
cmake --build build/linux-debug --target faset_render_temporal_acceptance_tests --parallel 2
|
||||
ctest --test-dir build/linux-debug --no-tests=error -R '^render_temporal_acceptance$' --output-on-failure
|
||||
build/linux-debug/faset_render_temporal_acceptance_tests --capture-quality /tmp/faset-p3-quality
|
||||
python3 tools/analyze_temporal_quality.py --input /tmp/faset-p3-quality \
|
||||
--output docs/validation/p3-temporal-2026-09-24 \
|
||||
--revision 1a1f69f7e88b3ea69986931dfcf6baf9b43a431c \
|
||||
--driver 'NVIDIA proprietary 595.84'
|
||||
build/linux-debug/faset_render_temporal_acceptance_tests --profile-720p /tmp/faset-p3-720p.csv
|
||||
```
|
||||
|
||||
## Image-quality observations
|
||||
|
||||
The static variation measure is the mean absolute RGB difference between
|
||||
consecutive frames over phases 5–15 in the fixed ROI; lower means less frame
|
||||
shimmer, but it says nothing by itself about retained contrast. Wire energy is
|
||||
the mean summed RGB value over phases 4–15 in that ROI, and peak is the mean
|
||||
brightest channel per frame. All color figures use 8-bit output values.
|
||||
|
||||
| 160×120 fixture | Current-only | Accumulated | Change |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| Static wire RGB frame delta, TAA | 0.388 | 0.360 | −7.2% |
|
||||
| Static wire RGB frame delta, Upscale | 0.439 | 0.412 | −6.1% |
|
||||
| Static wire ROI RGB energy, TAA | 8,234 | 8,275 | +0.5% |
|
||||
| Static wire ROI RGB energy, Upscale | 7,429 | 7,485 | +0.8% |
|
||||
| Static wire mean peak, TAA | 179 | 167 | −6.7% |
|
||||
| Static wire mean peak, Upscale | 179 | 161 | −9.9% |
|
||||
| Slow pan RGB frame delta, TAA | 0.399 | 0.398 | −0.2% |
|
||||
| Moving cube RGB frame delta, TAA | 1.930 | 1.917 | includes real motion |
|
||||
|
||||
The separate static cube-edge acceptance ROI fell from 0.832 jittered
|
||||
current-only to about 0.739 under TAA. Its exact percentage does not transfer
|
||||
to the thin wire. The original resolver achieved a much larger apparent wire
|
||||
variance reduction by dimming the wire about 15%; the final depth-aware
|
||||
resolver retains total wire energy within 1% in this fixture. It still reduces
|
||||
peak contrast and offers little gain during a slow pan. Upscale is not
|
||||
equivalent to a full-resolution reference for thin detail.
|
||||
Off has zero static frame variation because it has no jitter; that does not
|
||||
make its edges alias-free.
|
||||
|
||||
The door's newly exposed center matched current-only within one RGB value on
|
||||
the first open frame. No red pixels from the old door appeared in the tested
|
||||
old-door ROI. Against a phase-aligned, unobstructed temporal background, the
|
||||
30×35 edge ROI had 121 TAA and 176 Upscale pixels with any channel difference
|
||||
above 8 on the first open frame, then 17 and 28 respectively on the next frame.
|
||||
The enlarged comparison shows a one-pixel dark green/top-bottom edge
|
||||
difference, with no displaced red silhouette. It is a bounded residual, not a
|
||||
claim of zero halo. The explicit cut output matched
|
||||
current-only exactly in its ROI; resize and UI pixels matched their controls.
|
||||
The existing Direct, GPU-frustum and GPU-occlusion tests separately cover
|
||||
moving reveal, cut, reset, resize, shader reload and Vulkan validation.
|
||||
|
||||
## 1280×720 cost on this sparse scene
|
||||
|
||||
All values below are milliseconds except allocation. p95 is linearly
|
||||
interpolated at rank `(n − 1) × 0.95` among the 30 measured frames.
|
||||
|
||||
| Mode | Full GPU p50 / p95 | Resolve p50 / p95 | Composite p50 / p95 | Renderer CPU p50 / p95 | Live Vulkan allocation |
|
||||
| --- | ---: | ---: | ---: | ---: | ---: |
|
||||
| Off | 0.560 / 0.580 | — | — | 2.256 / 2.527 | 43.02 MiB |
|
||||
| TAA | 0.671 / 0.715 | 0.081 / 0.101 | 0.026 / 0.028 | 2.545 / 2.927 | 76.77 MiB (+33.75) |
|
||||
| Upscale 0.67 | 0.672 / 0.703 | 0.079 / 0.099 | 0.025 / 0.027 | 2.630 / 3.448 | 68.52 MiB (+25.50) |
|
||||
|
||||
Main raster p50 was only 0.015–0.018 ms because this fixture is sparse; at
|
||||
this resolution and content, lower scene resolution did not pay for the output
|
||||
resolve/composite. The depth-aware 2×2 history sampling is included in these
|
||||
costs. A dense game scene, Release build, another driver or display path may
|
||||
have different results. The renderer's synchronous full-frame capture makes
|
||||
these CPU and GPU totals unsuitable as unqualified gameplay FPS predictions.
|
||||
|
||||
TAA and Upscale therefore remain opt-in. Compare Off and a jittered
|
||||
current-only capture at the game's target resolution, watch thin-object peak
|
||||
contrast and newly revealed edges, and profile the whole frame. These fixtures
|
||||
are a bounded regression check, not parity with Unreal TSR, FSR or DLSS.
|
||||
|
After Width: | Height: | Size: 186 B |
|
After Width: | Height: | Size: 282 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 262 B |
|
After Width: | Height: | Size: 186 B |
|
After Width: | Height: | Size: 282 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 185 B |
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 209 B |
|
After Width: | Height: | Size: 205 B |
|
After Width: | Height: | Size: 214 B |
|
After Width: | Height: | Size: 210 B |
|
After Width: | Height: | Size: 210 B |
|
After Width: | Height: | Size: 207 B |
|
After Width: | Height: | Size: 209 B |
|
After Width: | Height: | Size: 213 B |
|
After Width: | Height: | Size: 214 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 209 B |
|
After Width: | Height: | Size: 211 B |
|
After Width: | Height: | Size: 209 B |
|
After Width: | Height: | Size: 205 B |
|
After Width: | Height: | Size: 215 B |
|
After Width: | Height: | Size: 205 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 208 B |
|
After Width: | Height: | Size: 209 B |
|
After Width: | Height: | Size: 237 B |
|
After Width: | Height: | Size: 250 B |
|
After Width: | Height: | Size: 263 B |
|
After Width: | Height: | Size: 251 B |
|
After Width: | Height: | Size: 253 B |
|
After Width: | Height: | Size: 261 B |
|
After Width: | Height: | Size: 253 B |
|
After Width: | Height: | Size: 255 B |
|
After Width: | Height: | Size: 254 B |
|
After Width: | Height: | Size: 248 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 260 B |
|
After Width: | Height: | Size: 242 B |
|
After Width: | Height: | Size: 258 B |
|
After Width: | Height: | Size: 262 B |
|
After Width: | Height: | Size: 205 B |
|
After Width: | Height: | Size: 244 B |
|
After Width: | Height: | Size: 274 B |
|
After Width: | Height: | Size: 264 B |
|
After Width: | Height: | Size: 257 B |
|
After Width: | Height: | Size: 255 B |
|
After Width: | Height: | Size: 271 B |
|
After Width: | Height: | Size: 261 B |
|
After Width: | Height: | Size: 246 B |
|
After Width: | Height: | Size: 267 B |
|
After Width: | Height: | Size: 286 B |
|
After Width: | Height: | Size: 257 B |
|
After Width: | Height: | Size: 263 B |
|
After Width: | Height: | Size: 261 B |
|
After Width: | Height: | Size: 252 B |
|
After Width: | Height: | Size: 276 B |
|
After Width: | Height: | Size: 205 B |
|
After Width: | Height: | Size: 199 B |
|
After Width: | Height: | Size: 198 B |
|
After Width: | Height: | Size: 203 B |
|
After Width: | Height: | Size: 200 B |
|
After Width: | Height: | Size: 204 B |
|
After Width: | Height: | Size: 201 B |
|
After Width: | Height: | Size: 203 B |
|
After Width: | Height: | Size: 202 B |
|
After Width: | Height: | Size: 204 B |
|
After Width: | Height: | Size: 200 B |
|
After Width: | Height: | Size: 204 B |
|
After Width: | Height: | Size: 201 B |
|
After Width: | Height: | Size: 202 B |
|
After Width: | Height: | Size: 198 B |
|
After Width: | Height: | Size: 199 B |
|
After Width: | Height: | Size: 263 B |
|
After Width: | Height: | Size: 267 B |
|
After Width: | Height: | Size: 291 B |
|
After Width: | Height: | Size: 297 B |
|
After Width: | Height: | Size: 257 B |
|
After Width: | Height: | Size: 257 B |
|
After Width: | Height: | Size: 294 B |