Checkpoint WebGL procedural book lab

This commit is contained in:
2026-06-05 22:51:30 +02:00
parent 80d29ed2d2
commit ca38f9ce92
5 changed files with 2004 additions and 213 deletions
+167 -90
View File
@@ -6,10 +6,49 @@ This document captures the agreed direction for the WebGL book UI. Later decisio
Build a beautiful, readable, extensible WebGL book interface for the interactive fiction UI.
The first stable milestone is a standalone 3D scene: an open book lying correctly on a polished wooden table, lit only by flickering candles, with the two existing application pages rendered as crisp dynamic textures on the actual book pages.
The current stable milestone is `public/webgl-book-lab.html`: an open procedural book lying on a polished wooden table, lit by flickering candles, with the existing application page content rendered into textures that are applied to the actual top surfaces of the paper stacks.
The later product goal is a procedural book UI that supports virtual scrolling, animated page flips, dynamic page stacks, and content backfilling across spreads.
## Current Implementation Snapshot
This section records the current state after the procedural book integration work.
- The active standalone scene is `public/webgl-book-lab.html`.
- The intended local test URL is `http://localhost:3001/webgl-book-lab.html`.
- The current test server is expected to be the single Node process listening on port `3001`.
- The procedural book model lives in `public/js/procedural-book-model.js`.
- The WebGL lab integration lives in `public/js/webgl-book-lab.js`.
- The old fixed-box book has been removed from the lab scene.
- The new procedural book is generated from fixed page dimensions, a calculated spine arc, cover panels, hinge panels, page-stack spline lines, stack bodies, and animated flipping page geometry.
- Book page count is clamped to 40-500 pages.
- Page count changes in 10-page bundle increments.
- Each visible bundle line represents 10 pages.
- Reading progress controls the left/right split of page bundles along the spine arc.
- The spine grows with page count and pushes the covers outward; the covers do not shrink to pay for spine growth.
- `PAGE_SPLINE_LENGTH` must match `PAGE_WIDTH`.
- Cover width is derived from page width plus cover overhang.
- The spine bottom is aligned to the table plane with only a tiny render clearance.
- The book controls are in the top bar: fast backward, backward, progress slider, page-count slider, forward, and fast forward.
- Slow page flips and fast 10-page transitions are implemented.
- Fast transitions run overlapping flip animations before shifting the book by one bundle.
- The readable page content belongs on the visible top cap of the paper stacks.
- No separate floating reading-surface overlay should be added on top of the stack cap.
- Extreme progress states must use the same top-cap/material topology as normal stack states.
- Synthetic hair/support pages used for empty-side extremes must not receive page content if they are not the actual readable stack top.
- The spine arc and cloth spine must not receive page-content textures.
- Page-content textures are high-resolution canvas textures with hardcover-style margins.
- The current page canvases are deliberately smoother than the old noisy page texture.
- Page-stack side lines are generated as textures, not as free-standing line meshes.
- Stack side textures should have consistent orientation and line count on all visible stack sides.
- Cover, hinge, spine base, and cover edge materials use leather-style materials with procedural leather color and normal maps.
- The book, table, candles, and flipping pages have `castShadow` and `receiveShadow` disabled.
- Three.js/OpenGL primitive shadows must stay disabled.
- Candle shadows are implemented in the custom table/book shader path, not through Three.js shadow maps.
- Scene SSAO is present as a postprocessing pass, but the procedural book and flip page are currently excluded from that AO pass because the previous AO interaction caused misleading/inset visual artifacts.
- The table reflection path remains active and should include the book and candles.
- Temporary screenshots and generated debug images are not product assets unless explicitly promoted.
## Non-Negotiable Workflow Rules
- Do not continue visual coding without a concrete plan for the current sprint.
@@ -26,6 +65,10 @@ The later product goal is a procedural book UI that supports virtual scrolling,
- Do not introduce fallback visual cheats when the agreed task fails. If the real technique is not working, stop, document the failure, and investigate the real technique.
- Do not let a fallback or diagnostic layer become part of the final composite unless it is explicitly approved as a permanent art-direction layer.
- When screenshot capture fails, fix the capture/test tooling before continuing visual iteration.
- Do not enable `renderer.shadowMap.enabled`.
- Do not set any mesh `castShadow` or `receiveShadow` flag to `true`.
- Do not use Three.js primitive shadow maps as a fallback for candle shadows.
- Candle shadows must remain a custom shader responsibility.
## Repository And Branch Rules
@@ -68,6 +111,18 @@ During visual development:
- Text must be crisp enough for reading.
- Page texture resolution must be high enough that the projected text remains crisp at intended camera distances.
- The old UI/html creation module must be kept for reference while the new module replaces it.
- The open book is made from named parts:
- Spine: the central cloth/red arc and supporting center area.
- Hinge: the angled transition from spine top height to cover/table height.
- Cover: the main leather cover panel that supports each page stack.
- Cover overhang: the small cover border extending beyond the paper stack.
- The hinge width is the width required to descend from spine-top height to spine-bottom/table height at the chosen 45 degree hinge angle.
- The cover starts at spine-top height near the hinge and descends until its outer edge touches the table.
- The cover must extend under the page stack by the same overhang along book width as along book depth.
- The paper stack must have closed bottom geometry where needed; it must not reveal empty inside faces from below.
- The paper stack top is the readable content surface.
- At progress `0.00`, `0.03`, `0.07`, and other extreme values, the surface topology and material assignment must remain consistent.
- The right page must not become a different material or broken cap merely because the left side has no full stack yet.
### Later Product Goal
@@ -90,11 +145,23 @@ The book should become a dynamic procedural object:
- Page content must be rendered into textures applied to the actual page geometry.
- No separate reading-surface overlay on top of the book model.
- The visible top cap of the paper stack is the page display surface.
- Do not add a coincident floating page mesh over the stack cap to display content; that creates z-fighting risk and violates the intended architecture.
- If the page content is wrong at an extreme progress state, fix the stack-cap topology or material assignment, not by adding a second page surface.
- The left page texture must contain the full left page of the old layout.
- The right page texture must contain the dynamic typeset text from the original module.
- Text and lines must respect the original page proportions.
- Texture capture/generation must not silently crop the content.
- The page texture pipeline must support future virtualized content.
- Page content should use typical hardcover novel margins:
- Larger inner/gutter margin.
- Smaller outer margin.
- Comfortable top margin.
- Larger bottom margin.
- The DOM/canvas source used for page content must have the same aspect ratio and orientation as the physical page surface.
- Page textures must be smooth enough that projected content does not reveal unwanted construction lines, stack lines, or noisy paper grain.
- Neutral paper texture and content-page texture should have compatible filtering, mipmapping, and anisotropy.
- Spine arc, hinge, cloth, and support-strip materials must not accidentally receive page-content texture.
## Camera Requirements
@@ -191,15 +258,15 @@ Wax shader:
## Shadow Requirements
This is currently a regression area. The candle shadow system was previously better, and it must be treated as a locked baseline unless a specific shadow-restoration sprint is active.
This project does not use Three.js/OpenGL primitive shadow maps for the book, table, or candles. Shadows are owned by the custom shader pipeline.
Required behavior:
- Candle cast shadows must exist in the final composite.
- The previous working candle shadow behavior must be restored.
- All three candle bodies must cast visible shadows.
- All three candle light/flame positions must participate.
- The book must cast shadows onto the table from all three candles.
- The paper stacks, visible page tops, covers, hinges, spine, candles, wax bodies, and table must use the custom shader lighting/shadow path where relevant.
- The candle shadows must respect wax translucency conceptually: wax transmission should soften/reduce the shadow rather than creating hard opaque cylinder shadows.
- Shadows should be soft and believable, not hard-edged cones or arbitrary blobs.
- Shadows must move subtly with the animated flame/light positions.
@@ -207,6 +274,8 @@ Required behavior:
- Reflections are not a substitute for candle cast shadows.
- SSAO is not a substitute for candle cast shadows.
- Candle shadows must not be weakened, removed, or repurposed while working on SSAO.
- `renderer.shadowMap.enabled` must stay `false`.
- `castShadow` and `receiveShadow` must stay `false` on scene meshes.
Debug proof:
@@ -217,10 +286,8 @@ Debug proof:
Implementation note:
- The prior candle shadow behavior was lost during SSAO/compositing work.
- The shadow debug view was not literally repurposed to show contact AO, but contact AO was incorrectly used as evidence of scene grounding while the real shadow regression remained unresolved.
- `tableDebug=shadow` must remain dedicated to candle cast-shadow proof.
- If SSAO conflicts with existing cast shadows, SSAO loses until it is redesigned.
- If SSAO conflicts with custom candle shadows or page readability, SSAO loses until it is redesigned.
## Ambient Occlusion Requirements
@@ -240,12 +307,11 @@ Required behavior:
Current status:
- Scene-level SSAO has been added but is visually weak.
- The visible candle-bottom effect is currently analytic table-shader contact AO. This is a failed fallback, not an accepted feature.
- SSAO is not yet good enough to be considered the solved AO system.
- `tableDebug=ao` currently proves only that a Three.js `SSAOPass` is wired. It does not prove useful visual AO.
- The SSAO attempt has not yet produced a meaningful composite result.
- The analytic contact fallback confused the evaluation and must be removed so SSAO can be judged honestly.
- Scene-level SSAO has been added as a Three.js `SSAOPass`.
- Flames and glow sprites are excluded from AO.
- The procedural book and animated flip page are currently excluded from AO because the previous AO interaction made the book look inset/incorrect and excluded the top page from the effect.
- `tableDebug=ao` proves the pass is wired, but the current AO result is not the accepted final AO design.
- AO work is paused until the book material/topology integration is stable.
Debug proof:
@@ -320,7 +386,7 @@ The standalone scene should support debug query modes:
Deprecated:
- `tableDebug=contact`: analytic contact fallback diagnostic. This must be removed with the fallback contact layer unless explicitly retained as a temporary cleanup check.
- `tableDebug=contact`: removed/deprecated. It must not return as a final-composite fallback.
Debug views must be visually meaningful. A debug view that is too subtle to interpret is not useful proof.
@@ -354,54 +420,85 @@ Screenshot tooling:
4. Preserve unrelated `.env` changes unstaged.
5. Remove or ignore temporary screenshot files unless needed for explicit review.
### Phase 1: Remove The Analytic Contact Fallback
### Phase 1: Procedural Book Integration
Goal: remove the fallback contact-shadow/contact-AO cheat so the scene can be evaluated honestly.
Goal: replace the old fixed-box book in `webgl-book-lab.html` with the procedural book model while preserving candle lighting, table reflection, and shader-owned shadows.
Steps:
1. Remove analytic contact darkening from the final table composite.
2. Remove `surfaceContactOcclusion`, `candleContact`, and `candleFootOcclusion` from the final image unless they are only part of a temporary diagnostic that does not affect normal rendering.
3. Remove or clearly deprecate `tableDebug=contact`.
4. Confirm `tableDebug=shadow` still shows only candle cast shadows.
5. Confirm `tableDebug=ao` still shows only scene-level SSAO.
6. Capture before/after screenshots proving the fallback was removed.
7. Run checks and build.
Acceptance criteria:
- The normal composite no longer contains analytic contact fallback darkening.
- Contact darkening is not used as a substitute for SSAO or cast shadows.
- Any remaining grounding must come from real shadows, real SSAO, or accepted reflection/lighting behavior.
- Debug modes are no longer ambiguous.
### Phase 2: Restore And Protect Candle Cast Shadows
Goal: restore the candle shadows that were working before SSAO work.
Steps:
1. Inspect the last known good candle-shadow checkpoint.
2. Identify exactly which changes removed or masked candle shadows.
3. Restore shadow contribution without disturbing accepted table dust/grease/reflection work.
4. Verify whether `tableMesh.receiveShadow = false` is still valid. If primitive shadow receiving was part of the working candle shadows, restore it or provide a proven shader replacement.
5. Verify whether candle wax meshes need to cast primitive shadows or whether analytic shader shadows fully replace them.
6. Ensure all three candle flame positions and all three candle bodies are included.
7. Ensure the book participates in candle shadows.
8. Use `tableDebug=shadow` to prove the shadow field.
9. Use the normal composite to prove shadows are visible.
1. Import `createProceduralBookModel` into the WebGL lab.
2. Place the procedural book so the spine bottom touches the table plane with minimal render clearance.
3. Add top-bar controls for progress, page count, backward, forward, fast backward, and fast forward.
4. Keep all book parts participating in custom candle shader lighting.
5. Keep all Three.js primitive shadow flags disabled.
6. Preserve table reflection and candle rendering.
7. Ensure the right page/top cap is present at all progress values.
8. Ensure the readable page content projects onto the stack top cap.
9. Ensure spine arc/support/cloth materials do not receive page content.
10. Run checks and build.
11. Commit only after visual proof.
Acceptance criteria:
- All three candles cast visible shadows.
- Shadows are visible in final composite.
- Shadows are soft, not hard black cones.
- No analytic contact fallback is used to fake shadows.
- Reflections, dust, grease, normal map, and page textures remain intact.
- The old book is gone from the lab scene.
- The procedural book is visible, correctly placed on the table, and controllable.
- Top page content appears on the actual stack top, not on a hovering overlay.
- Extreme progress values render with the same topology/material rules as normal values.
- No OpenGL shadow flags are enabled.
### Phase 3: Implement True SSAO
### Phase 2: Procedural Book Geometry And Solver
Goal: keep the book shape physically plausible and stable across progress/page-count values.
Steps:
1. Keep page width, page depth, and page spline length consistent.
2. Use deterministic line generation for page splines.
3. Keep fixed segment lengths whose sum equals page width.
4. Use shorter page-line segments near the spine and longer segments toward the page edge.
5. Make every line follow the closest legal underlying layer:
- First layer follows spine/hinge/cover profile and may touch it.
- Later layers follow the paper line below and keep one bundle spacing.
6. Keep the spine arc spacing proportional to page bundle count.
7. Keep the spine as small as needed for 40 pages and as large as needed up to the capped maximum.
8. Keep page count capped at 500 pages.
9. Keep cover width independent of spine growth.
10. Ensure stack bodies have closed sides, bottom where needed, and correct top cap normals.
Acceptance criteria:
- Left and right cover lengths remain the same even when stack sizes differ.
- Page widths remain the same on thick and thin stacks.
- No final line segment runs backward.
- The top caps face outward/upward and light correctly.
- The first and last page states remain valid.
- No stack body exposes an unintended hollow interior.
### Phase 3: Page Content And Materials
Goal: make the book read as a real leather-bound book with readable page content.
Steps:
1. Generate page canvas textures at the correct page aspect ratio.
2. Use hardcover-style margins.
3. Keep page content on stack top caps.
4. Keep neutral paper and content page textures smooth and consistently filtered.
5. Generate stack side lines as textures.
6. Keep stack side texture orientation consistent across front, back, left, and right sides.
7. Use procedural leather color and normal maps for cover, hinge, spine base, and cover edge.
8. Round the edge impression of cover panels without introducing open faces.
9. Verify cover, hinge, spine base, cover edge, paper side, paper top, and cloth spine material groups.
Acceptance criteria:
- Page content is readable and correctly oriented.
- Stack side lines are not free-standing meshes.
- Stack side lines meet at corners without visible mismatch.
- The visible page surface is smooth and does not reveal construction-line artifacts.
- Leather parts look like real cover geometry, not flat orange planes.
- Cloth spine remains visually distinct from leather cover parts.
### Phase 4: True SSAO Revisit
Goal: understand, fix, and complete real scene-level SSAO.
@@ -427,7 +524,7 @@ Acceptance criteria:
- AO does not replace cast shadows.
- No fallback contact darkening remains in the final composite.
### Phase 4: Reflection And Compositing Cleanup
### Phase 5: Reflection And Compositing Cleanup
Goal: make the table reflection physically coherent.
@@ -448,26 +545,6 @@ Acceptance criteria:
- Flame reflection does not appear as an impossible unoccluded blob.
- Table wood remains visible.
### Phase 5: Page Texture Quality
Goal: make the book usable as an actual reading UI.
Steps:
1. Audit old layout page dimensions.
2. Create high-resolution page texture canvases.
3. Render left and right old-layout content into those textures.
4. Preserve text orientation and aspect ratio.
5. Verify crispness at default and close camera distances.
6. Add debug/export view for page textures.
Acceptance criteria:
- Text is crisp.
- Left and right pages match old layout content and proportions.
- No mirrored or rotated page.
- No overlay reading surface.
### Phase 6: Integration Back Into App Shell
Goal: connect the standalone scene back to the real app.
@@ -511,25 +588,25 @@ Acceptance criteria:
## Current Known Problems
- Candle cast shadows are missing/regressed.
- Scene-level SSAO is visually weak.
- Analytic candle/book contact darkening exists as a fallback cheat and must be removed.
- Candle contact AO is not a substitute for shadows or true SSAO.
- The current shadow/composite path must be repaired before further visual polish.
- Reflection and dust/grease work are acceptable enough to preserve while fixing shadows.
- Screenshot capture can stall at large viewport sizes; current reliable method uses smaller viewport and explicit screenshot timeout.
- The current extreme-progress rendering still needs user screenshot validation after the latest stack-cap material and cap-winding fixes.
- The page-content texture must not appear on the spine arc or synthetic support strip.
- At `0.00` and very early progress, the side with no real stack must still render with the same topology/material rules as later states.
- The current content page surface should stay smooth; construction lines from stack textures must not appear on readable content.
- Leather material quality is still provisional and may need further art-direction tuning.
- Scene-level SSAO is not accepted as final and is currently not allowed to drive book appearance.
- The table reflection path is active and should not be disabled to hide book/cover problems.
- Two pathless Windows Node processes may resist termination with access denied; they are not the `:3001` server.
## Next Immediate Task
Remove the analytic contact fallback completely, then investigate and fix true SSAO.
Validate the latest procedural-book integration visually in the running `:3001` lab scene, especially the extreme progress states.
No other visual topic should be started until the following are true:
The next visual work should focus on the book material/topology issues in this order:
- The final composite no longer uses analytic contact fallback darkening.
- `tableDebug=contact` is removed or explicitly marked deprecated and disconnected from the final composite.
- `tableDebug=ao` is understood, documented, and made visually meaningful.
- The cause of the weak SSAO output is identified before intensity tuning.
- Any SSAO fix is proven in both debug and final composite.
- Existing candle shadows are not weakened or repurposed during SSAO work.
- Static checks and build pass.
- No orphaned processes remain.
1. Confirm that content appears only on the intended stack-top page surfaces.
2. Confirm that spine arc, hinge, cloth, and support strips do not receive page-content texture.
3. Confirm that the right stack has a valid top cap even when the left side has no full stack.
4. Confirm that readable page surfaces are smooth and not showing construction-line artifacts.
5. Continue cover/hinge/spine leather material refinement only after the page-top topology is stable.
6. Keep `:3001` as the single current test server.
7. Keep OpenGL primitive shadows disabled.