diff options
| -rw-r--r-- | CLAUDE.md | 1 | ||||
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | doc/AI_RULES.md | 19 | ||||
| -rw-r--r-- | doc/CONTRIBUTING.md | 15 | ||||
| -rw-r--r-- | doc/EFFECT_WORKFLOW.md | 228 | ||||
| -rw-r--r-- | doc/HOWTO.md | 2 | ||||
| -rw-r--r-- | doc/RECIPE.md | 4 | ||||
| -rw-r--r-- | tools/shadertoy/README.md | 22 | ||||
| -rwxr-xr-x | tools/shadertoy/convert_shadertoy.py | 16 | ||||
| -rw-r--r-- | workspaces/main/timeline.seq | 3 |
11 files changed, 291 insertions, 22 deletions
@@ -11,6 +11,7 @@ @doc/HOWTO.md @doc/CONTRIBUTING.md @doc/AI_RULES.md +@doc/EFFECT_WORKFLOW.md # ============================================ # TIER 3: DESIGN DOCS (Load On-Demand) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97b371a..753a9b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -149,6 +149,7 @@ if (DEMO_HEADLESS) src/gpu/effects/particle_spray_effect.cc src/gpu/effects/gaussian_blur_effect.cc src/gpu/effects/solarize_effect.cc +# Disabled: src/gpu/effects/cube_sphere_effect.cc (incomplete conversion) src/gpu/effects/chroma_aberration_effect.cc src/gpu/effects/vignette_effect.cc src/gpu/effects/cnn_effect.cc @@ -179,6 +180,7 @@ else() src/gpu/effects/particle_spray_effect.cc src/gpu/effects/gaussian_blur_effect.cc src/gpu/effects/solarize_effect.cc +# Disabled: src/gpu/effects/cube_sphere_effect.cc (incomplete conversion) src/gpu/effects/chroma_aberration_effect.cc src/gpu/effects/vignette_effect.cc src/gpu/effects/cnn_effect.cc @@ -16,5 +16,6 @@ cmake --build build -j4 - **TODO.md** - Active tasks and priorities - **doc/HOWTO.md** - Common operations (building, testing, assets) - **doc/CONTRIBUTING.md** - Development guidelines and protocols +- **doc/EFFECT_WORKFLOW.md** - Step-by-step guide for adding visual effects See `doc/` for detailed technical documentation. diff --git a/doc/AI_RULES.md b/doc/AI_RULES.md index d18a0cc..1a4ee78 100644 --- a/doc/AI_RULES.md +++ b/doc/AI_RULES.md @@ -5,3 +5,22 @@ - Prefer small, reviewable commits - All `cmake --build` commands must use the `-j4` option for parallel building. - after a task, a 'big' final commit should contain a short handoff tag like "handoff(Gemini):..." if you're gemini-cli, or "handoff(Claude): ..." if you're claude-code. + +## Adding Visual Effects + +**IMPORTANT:** When adding new visual effects, follow the complete workflow in `doc/EFFECT_WORKFLOW.md`. + +**Required steps (must complete ALL):** +1. Create effect files (.h, .cc, .wgsl) +2. Add shader to `workspaces/main/assets.txt` +3. Add `.cc` to CMakeLists.txt GPU_SOURCES (BOTH sections: headless and normal) +4. Include header in `src/gpu/demo_effects.h` +5. Add to timeline with `EFFECT +` (priority modifier is REQUIRED) +6. Add to test list in `src/tests/gpu/test_demo_effects.cc` +7. Build and verify: `cmake --build build -j4 && cd build && ./test_demo_effects` + +**Common mistakes to avoid:** +- Missing priority modifier in timeline (`EFFECT` must be `EFFECT +`, `EFFECT =`, or `EFFECT -`) +- Adding `.cc` to only one CMakeLists.txt section (need BOTH headless and normal) +- Wrong asset ID (check assets.txt entry name → `ASSET_SHADER_<NAME>`) +- Forgetting to add to test file diff --git a/doc/CONTRIBUTING.md b/doc/CONTRIBUTING.md index 9cd785b..98df873 100644 --- a/doc/CONTRIBUTING.md +++ b/doc/CONTRIBUTING.md @@ -65,12 +65,15 @@ See `doc/CODING_STYLE.md` for detailed examples. ## Development Protocols ### Adding Visual Effect -1. Implement `Effect` subclass in `src/gpu/demo_effects.cc` -2. Add to workspace `timeline.seq` (e.g., `workspaces/main/timeline.seq`) -3. **Update `test_demo_effects.cc`**: - - Add to test list - - Increment `EXPECTED_*_COUNT` -4. Verify: +1. Create effect class files (use `tools/shadertoy/convert_shadertoy.py` or templates) +2. Add shader to `workspaces/main/assets.txt` +3. Add effect `.cc` file to `CMakeLists.txt` GPU_SOURCES (both sections) +4. Include header in `src/gpu/demo_effects.h` +5. Add to workspace `timeline.seq` (e.g., `workspaces/main/timeline.seq`) +6. **Update `src/tests/gpu/test_demo_effects.cc`**: + - Add to `post_process_effects` list (lines 80-93) or `scene_effects` list (lines 125-137) + - Example: `{"MyEffect", std::make_shared<MyEffect>(fixture.ctx())},` +7. Verify: ```bash cmake -S . -B build -DDEMO_BUILD_TESTS=ON cmake --build build -j4 --target test_demo_effects diff --git a/doc/EFFECT_WORKFLOW.md b/doc/EFFECT_WORKFLOW.md new file mode 100644 index 0000000..45c47b7 --- /dev/null +++ b/doc/EFFECT_WORKFLOW.md @@ -0,0 +1,228 @@ +# Effect Creation Workflow + +**Target Audience:** AI coding agents and developers + +Automated checklist for adding new visual effects to the demo. + +--- + +## Quick Reference + +**For ShaderToy conversions:** Use `tools/shadertoy/convert_shadertoy.py` then follow steps 3-8 below. + +**For custom effects:** Follow all steps 1-8. + +--- + +## Step-by-Step Workflow + +### 1. Create Effect Files + +**Location:** +- Header: `src/gpu/effects/<effect_name>_effect.h` +- Implementation: `src/gpu/effects/<effect_name>_effect.cc` +- Shader: `workspaces/main/shaders/<effect_name>.wgsl` + +**Naming Convention:** +- Class name: `<EffectName>Effect` (e.g., `TunnelEffect`, `PlasmaEffect`) +- Files: `<effect_name>_effect.*` (snake_case) + +**Base Class:** +- Post-process effects: inherit from `PostProcessEffect` +- Scene effects: inherit from `Effect` + +**Template:** See `tools/shadertoy/template.*` or use `convert_shadertoy.py` + +### 2. Add Shader to Assets + +**File:** `workspaces/main/assets.txt` + +**Format:** +``` +SHADER_<UPPER_SNAKE_NAME>, NONE, shaders/<effect_name>.wgsl, "Effect description" +``` + +**Example:** +``` +SHADER_TUNNEL, NONE, shaders/tunnel.wgsl, "Tunnel effect shader" +``` + +**Asset ID:** Will be `AssetId::ASSET_SHADER_<UPPER_SNAKE_NAME>` in C++ + +### 3. Add to CMakeLists.txt + +**File:** `CMakeLists.txt` + +**Action:** Add `src/gpu/effects/<effect_name>_effect.cc` to **BOTH** GPU_SOURCES sections: +- Headless mode section (around line 141-167) +- Normal mode section (around line 171-197) + +**Location:** After similar effects (post-process with post-process, scene with scene) + +**Example:** +```cmake +# In headless section (line ~152): + src/gpu/effects/solarize_effect.cc + src/gpu/effects/tunnel_effect.cc # <-- Add here + src/gpu/effects/chroma_aberration_effect.cc + +# In normal section (line ~183): + src/gpu/effects/solarize_effect.cc + src/gpu/effects/tunnel_effect.cc # <-- Add here + src/gpu/effects/chroma_aberration_effect.cc +``` + +### 4. Include in demo_effects.h + +**File:** `src/gpu/demo_effects.h` + +**Action:** Add include directive: +```cpp +#include "gpu/effects/<effect_name>_effect.h" +``` + +**Location:** Alphabetically with other effect includes + +### 5. Add to Timeline + +**File:** `workspaces/main/timeline.seq` + +**Format:** +``` +SEQUENCE <start_time> <priority> + EFFECT <+|=|-> <EffectName>Effect <local_start> <local_end> [params...] +``` + +**Priority Modifiers (REQUIRED):** +- `+` : Increment priority +- `=` : Same priority as previous effect +- `-` : Decrement priority (for backgrounds) + +**Example:** +``` +SEQUENCE 0.0 0 + EFFECT + TunnelEffect 0.0 10.0 +``` + +**Common Mistake:** Missing priority modifier (`+`, `=`, `-`) after EFFECT keyword + +### 6. Update Tests + +**File:** `src/tests/gpu/test_demo_effects.cc` + +**Action:** Add effect to appropriate list: + +**Post-Process Effects (lines 80-93):** +```cpp +{"TunnelEffect", std::make_shared<TunnelEffect>(fixture.ctx())}, +``` + +**Scene Effects (lines 125-137):** +```cpp +{"TunnelEffect", std::make_shared<TunnelEffect>(fixture.ctx())}, +``` + +**3D Effects:** If requires Renderer3D, add to `requires_3d` check (line 148-151) + +### 7. Build and Test + +```bash +# Full build +cmake --build build -j4 + +# Run effect tests +cmake -S . -B build -DDEMO_BUILD_TESTS=ON +cmake --build build -j4 --target test_demo_effects +cd build && ./test_demo_effects + +# Run all tests +cd build && ctest +``` + +### 8. Verify + +**Checklist:** +- [ ] Effect compiles without errors +- [ ] Effect appears in timeline +- [ ] test_demo_effects passes +- [ ] Effect renders correctly: `./build/demo64k` +- [ ] No shader compilation errors +- [ ] Follows naming conventions + +--- + +## Common Issues + +### Build Error: "no member named 'ASSET_..._SHADER'" + +**Cause:** Shader not in assets.txt or wrong asset ID name + +**Fix:** +1. Check `workspaces/main/assets.txt` has shader entry +2. Asset ID is `ASSET_` + uppercase entry name (e.g., `SHADER_TUNNEL` → `ASSET_SHADER_TUNNEL`) + +### Build Error: "undefined symbol for architecture" + +**Cause:** Effect not in CMakeLists.txt GPU_SOURCES + +**Fix:** Add `.cc` file to BOTH sections (headless and normal mode) + +### Timeline Parse Error: "Expected '+', '=', or '-'" + +**Cause:** Missing priority modifier after EFFECT keyword + +**Fix:** Use `EFFECT +`, `EFFECT =`, or `EFFECT -` (never just `EFFECT`) + +### Test Failure: Effect not in test list + +**Cause:** Effect not added to test_demo_effects.cc + +**Fix:** Add to `post_process_effects` or `scene_effects` list + +--- + +## Automation Script Example + +```bash +#!/bin/bash +# Example automation for AI agents + +EFFECT_NAME="$1" # CamelCase (e.g., "Tunnel") +SNAKE_NAME=$(echo "$EFFECT_NAME" | sed 's/\([A-Z]\)/_\L\1/g' | sed 's/^_//') +UPPER_NAME=$(echo "$SNAKE_NAME" | tr '[:lower:]' '[:upper:]') + +echo "Creating effect: $EFFECT_NAME" +echo " Snake case: $SNAKE_NAME" +echo " Upper case: $UPPER_NAME" + +# 1. Generate files (if using ShaderToy) +# ./tools/shadertoy/convert_shadertoy.py shader.txt "$EFFECT_NAME" + +# 2. Add to assets.txt +echo "SHADER_${UPPER_NAME}, NONE, shaders/${SNAKE_NAME}.wgsl, \"${EFFECT_NAME} effect\"" \ + >> workspaces/main/assets.txt + +# 3. Add to CMakeLists.txt (both sections) +# Use Edit tool to add to both GPU_SOURCES sections + +# 4. Add include to demo_effects.h +# Use Edit tool to add #include line + +# 5. Add to timeline.seq +# Use Edit tool to add EFFECT line with priority modifier + +# 6. Add to test file +# Use Edit tool to add to appropriate test list + +# 7. Build +cmake --build build -j4 +``` + +--- + +## See Also + +- `tools/shadertoy/README.md` - ShaderToy conversion guide +- `doc/SEQUENCE.md` - Timeline format documentation +- `doc/CONTRIBUTING.md` - General contribution guidelines +- `src/gpu/effects/` - Existing effect examples diff --git a/doc/HOWTO.md b/doc/HOWTO.md index 07d480b..a57a161 100644 --- a/doc/HOWTO.md +++ b/doc/HOWTO.md @@ -108,7 +108,7 @@ Generate shaders from checkpoint: Edit `workspaces/main/timeline.seq`: ```text SEQUENCE 0.0 0 - EFFECT HeptagonEffect 0.0 60.0 0 + EFFECT + HeptagonEffect 0.0 60.0 0 ``` Rebuild to apply. See `doc/SEQUENCE.md`. diff --git a/doc/RECIPE.md b/doc/RECIPE.md index 6404391..d563027 100644 --- a/doc/RECIPE.md +++ b/doc/RECIPE.md @@ -157,8 +157,8 @@ void MyEffect::render(WGPUTextureView prev, WGPUTextureView target, **.seq syntax:** ``` -EFFECT MyEffect 0.0 10.0 strength=0.5 speed=3.0 -EFFECT MyEffect 10.0 20.0 strength=2.0 # speed keeps previous value +EFFECT + MyEffect 0.0 10.0 strength=0.5 speed=3.0 +EFFECT = MyEffect 10.0 20.0 strength=2.0 # speed keeps previous value ``` **Example:** `src/gpu/effects/flash_effect.cc`, `src/gpu/effects/chroma_aberration_effect.cc` diff --git a/tools/shadertoy/README.md b/tools/shadertoy/README.md index e734684..d12865f 100644 --- a/tools/shadertoy/README.md +++ b/tools/shadertoy/README.md @@ -2,6 +2,8 @@ Quick guide to convert ShaderToy shaders to demo effects. +**For complete workflow:** See `doc/EFFECT_WORKFLOW.md` for full integration checklist. + ## Quick Start (Automated) ```bash @@ -95,16 +97,24 @@ In `src/gpu/demo_effects.h`: In `workspaces/main/timeline.seq`: ``` SEQUENCE 0.0 0 - EFFECT MyEffectEffect 0.0 10.0 0 + EFFECT + MyEffectEffect 0.0 10.0 +``` + +### 7. Update CMakeLists.txt + +Add effect source to `CMakeLists.txt` GPU_SOURCES (both headless and normal mode sections): +```cmake +src/gpu/effects/myeffect_effect.cc ``` -### 7. Update Tests +### 8. Update Tests -In `tests/test_demo_effects.cc`: -- Add `"MyEffectEffect"` to test list -- Increment `EXPECTED_*_COUNT` +In `src/tests/gpu/test_demo_effects.cc`: +- Add to `post_process_effects` list (lines 80-93) if it's a post-process effect +- OR add to `scene_effects` list (lines 125-137) if it's a scene effect +- Example: `{"MyEffectEffect", std::make_shared<MyEffectEffect>(fixture.ctx())},` -### 8. Build & Test +### 9. Build & Test ```bash cmake --build build -j4 diff --git a/tools/shadertoy/convert_shadertoy.py b/tools/shadertoy/convert_shadertoy.py index 4956cfd..29eca1d 100755 --- a/tools/shadertoy/convert_shadertoy.py +++ b/tools/shadertoy/convert_shadertoy.py @@ -383,7 +383,7 @@ def main(): print("✓ Files generated") print() - print("Next steps:") + print("Next steps (see doc/EFFECT_WORKFLOW.md for details):") print() print("1. Add shader to workspaces/main/assets.txt:") print(f" shaders/{snake_name}.wgsl") @@ -392,13 +392,17 @@ def main(): print(f' #include "gpu/effects/{snake_name}_effect.h"') print() print("3. Add to timeline in workspaces/main/timeline.seq:") - print(f" EFFECT {effect_name}Effect 0.0 10.0 0") + print(f" EFFECT + {effect_name}Effect 0.0 10.0") print() - print("4. Update tests/test_demo_effects.cc:") - print(f' - Add "{effect_name}Effect" to test list') - print(" - Increment EXPECTED_*_COUNT") + print("4. Add to CMakeLists.txt GPU_SOURCES (both headless and normal mode):") + print(f" src/gpu/effects/{snake_name}_effect.cc") print() - print("5. Build and test:") + print("5. Update src/tests/gpu/test_demo_effects.cc:") + print(f' - Add "{{{effect_name}Effect", std::make_shared<{effect_name}Effect>(fixture.ctx())}}" to appropriate list') + print(" - Use post_process_effects (lines 80-93) for post-process effects") + print(" - Use scene_effects (lines 125-137) for scene effects") + print() + print("6. Build and test:") print(" cmake --build build -j4") print(" ./build/demo64k") print() diff --git a/workspaces/main/timeline.seq b/workspaces/main/timeline.seq index 8f7eea6..5e9a84f 100644 --- a/workspaces/main/timeline.seq +++ b/workspaces/main/timeline.seq @@ -36,7 +36,8 @@ SEQUENCE 8.50 2 "Hybrid3D" SEQUENCE 10.50 0 "CNN effect" EFFECT + HeptagonEffect 0.0 12.00 # EFFECT + RotatingCubeEffect 0.00 12.0 - EFFECT + Hybrid3DEffect 0.00 12.00 +# EFFECT + Hybrid3DEffect 0.00 12.00 +# EFFECT + CubeSphereEffect 0.0 10.0 EFFECT + CNNEffect 1.0 12.0 layers=3 blend=1.5 SEQUENCE 22.0 0 "buggy" |
