Document and demonstrate prepared mesh LOD visibility
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
# GPU visibility and prepared mesh LOD
|
||||
|
||||
Faset can draw opaque static triangle meshes through GPU frustum culling and,
|
||||
optionally, two-pass HZB occlusion. The original direct renderer remains available
|
||||
for comparison. In the Editor, build with `FASET_DEBUG_IMGUI=ON`, press **F12**,
|
||||
and choose **Direct**, **GPU frustum**, or **GPU occlusion** in Diagnostics. **Path:
|
||||
active** confirms that the selected GPU path actually ran. See
|
||||
[developer diagnostics](diagnostics.md) for the HZB preview and counters.
|
||||
|
||||
The current GPU path groups instances with the same mesh and texture into fixed
|
||||
indirect draw bins. A previous-frame HZB can defer an object, but the current-frame
|
||||
post pass checks it again before the final image. Sprites, editor UI, transparent
|
||||
meshes, and shadow casters keep their existing ordered or shadow paths. This option
|
||||
does not require ray tracing or mesh shaders.
|
||||
|
||||
## Supply prepared LODs from C++
|
||||
|
||||
`DrawItem::mesh` is LOD 0. Set `lod_meshes[0]` to a prepared LOD 1 mesh,
|
||||
`lod_meshes[1]` to LOD 2, and so on. These are actual `Mesh` objects with a
|
||||
complete triangle list; Faset does not simplify a source mesh automatically.
|
||||
Keep a stable `instance_key` across frames. Give different scene objects different
|
||||
keys, and retain the same shared mesh objects instead of rebuilding them every
|
||||
frame. For a manually constructed `Snapshot`, supply both `projection` and
|
||||
`view_projection`; set `view_id` for each camera and `camera_cut` when switching
|
||||
shots. The Player's scene extraction fills the camera fields and instance keys.
|
||||
|
||||
```cpp
|
||||
faset::render::DrawItem draw;
|
||||
draw.mesh = prepared_high_detail;
|
||||
draw.lod_meshes = {prepared_medium_detail, prepared_low_detail};
|
||||
draw.instance_key = "scene/object-id/primitive-id";
|
||||
draw.model = faset::render::transform({0, 0, 0});
|
||||
snapshot.draws.push_back(std::move(draw));
|
||||
```
|
||||
|
||||
LOD selection uses projected screen size. The first transition is 192 pixels;
|
||||
each additional level halves that threshold. A 12% hysteresis band avoids
|
||||
switching back and forth near a boundary. Missing levels fall back to an available
|
||||
mesh. Changing level invalidates that instance's temporal occlusion state while
|
||||
preserving its logical key. `FrameStats::lod_counts` reports selected levels 0–3
|
||||
(higher levels are included in the final bucket).
|
||||
|
||||
For a runnable C++ example, build `faset_p2_visibility_example` and capture the
|
||||
same scene in any mode:
|
||||
|
||||
```sh
|
||||
cmake --build --preset linux-debug --target faset_p2_visibility_example
|
||||
build/linux-debug/faset_p2_visibility_example occlusion /tmp/p2-visibility.ppm
|
||||
build/linux-debug/faset_p2_visibility_example direct /tmp/p2-direct.ppm
|
||||
```
|
||||
|
||||
The example creates a fine cube and a prepared coarse tetrahedron in
|
||||
[`examples/renderer/p2_visibility.cpp`](https://github.com/emil28092005/Faset_Engine/blob/main/examples/renderer/p2_visibility.cpp).
|
||||
Imported GLB geometry can be supplied as prepared levels by C++ integration,
|
||||
but automatic LOD generation and assigning a GLB's alternate meshes as LODs in
|
||||
the Inspector are not implemented yet.
|
||||
|
||||
## Measure before choosing a mode
|
||||
|
||||
The GPU route saves per-instance CPU vertex transformation and direct draw
|
||||
submission, but its compute passes and indirect rendering have a cost. Keep the
|
||||
same scene, resolution and camera path when comparing modes. Hide Diagnostics for
|
||||
an ordinary Player measurement: opening it enables GPU counter readback, while
|
||||
**Show HZB** adds a separate image copy. The renderer currently captures and
|
||||
waits for every frame even without this overlay. Read
|
||||
[profiling and measurements](profiling.md) and the
|
||||
[P2 acceptance study](https://github.com/emil28092005/Faset_Engine/blob/main/docs/studies/19-p2-gpu-visibility-acceptance.md)
|
||||
for the measured scope and limitations.
|
||||
Reference in New Issue
Block a user