diff options
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/COMPLETED.md | 27 | ||||
| -rw-r--r-- | doc/HOWTO.md | 38 | ||||
| -rw-r--r-- | doc/MASKING_SYSTEM.md | 240 | ||||
| -rw-r--r-- | doc/archive/ANALYSIS_VARIABLE_TEMPO.md (renamed from doc/ANALYSIS_VARIABLE_TEMPO.md) | 0 | ||||
| -rw-r--r-- | doc/archive/ANALYSIS_VARIABLE_TEMPO_V2.md (renamed from doc/ANALYSIS_VARIABLE_TEMPO_V2.md) | 0 | ||||
| -rw-r--r-- | doc/archive/AUDIO_LIFECYCLE_REFACTOR.md (renamed from doc/AUDIO_LIFECYCLE_REFACTOR.md) | 0 | ||||
| -rw-r--r-- | doc/archive/AUDIO_TIMING_ARCHITECTURE.md (renamed from doc/AUDIO_TIMING_ARCHITECTURE.md) | 0 | ||||
| -rw-r--r-- | doc/archive/BUILD_OPTIMIZATION_PROPOSAL.md (renamed from doc/BUILD_OPTIMIZATION_PROPOSAL.md) | 0 | ||||
| -rw-r--r-- | doc/archive/BUILD_OPTIMIZATION_PROPOSAL_V2.md (renamed from doc/BUILD_OPTIMIZATION_PROPOSAL_V2.md) | 0 | ||||
| -rw-r--r-- | doc/archive/DEBUG_SHADOWS.md (renamed from doc/DEBUG_SHADOWS.md) | 0 | ||||
| -rw-r--r-- | doc/archive/FINAL_STRIP_REPORT.md (renamed from doc/FINAL_STRIP_REPORT.md) | 0 | ||||
| -rw-r--r-- | doc/archive/GPU_EFFECTS_TEST_ANALYSIS.md (renamed from doc/GPU_EFFECTS_TEST_ANALYSIS.md) | 0 | ||||
| -rw-r--r-- | doc/archive/HANDOFF.md (renamed from doc/HANDOFF.md) | 0 | ||||
| -rw-r--r-- | doc/archive/HANDOFF_2026-02-04.md (renamed from doc/HANDOFF_2026-02-04.md) | 0 | ||||
| -rw-r--r-- | doc/archive/HANDOFF_2026-02-08.md (renamed from doc/HANDOFF_2026-02-08.md) | 0 | ||||
| -rw-r--r-- | doc/archive/HANDOFF_CLAUDE.md (renamed from doc/HANDOFF_CLAUDE.md) | 0 | ||||
| -rw-r--r-- | doc/archive/HANDOFF_SCENE_LOADER.md (renamed from doc/HANDOFF_SCENE_LOADER.md) | 0 | ||||
| -rw-r--r-- | doc/archive/HANDOFF_SPECTRAL_EDITOR.md (renamed from doc/HANDOFF_SPECTRAL_EDITOR.md) | 0 | ||||
| -rw-r--r-- | doc/archive/PEAK_FIX_SUMMARY.md (renamed from doc/PEAK_FIX_SUMMARY.md) | 0 | ||||
| -rw-r--r-- | doc/archive/PEAK_METER_DEBUG.md (renamed from doc/PEAK_METER_DEBUG.md) | 0 | ||||
| -rw-r--r-- | doc/archive/PHASE2_COMPRESSION.md (renamed from doc/PHASE2_COMPRESSION.md) | 0 | ||||
| -rw-r--r-- | doc/archive/PLATFORM_ANALYSIS.md (renamed from doc/PLATFORM_ANALYSIS.md) | 0 | ||||
| -rw-r--r-- | doc/archive/PLATFORM_SIDE_QUEST_SUMMARY.md (renamed from doc/PLATFORM_SIDE_QUEST_SUMMARY.md) | 0 | ||||
| -rw-r--r-- | doc/archive/SAMPLE_ACCURATE_TIMING_FIX.md (renamed from doc/SAMPLE_ACCURATE_TIMING_FIX.md) | 0 | ||||
| -rw-r--r-- | doc/archive/SHADER_PARAMETRIZATION_PLAN.md (renamed from doc/SHADER_PARAMETRIZATION_PLAN.md) | 0 | ||||
| -rw-r--r-- | doc/archive/SPEC_EDITOR.md (renamed from doc/SPEC_EDITOR.md) | 0 | ||||
| -rw-r--r-- | doc/archive/STRIPPING.md (renamed from doc/STRIPPING.md) | 0 | ||||
| -rw-r--r-- | doc/archive/TASKS_SUMMARY.md (renamed from doc/TASKS_SUMMARY.md) | 0 | ||||
| -rw-r--r-- | doc/archive/VISUAL_DEBUG.md (renamed from doc/VISUAL_DEBUG.md) | 0 |
29 files changed, 305 insertions, 0 deletions
diff --git a/doc/COMPLETED.md b/doc/COMPLETED.md index a4e6a94..a3c173d 100644 --- a/doc/COMPLETED.md +++ b/doc/COMPLETED.md @@ -2,6 +2,33 @@ This file tracks recently completed tasks, organized by completion date. +## Archive Index + +Detailed historical documents have been moved to `doc/archive/` for reference: + +**Analysis & Architecture:** +- ANALYSIS_VARIABLE_TEMPO.md, ANALYSIS_VARIABLE_TEMPO_V2.md +- AUDIO_LIFECYCLE_REFACTOR.md, AUDIO_TIMING_ARCHITECTURE.md +- BUILD_OPTIMIZATION_PROPOSAL.md, BUILD_OPTIMIZATION_PROPOSAL_V2.md +- PLATFORM_ANALYSIS.md, SHADER_PARAMETRIZATION_PLAN.md + +**Handoffs & Summaries:** +- HANDOFF.md, HANDOFF_2026-02-04.md, HANDOFF_2026-02-08.md, HANDOFF_CLAUDE.md +- HANDOFF_SCENE_LOADER.md, HANDOFF_SPECTRAL_EDITOR.md +- PLATFORM_SIDE_QUEST_SUMMARY.md, TASKS_SUMMARY.md + +**Debug Reports:** +- DEBUG_SHADOWS.md, PEAK_FIX_SUMMARY.md, PEAK_METER_DEBUG.md +- SAMPLE_ACCURATE_TIMING_FIX.md, VISUAL_DEBUG.md + +**Testing & Reports:** +- FINAL_STRIP_REPORT.md, GPU_EFFECTS_TEST_ANALYSIS.md + +**Planning Docs:** +- PHASE2_COMPRESSION.md, SPEC_EDITOR.md, STRIPPING.md + +Use `read @doc/archive/FILENAME.md` to access archived documents. + ## Recently Completed (February 8, 2026) - [x] **Shader Parametrization System (Task #73 Phase 0)** (February 8, 2026) diff --git a/doc/HOWTO.md b/doc/HOWTO.md index 3a1aee2..55580ba 100644 --- a/doc/HOWTO.md +++ b/doc/HOWTO.md @@ -158,6 +158,44 @@ void test_example() { For low-level synth-only tests, you can still call `synth_init()` directly. +## Auxiliary Texture Masking + +The project supports inter-effect texture sharing via the auxiliary texture registry. This allows effects to generate textures (masks, shadow maps, etc.) and make them available to other effects within the same frame. + +**Common use case:** Screen-space partitioning where different scenes render to complementary regions. + +```cpp +class MaskGeneratorEffect : public Effect { + void init(MainSequence* demo) override { + demo_ = demo; + // Register a named auxiliary texture + demo->register_auxiliary_texture("my_mask", width_, height_); + } + + void compute(WGPUCommandEncoder encoder, ...) override { + // Generate mask to auxiliary texture + WGPUTextureView mask_view = demo_->get_auxiliary_view("my_mask"); + // ... render mask + } + + void render(WGPURenderPassEncoder pass, ...) override { + // Use mask in scene rendering + WGPUTextureView mask_view = demo_->get_auxiliary_view("my_mask"); + // ... render scene with mask + } +}; + +class MaskUserEffect : public Effect { + void render(WGPURenderPassEncoder pass, ...) override { + // Reuse mask from MaskGeneratorEffect + WGPUTextureView mask_view = demo_->get_auxiliary_view("my_mask"); + // ... render scene with inverted mask + } +}; +``` + +See `doc/MASKING_SYSTEM.md` for detailed architecture and examples. + ## Debugging ### Seeking / Fast-Forward diff --git a/doc/MASKING_SYSTEM.md b/doc/MASKING_SYSTEM.md new file mode 100644 index 0000000..d468d48 --- /dev/null +++ b/doc/MASKING_SYSTEM.md @@ -0,0 +1,240 @@ +# Auxiliary Texture Masking System + +## Overview + +The auxiliary texture masking system allows effects to share textures within a single frame render. Primary use case: **screen-space partitioning** where multiple effects render to complementary regions of the framebuffer. + +## Use Case + +**Problem:** Render two different 3D scenes to different regions of the screen (split-screen, portals, picture-in-picture). + +**Solution:** +- Effect1 generates a mask (1 = Effect1's region, 0 = Effect2's region) +- Effect1 renders scene A where mask = 1 +- Effect2 reuses the mask and renders scene B where mask = 0 +- Both render to the same framebuffer in the same frame + +## Architecture Choice: Mask Texture vs Stencil Buffer + +### Option 1: Stencil Buffer (NOT CHOSEN) +**Pros:** Hardware-accelerated, fast early-rejection +**Cons:** 8-bit limitation, complex pipeline config, hard to debug + +### Option 2: Mask Texture (CHOSEN) +**Pros:** +- Flexible (soft edges, gradients, any format) +- Debuggable (visualize mask as texture) +- Reusable (multiple effects can read same mask) +- Simple pipeline setup + +**Cons:** +- Requires auxiliary texture (~4 MB for 1280x720 RGBA8) +- Fragment shader discard (slightly slower than stencil) + +**Verdict:** Mask texture flexibility and debuggability outweigh performance cost. + +## Implementation + +### MainSequence Auxiliary Texture Registry + +```cpp +class MainSequence { + public: + // Register a named auxiliary texture (call once in effect init) + void register_auxiliary_texture(const char* name, int width, int height); + + // Get texture view for reading/writing (call every frame) + WGPUTextureView get_auxiliary_view(const char* name); + + private: + struct AuxiliaryTexture { + WGPUTexture texture; + WGPUTextureView view; + int width, height; + }; + std::map<std::string, AuxiliaryTexture> auxiliary_textures_; +}; +``` + +### Effect Lifecycle + +``` +Init Phase (once): + Effect1.init(): register_auxiliary_texture("mask_1", width, height) + Effect2.init(): (no registration - reuses Effect1's mask) + +Compute Phase (every frame): + Effect1.compute(): Generate mask to get_auxiliary_view("mask_1") + +Scene Pass (every frame, shared render pass): + Effect1.render(): Sample mask, discard if < 0.5, render scene A + Effect2.render(): Sample mask, discard if > 0.5, render scene B +``` + +### Render Flow Diagram + +``` +Frame N: +┌───────────────────────────────────────────────────────────┐ +│ Compute Phase: │ +│ Effect1.compute() │ +│ └─ Generate mask → auxiliary_textures_["mask_1"] │ +│ │ +├───────────────────────────────────────────────────────────┤ +│ Scene Pass (all effects share framebuffer A + depth): │ +│ Effect1.render() [priority 5] │ +│ ├─ Sample auxiliary_textures_["mask_1"] │ +│ ├─ Discard fragments where mask < 0.5 │ +│ └─ Render 3D scene A → framebuffer A │ +│ │ +│ Effect2.render() [priority 10] │ +│ ├─ Sample auxiliary_textures_["mask_1"] │ +│ ├─ Discard fragments where mask > 0.5 │ +│ └─ Render 3D scene B → framebuffer A │ +│ │ +│ Result: framebuffer A contains both scenes, partitioned │ +├───────────────────────────────────────────────────────────┤ +│ Post-Process Chain: │ +│ A ⟷ B ⟷ Screen │ +└───────────────────────────────────────────────────────────┘ +``` + +## Example: Circular Portal Effect + +### Effect1: Render Scene A (inside portal) + +```cpp +class PortalSceneEffect : public Effect { + public: + PortalSceneEffect(const GpuContext& ctx) : Effect(ctx) {} + + void init(MainSequence* demo) override { + demo_ = demo; + demo->register_auxiliary_texture("portal_mask", width_, height_); + // ... create pipelines + } + + void compute(WGPUCommandEncoder encoder, ...) override { + // Generate circular mask (portal region) + WGPUTextureView mask_view = demo_->get_auxiliary_view("portal_mask"); + // ... render fullscreen quad with circular mask shader + } + + void render(WGPURenderPassEncoder pass, ...) override { + // Render 3D scene, discard outside portal + WGPUTextureView mask_view = demo_->get_auxiliary_view("portal_mask"); + // ... bind mask, render scene with mask test + } +}; +``` + +### Effect2: Render Scene B (outside portal) + +```cpp +class OutsideSceneEffect : public Effect { + public: + OutsideSceneEffect(const GpuContext& ctx) : Effect(ctx) {} + + void init(MainSequence* demo) override { + demo_ = demo; + // Don't register - reuse PortalSceneEffect's mask + } + + void render(WGPURenderPassEncoder pass, ...) override { + // Render 3D scene, discard inside portal + WGPUTextureView mask_view = demo_->get_auxiliary_view("portal_mask"); + // ... bind mask, render scene with inverted mask test + } +}; +``` + +### Mask Generation Shader + +```wgsl +// portal_mask.wgsl +@group(0) @binding(0) var<uniform> uniforms: MaskUniforms; + +@fragment fn fs_main(@builtin(position) p: vec4<f32>) -> @location(0) vec4<f32> { + let uv = p.xy / uniforms.resolution; + let center = vec2<f32>(0.5, 0.5); + let radius = 0.3; + + let dist = length(uv - center); + let mask = f32(dist < radius); // 1.0 inside circle, 0.0 outside + + return vec4<f32>(mask, mask, mask, 1.0); +} +``` + +### Scene Rendering with Mask + +```wgsl +// scene_with_mask.wgsl +@group(0) @binding(2) var mask_sampler: sampler; +@group(0) @binding(3) var mask_texture: texture_2d<f32>; + +@fragment fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> { + // Sample mask + let screen_uv = in.position.xy / uniforms.resolution; + let mask_value = textureSample(mask_texture, mask_sampler, screen_uv).r; + + // Effect1: Discard outside portal (mask = 0) + if (mask_value < 0.5) { + discard; + } + + // Effect2: Invert test - discard inside portal (mask = 1) + // if (mask_value > 0.5) { discard; } + + // Render scene + return compute_scene_color(in); +} +``` + +## Memory Impact + +Each auxiliary texture: **width × height × 4 bytes** +- 1280×720 RGBA8: ~3.7 MB +- 1920×1080 RGBA8: ~8.3 MB + +For 2-3 masks: 10-25 MB total (acceptable overhead). + +## Use Cases + +1. **Split-screen**: Vertical/horizontal partition +2. **Portals**: Circular/arbitrary shape windows to other scenes +3. **Picture-in-picture**: Small viewport in corner +4. **Masked transitions**: Wipe effects between scenes +5. **Shadow maps**: Pre-generated in compute, used in render +6. **Reflection probes**: Generated once, reused by multiple objects + +## Alternatives Considered + +### Effect-Owned Texture (No MainSequence changes) +```cpp +auto effect1 = std::make_shared<Effect1>(...); +auto effect2 = std::make_shared<Effect2>(...); +effect2->set_mask_source(effect1->get_mask_view()); +``` + +**Pros:** No MainSequence changes +**Cons:** Manual wiring, effects coupled, less flexible + +**Verdict:** Not chosen. Registry approach is cleaner and more maintainable. + +## Future Extensions + +- **Multi-channel masks**: RGBA mask for 4 independent regions +- **Mipmap support**: For hierarchical queries +- **Compression**: Quantize masks to R8 (1 byte per pixel) +- **Enum-based lookup**: Replace string keys for size optimization + +## Size Impact + +- MainSequence changes: ~100 lines (~500 bytes code) +- std::map usage: ~1 KB overhead (low priority for CRT removal) +- Runtime memory: 4-8 MB per mask (acceptable) + +--- + +*Document created: February 8, 2026* diff --git a/doc/ANALYSIS_VARIABLE_TEMPO.md b/doc/archive/ANALYSIS_VARIABLE_TEMPO.md index f09996b..f09996b 100644 --- a/doc/ANALYSIS_VARIABLE_TEMPO.md +++ b/doc/archive/ANALYSIS_VARIABLE_TEMPO.md diff --git a/doc/ANALYSIS_VARIABLE_TEMPO_V2.md b/doc/archive/ANALYSIS_VARIABLE_TEMPO_V2.md index add347c..add347c 100644 --- a/doc/ANALYSIS_VARIABLE_TEMPO_V2.md +++ b/doc/archive/ANALYSIS_VARIABLE_TEMPO_V2.md diff --git a/doc/AUDIO_LIFECYCLE_REFACTOR.md b/doc/archive/AUDIO_LIFECYCLE_REFACTOR.md index f5e0045..f5e0045 100644 --- a/doc/AUDIO_LIFECYCLE_REFACTOR.md +++ b/doc/archive/AUDIO_LIFECYCLE_REFACTOR.md diff --git a/doc/AUDIO_TIMING_ARCHITECTURE.md b/doc/archive/AUDIO_TIMING_ARCHITECTURE.md index 7b125d0..7b125d0 100644 --- a/doc/AUDIO_TIMING_ARCHITECTURE.md +++ b/doc/archive/AUDIO_TIMING_ARCHITECTURE.md diff --git a/doc/BUILD_OPTIMIZATION_PROPOSAL.md b/doc/archive/BUILD_OPTIMIZATION_PROPOSAL.md index 8d61e10..8d61e10 100644 --- a/doc/BUILD_OPTIMIZATION_PROPOSAL.md +++ b/doc/archive/BUILD_OPTIMIZATION_PROPOSAL.md diff --git a/doc/BUILD_OPTIMIZATION_PROPOSAL_V2.md b/doc/archive/BUILD_OPTIMIZATION_PROPOSAL_V2.md index 315911a..315911a 100644 --- a/doc/BUILD_OPTIMIZATION_PROPOSAL_V2.md +++ b/doc/archive/BUILD_OPTIMIZATION_PROPOSAL_V2.md diff --git a/doc/DEBUG_SHADOWS.md b/doc/archive/DEBUG_SHADOWS.md index bcf6d3e..bcf6d3e 100644 --- a/doc/DEBUG_SHADOWS.md +++ b/doc/archive/DEBUG_SHADOWS.md diff --git a/doc/FINAL_STRIP_REPORT.md b/doc/archive/FINAL_STRIP_REPORT.md index 6ed1b43..6ed1b43 100644 --- a/doc/FINAL_STRIP_REPORT.md +++ b/doc/archive/FINAL_STRIP_REPORT.md diff --git a/doc/GPU_EFFECTS_TEST_ANALYSIS.md b/doc/archive/GPU_EFFECTS_TEST_ANALYSIS.md index 31399b5..31399b5 100644 --- a/doc/GPU_EFFECTS_TEST_ANALYSIS.md +++ b/doc/archive/GPU_EFFECTS_TEST_ANALYSIS.md diff --git a/doc/HANDOFF.md b/doc/archive/HANDOFF.md index bc22314..bc22314 100644 --- a/doc/HANDOFF.md +++ b/doc/archive/HANDOFF.md diff --git a/doc/HANDOFF_2026-02-04.md b/doc/archive/HANDOFF_2026-02-04.md index f38e5be..f38e5be 100644 --- a/doc/HANDOFF_2026-02-04.md +++ b/doc/archive/HANDOFF_2026-02-04.md diff --git a/doc/HANDOFF_2026-02-08.md b/doc/archive/HANDOFF_2026-02-08.md index f796f05..f796f05 100644 --- a/doc/HANDOFF_2026-02-08.md +++ b/doc/archive/HANDOFF_2026-02-08.md diff --git a/doc/HANDOFF_CLAUDE.md b/doc/archive/HANDOFF_CLAUDE.md index 24de0b1..24de0b1 100644 --- a/doc/HANDOFF_CLAUDE.md +++ b/doc/archive/HANDOFF_CLAUDE.md diff --git a/doc/HANDOFF_SCENE_LOADER.md b/doc/archive/HANDOFF_SCENE_LOADER.md index b218d0b..b218d0b 100644 --- a/doc/HANDOFF_SCENE_LOADER.md +++ b/doc/archive/HANDOFF_SCENE_LOADER.md diff --git a/doc/HANDOFF_SPECTRAL_EDITOR.md b/doc/archive/HANDOFF_SPECTRAL_EDITOR.md index 97d9f98..97d9f98 100644 --- a/doc/HANDOFF_SPECTRAL_EDITOR.md +++ b/doc/archive/HANDOFF_SPECTRAL_EDITOR.md diff --git a/doc/PEAK_FIX_SUMMARY.md b/doc/archive/PEAK_FIX_SUMMARY.md index cf42233..cf42233 100644 --- a/doc/PEAK_FIX_SUMMARY.md +++ b/doc/archive/PEAK_FIX_SUMMARY.md diff --git a/doc/PEAK_METER_DEBUG.md b/doc/archive/PEAK_METER_DEBUG.md index 002180c..002180c 100644 --- a/doc/PEAK_METER_DEBUG.md +++ b/doc/archive/PEAK_METER_DEBUG.md diff --git a/doc/PHASE2_COMPRESSION.md b/doc/archive/PHASE2_COMPRESSION.md index 3c83fa4..3c83fa4 100644 --- a/doc/PHASE2_COMPRESSION.md +++ b/doc/archive/PHASE2_COMPRESSION.md diff --git a/doc/PLATFORM_ANALYSIS.md b/doc/archive/PLATFORM_ANALYSIS.md index eefbd42..eefbd42 100644 --- a/doc/PLATFORM_ANALYSIS.md +++ b/doc/archive/PLATFORM_ANALYSIS.md diff --git a/doc/PLATFORM_SIDE_QUEST_SUMMARY.md b/doc/archive/PLATFORM_SIDE_QUEST_SUMMARY.md index d4be581..d4be581 100644 --- a/doc/PLATFORM_SIDE_QUEST_SUMMARY.md +++ b/doc/archive/PLATFORM_SIDE_QUEST_SUMMARY.md diff --git a/doc/SAMPLE_ACCURATE_TIMING_FIX.md b/doc/archive/SAMPLE_ACCURATE_TIMING_FIX.md index 6399090..6399090 100644 --- a/doc/SAMPLE_ACCURATE_TIMING_FIX.md +++ b/doc/archive/SAMPLE_ACCURATE_TIMING_FIX.md diff --git a/doc/SHADER_PARAMETRIZATION_PLAN.md b/doc/archive/SHADER_PARAMETRIZATION_PLAN.md index f5afa27..f5afa27 100644 --- a/doc/SHADER_PARAMETRIZATION_PLAN.md +++ b/doc/archive/SHADER_PARAMETRIZATION_PLAN.md diff --git a/doc/SPEC_EDITOR.md b/doc/archive/SPEC_EDITOR.md index 497a5a2..497a5a2 100644 --- a/doc/SPEC_EDITOR.md +++ b/doc/archive/SPEC_EDITOR.md diff --git a/doc/STRIPPING.md b/doc/archive/STRIPPING.md index 7e69177..7e69177 100644 --- a/doc/STRIPPING.md +++ b/doc/archive/STRIPPING.md diff --git a/doc/TASKS_SUMMARY.md b/doc/archive/TASKS_SUMMARY.md index 77cde6b..77cde6b 100644 --- a/doc/TASKS_SUMMARY.md +++ b/doc/archive/TASKS_SUMMARY.md diff --git a/doc/VISUAL_DEBUG.md b/doc/archive/VISUAL_DEBUG.md index f0adcba..f0adcba 100644 --- a/doc/VISUAL_DEBUG.md +++ b/doc/archive/VISUAL_DEBUG.md |
