summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore7
-rw-r--r--CLAUDE.md2
-rw-r--r--GEMINI.md55
-rw-r--r--PROJECT_CONTEXT.md4
-rw-r--r--TODO.md2
-rw-r--r--cmake/DemoCodegen.cmake150
-rw-r--r--cmake/DemoCommon.cmake31
-rw-r--r--cmake/DemoLibraries.cmake8
-rw-r--r--cmake/DemoSourceLists.cmake51
-rw-r--r--cmake/DemoTests.cmake80
-rw-r--r--cnn_v1/README.md64
-rw-r--r--cnn_v1/docs/CNN.md (renamed from doc/CNN.md)2
-rw-r--r--cnn_v1/docs/CNN_BIAS_FIX_2026-02.md (renamed from doc/CNN_BIAS_FIX_2026-02.md)0
-rw-r--r--cnn_v1/docs/CNN_DEBUG.md (renamed from doc/CNN_DEBUG.md)0
-rw-r--r--cnn_v1/docs/CNN_FLATTEN_ANALYSIS.md (renamed from doc/CNN_FLATTEN_ANALYSIS.md)6
-rw-r--r--cnn_v1/docs/CNN_RGBD_GRAYSCALE_SUMMARY.md (renamed from doc/CNN_RGBD_GRAYSCALE_SUMMARY.md)0
-rw-r--r--cnn_v1/docs/CNN_TEST_TOOL.md (renamed from doc/CNN_TEST_TOOL.md)0
-rw-r--r--cnn_v1/docs/CNN_V1_EFFECT.md (renamed from doc/CNN_EFFECT.md)0
-rw-r--r--cnn_v1/shaders/cnn_activation.wgsl (renamed from workspaces/main/shaders/cnn/cnn_activation.wgsl)0
-rw-r--r--cnn_v1/shaders/cnn_conv1x1.wgsl (renamed from workspaces/main/shaders/cnn/cnn_conv1x1.wgsl)0
-rw-r--r--cnn_v1/shaders/cnn_conv3x3.wgsl (renamed from workspaces/main/shaders/cnn/cnn_conv3x3.wgsl)0
-rw-r--r--cnn_v1/shaders/cnn_conv5x5.wgsl (renamed from workspaces/main/shaders/cnn/cnn_conv5x5.wgsl)0
-rw-r--r--cnn_v1/shaders/cnn_conv7x7.wgsl (renamed from workspaces/main/shaders/cnn/cnn_conv7x7.wgsl)0
-rw-r--r--cnn_v1/shaders/cnn_layer.wgsl (renamed from workspaces/main/shaders/cnn/cnn_layer.wgsl)0
-rw-r--r--cnn_v1/shaders/cnn_weights_generated.wgsl (renamed from workspaces/main/shaders/cnn/cnn_weights_generated.wgsl)0
-rw-r--r--cnn_v1/src/cnn_v1_effect.cc (renamed from src/effects/cnn_effect.cc)18
-rw-r--r--cnn_v1/src/cnn_v1_effect.h (renamed from src/effects/cnn_effect.h)14
-rwxr-xr-xcnn_v1/training/train_cnn.py (renamed from training/train_cnn.py)0
-rw-r--r--cnn_v2/README.md60
-rw-r--r--cnn_v2/docs/CNN_V2.md (renamed from doc/CNN_V2.md)0
-rw-r--r--cnn_v2/docs/CNN_V2_BINARY_FORMAT.md (renamed from doc/CNN_V2_BINARY_FORMAT.md)0
-rw-r--r--cnn_v2/docs/CNN_V2_DEBUG_TOOLS.md (renamed from doc/CNN_V2_DEBUG_TOOLS.md)0
-rw-r--r--cnn_v2/docs/CNN_V2_WEB_TOOL.md (renamed from doc/CNN_V2_WEB_TOOL.md)0
-rwxr-xr-xcnn_v2/scripts/train_cnn_v2_full.sh (renamed from scripts/train_cnn_v2_full.sh)10
-rw-r--r--cnn_v2/shaders/cnn_v2_compute.wgsl (renamed from workspaces/main/shaders/cnn_v2/cnn_v2_compute.wgsl)0
-rw-r--r--cnn_v2/shaders/cnn_v2_layer_0.wgsl (renamed from workspaces/main/shaders/cnn_v2/cnn_v2_layer_0.wgsl)0
-rw-r--r--cnn_v2/shaders/cnn_v2_layer_1.wgsl (renamed from workspaces/main/shaders/cnn_v2/cnn_v2_layer_1.wgsl)0
-rw-r--r--cnn_v2/shaders/cnn_v2_layer_2.wgsl (renamed from workspaces/main/shaders/cnn_v2/cnn_v2_layer_2.wgsl)0
-rw-r--r--cnn_v2/shaders/cnn_v2_layer_template.wgsl (renamed from workspaces/main/shaders/cnn_v2/cnn_v2_layer_template.wgsl)0
-rw-r--r--cnn_v2/shaders/cnn_v2_static.wgsl (renamed from workspaces/main/shaders/cnn_v2/cnn_v2_static.wgsl)0
-rw-r--r--cnn_v2/src/cnn_v2_effect.cc (renamed from src/effects/cnn_v2_effect.cc)2
-rw-r--r--cnn_v2/src/cnn_v2_effect.h (renamed from src/effects/cnn_v2_effect.h)0
-rw-r--r--cnn_v2/tools/cnn_v2_test/README.md (renamed from tools/cnn_v2_test/README.md)0
-rw-r--r--cnn_v2/tools/cnn_v2_test/index.html (renamed from tools/cnn_v2_test/index.html)0
-rwxr-xr-xcnn_v2/training/export_cnn_v2_shader.py (renamed from training/export_cnn_v2_shader.py)6
-rwxr-xr-xcnn_v2/training/export_cnn_v2_weights.py (renamed from training/export_cnn_v2_weights.py)8
-rwxr-xr-xcnn_v2/training/gen_identity_weights.py (renamed from training/gen_identity_weights.py)6
-rwxr-xr-xcnn_v2/training/train_cnn_v2.py (renamed from training/train_cnn_v2.py)0
-rw-r--r--cnn_v3/README.md36
-rw-r--r--cnn_v3/training/input/photo1.jpgbin0 -> 5813575 bytes
-rw-r--r--cnn_v3/training/input/photo2.jpgbin0 -> 3328126 bytes
-rw-r--r--cnn_v3/training/input/photo3.jpgbin0 -> 723541 bytes
-rw-r--r--cnn_v3/training/input/photo4.jpgbin0 -> 286046 bytes
-rw-r--r--cnn_v3/training/target_1/photo1_out.pngbin0 -> 4038843 bytes
-rw-r--r--cnn_v3/training/target_1/photo2_1_out.pngbin0 -> 2875939 bytes
-rw-r--r--cnn_v3/training/target_1/photo2_2_out.pngbin0 -> 2865857 bytes
-rw-r--r--cnn_v3/training/target_1/photo4_out.pngbin0 -> 718912 bytes
-rw-r--r--doc/AUXILIARY_TEXTURE_INIT.md2
-rw-r--r--doc/BUILD.md8
-rw-r--r--doc/CMAKE_MODULES.md22
-rw-r--r--doc/COMPLETED.md6
-rw-r--r--doc/HOWTO.md44
-rw-r--r--src/app/test_demo.cc4
-rw-r--r--src/gpu/demo_effects.h4
-rw-r--r--src/tests/audio/test_audio_engine.cc8
-rw-r--r--src/tests/gpu/test_demo_effects.cc4
-rw-r--r--tools/cnn_test.cc2
-rw-r--r--training/README.md2
-rw-r--r--workspaces/main/assets.txt20
-rw-r--r--workspaces/main/timeline.seq4
70 files changed, 576 insertions, 176 deletions
diff --git a/.gitignore b/.gitignore
index 41d0683..bce098f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,3 +70,10 @@ Testing/
training/checkpoints/
checkpoints/
validation_results/
+**/assets_filtered_*.txt
+**/assets_assets_*.txt
+
+# Timeline editor temp files
+test_*.seq
+*_save.seq
+tools/timeline_editor/timeline.seq
diff --git a/CLAUDE.md b/CLAUDE.md
index 2a60521..526e940 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -12,7 +12,7 @@
# TIER 3: DESIGN DOCS (Load On-Demand by Subsystem)
#
# Audio: SPECTRAL_BRUSH_EDITOR.md, TRACKER.md, BEAT_TIMING.md
-# CNN: CNN.md, CNN_EFFECT.md, CNN_V2*.md, CNN_TEST_TOOL.md, CNN_*ANALYSIS.md, CNN_BIAS_FIX*.md
+# CNN: cnn_v1/docs/CNN_V1_EFFECT.md, cnn_v2/docs/CNN_V2*.md
# 3D/Graphics: 3D.md, GPU_PROCEDURAL_PHASE4.md, MASKING_SYSTEM.md, SDF_EFFECT_GUIDE.md
# Scene: SCENE_FORMAT.md, SEQUENCE.md, WORKSPACE_SYSTEM.md
# Build: ASSET_SYSTEM.md, BUILD.md, CMAKE_MODULES.md, SIZE_MEASUREMENT.md
diff --git a/GEMINI.md b/GEMINI.md
index 787ba22..5c47b07 100644
--- a/GEMINI.md
+++ b/GEMINI.md
@@ -84,48 +84,19 @@ IMPORTANT:
- Keep PROJECT_CONTEXT.md focused on current status
- Keep TODO.md focused on active/next tasks only
-# ============================================
-# CURRENT STATE SNAPSHOT (Gemini-Specific)
-# ============================================
-<state_snapshot>
- <overall_goal>
- Produce a cross-platform (Windows, macOS, Linux) 64-kilobyte demoscene production. This is achieved through a C++ codebase utilizing WebGPU for graphics (with a hybrid SDF/rasterization pipeline) and a real-time procedural audio engine for sound, with a heavy focus on size-optimization at all stages.
- </overall_goal>
-
- <active_constraints>
- - All tests passing (36/36 - 100%).
- - Strict 64k final binary size target.
- - Adherence to project coding style and contribution guidelines is mandatory.
- </active_constraints>
-
- <key_knowledge>
- - **Workspace System:** The project is organized into self-contained workspaces (e.g., `workspaces/main`, `workspaces/test`) managed by a `workspace.cfg` file, separating demo-specific content from a `common/` directory that holds shared shaders and resources. Selection is done at build time with `-DDEMO_WORKSPACE=<name>`.
- - **Build & Asset Pipeline:** A modular CMake system orchestrates the build. It uses host-native tools (`asset_packer`, `seq_compiler`, `tracker_compiler`) to parse manifest files (`assets.txt`, `timeline.seq`, `music.track`) and compile assets directly into the binary as C++ data, including procedural asset generation.
- - **Audio Engine:** A real-time, sample-accurate audio engine with a tracker system for sequencing patterns from `.track` files. It features procedural synthesis from spectrograms (FFT-based IDCT), variable tempo that is decoupled from visual timing, and an abstracted backend for testing and offline rendering (`WavDumpBackend`).
- - **Graphics & Rendering:** The renderer uses WebGPU (wgpu-native) and WGSL shaders. It employs a hybrid technique, rasterizing proxy geometry (cubes) and then performing SDF raymarching within the fragment shader. The 3D system supports BVH acceleration, and there's a pipeline for importing OBJ models.
- - **Sequence & Timing:** Visuals are defined in `.seq` files using a beat-based timeline that is compiled into physical seconds. Shaders receive a `CommonPostProcessUniforms` buffer containing both physical time (`time`) for constant-speed animations and musical time (`beat_time`, `beat_phase`) for syncing with the audio playback clock.
- - **CNN Post-Processing:** The project features a sophisticated CNN post-processing pipeline (CNNv2) for visual stylization. This includes a full Python/PyTorch training toolchain, a binary weight format, and a WebGPU-based validation tool. The network uses 7D parametric static features (RGBD, UV, sin, bias) for rich, position-aware effects.
- - **Development Workflow:** There is a strong emphasis on tooling and process, including a visual timeline editor, audio analysis tools, a web-based CNN debugger, strict coding standards enforced by `clang-format`, and a comprehensive pre-commit script (`./scripts/check_all.sh`).
- </key_knowledge>
+# Role: Senior Systems Engineer (C++ Focus)
- <artifact_trail>
- - `GEMINI.md`: This file, synchronized with CLAUDE.md structure
- - `PROJECT_CONTEXT.md`: Current system status
- - `TODO.md`: Active priorities (Task #5 in progress)
- </artifact_trail>
+## Response Style
+- **Extreme Brevity:** Provide direct answers. No "Sure, I can help," "I hope this helps," or "Here is the code."
+- **Code-First:** Lead with the solution or the code block.
+- **Explain on Demand:** Do not explain *how* the code works unless explicitly asked with "Why?" or "Explain."
+- **No Markdown Fluff:** Avoid bolding every other word. Use standard technical formatting.
- <recent_actions>
- - **File Hierarchy Cleanup:** Major reorganization of the project structure, establishing the `workspaces/` and `common/` directories and eliminating ~100 redundant files (especially shaders).
- - **CNNv2 Training Pipeline:** Fixed critical checkpointing bugs and streamlined the output of the training scripts for faster iteration.
- - **Effect Render API Refactor:** Simplified the `Effect::render` API and fixed uniform initialization bugs across 19 effects.
- - **CNN Shader Testing Tool:** Implemented `tools/cnn_test` for offline GPU-accelerated validation of trained CNN models.
- - **Effect Source Hierarchy Cleanup**: Refactored the effects system by splitting `src/gpu/demo_effects.h` into individual header files for each effect, creating 10 new headers, moving class definitions, updating `.cc` files with new includes, fixing missing `#include` statements, creating a common `particle_defs.h`, and cleaning up `demo_effects.h`. Verified by passing all 34 tests. handoff(Gemini):
- </recent_actions>
+## Technical Preferences
+- **C++ Standards:** Default to C++20/C++23 unless specified otherwise.
+- **Style:** Prefer Modern C++ (RAII, templates, constexpr, STL) over C-style patterns.
+- **Nomenclature:** Use standard engineering terminology (e.g., "O(n) complexity," "pointer aliasing," "cache miss") without defining the terms.
- <task_state>
- 1. [IN PROGRESS] Task #5: Spectral Brush Editor (Priority 1)
- 2. [PENDING] Task #18: 3D System Enhancements (Priority 4)
- 3. [RECURRENT] Task #50: WGSL Modularization (Priority 4)
- 4. [PENDING] Tracker Humanization & Sample Offset (Priority 3)
- </task_state>
-</state_snapshot> \ No newline at end of file
+## Interaction Protocol
+- If a query is ambiguous, provide the most likely technical solution rather than asking for clarification.
+- Treat the user as a peer with expert-level knowledge.
diff --git a/PROJECT_CONTEXT.md b/PROJECT_CONTEXT.md
index 63e6f8a..f59eb8b 100644
--- a/PROJECT_CONTEXT.md
+++ b/PROJECT_CONTEXT.md
@@ -57,9 +57,9 @@ See `TODO.md` for current priorities and active tasks.
- `doc/CONTRIBUTING.md` - Development protocols
**Technical Reference:**
-- Core: `ASSET_SYSTEM.md`, `SEQUENCE.md`, `TRACKER.md`, `3D.md`, `CNN_EFFECT.md`, `CNN_V2.md`
+- Core: `ASSET_SYSTEM.md`, `SEQUENCE.md`, `TRACKER.md`, `3D.md`, `cnn_v1/docs/CNN_V1_EFFECT.md`, `cnn_v2/docs/CNN_V2.md`
- Formats: `SCENE_FORMAT.md`, `MASKING_SYSTEM.md`
-- Tools: `BUILD.md`, `WORKSPACE_SYSTEM.md`, `SIZE_MEASUREMENT.md`, `CNN_TEST_TOOL.md`, `tools/timeline_editor/README.md`
+- Tools: `BUILD.md`, `WORKSPACE_SYSTEM.md`, `SIZE_MEASUREMENT.md`, `cnn_v1/docs/CNN_TEST_TOOL.md`, `tools/timeline_editor/README.md`
**History:**
- `doc/COMPLETED.md` - Completed tasks archive
diff --git a/TODO.md b/TODO.md
index 78e13ab..4e67b51 100644
--- a/TODO.md
+++ b/TODO.md
@@ -28,7 +28,7 @@ Self-contained workspaces for parallel demo development.
Enhanced CNN post-processing with multi-dimensional feature inputs.
-**Design:** `doc/CNN_V2.md`
+**Design:** `cnn_v2/docs/CNN_V2.md`
**Status:**
- ✅ Full implementation complete and validated
diff --git a/cmake/DemoCodegen.cmake b/cmake/DemoCodegen.cmake
index 272e424..d27e9eb 100644
--- a/cmake/DemoCodegen.cmake
+++ b/cmake/DemoCodegen.cmake
@@ -53,6 +53,48 @@ function(pack_assets NAME INPUT_TXT HEADER_VAR DATA_CC_VAR TARGET_NAME)
add_custom_target(${TARGET_NAME} DEPENDS ${OUT_H} ${OUT_CC})
endfunction()
+# Pack assets by category (filters by filename pattern)
+function(pack_assets_category NAME PATTERN INPUT_TXT HEADER_VAR DATA_CC_VAR TARGET_NAME)
+ set(OUT_H ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/${NAME}.h)
+ set(OUT_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/${NAME}_data.cc)
+
+ # Get directory of INPUT_TXT for relative path resolution
+ get_filename_component(INPUT_DIR ${INPUT_TXT} DIRECTORY)
+ get_filename_component(INPUT_NAME ${INPUT_TXT} NAME_WE)
+ set(FILTERED_TXT ${INPUT_DIR}/${INPUT_NAME}_${NAME}.txt)
+
+ # Create filtered asset list
+ file(STRINGS ${INPUT_TXT} ALL_LINES)
+ set(FILTERED_LINES "")
+ foreach(LINE ${ALL_LINES})
+ string(STRIP "${LINE}" LINE)
+ if(LINE MATCHES "^#" OR LINE STREQUAL "")
+ list(APPEND FILTERED_LINES "${LINE}")
+ else()
+ string(REGEX REPLACE "^[^,]+,[^,]+,[ ]*([^,]+).*" "\\1" FILENAME "${LINE}")
+ if(FILENAME MATCHES "${PATTERN}")
+ list(APPEND FILTERED_LINES "${LINE}")
+ endif()
+ endif()
+ endforeach()
+ string(REPLACE ";" "\n" FILTERED_CONTENT "${FILTERED_LINES}")
+ file(WRITE ${FILTERED_TXT} "${FILTERED_CONTENT}\n")
+
+ # Parse filtered list for dependencies (now in same directory as INPUT_TXT)
+ parse_asset_list(${FILTERED_TXT} ASSET_FILE_DEPS)
+
+ add_custom_command(
+ OUTPUT ${OUT_H} ${OUT_CC}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/src/generated
+ COMMAND ${ASSET_PACKER_CMD} ${FILTERED_TXT} ${OUT_H} ${OUT_CC}
+ DEPENDS ${ASSET_PACKER_DEPENDS} ${INPUT_TXT} ${ASSET_FILE_DEPS}
+ COMMENT "Generating ${NAME} assets..."
+ )
+ set(${HEADER_VAR} ${OUT_H} PARENT_SCOPE)
+ set(${DATA_CC_VAR} ${OUT_CC} PARENT_SCOPE)
+ add_custom_target(${TARGET_NAME} DEPENDS ${OUT_H} ${OUT_CC})
+endfunction()
+
# Pack test assets (output to build/src/generated_test/)
function(pack_test_assets NAME INPUT_TXT HEADER_VAR DATA_CC_VAR TARGET_NAME)
set(OUT_H ${CMAKE_CURRENT_BINARY_DIR}/src/generated_test/${NAME}.h)
@@ -102,8 +144,112 @@ add_custom_command(
)
add_custom_target(generate_tracker_music ALL DEPENDS ${GENERATED_MUSIC_DATA_CC})
-# Asset packing
-pack_assets(assets ${WORKSPACE_ASSETS} GEN_DEMO_H GEN_DEMO_CC generate_demo_assets)
+# Asset packing (split by category for granular rebuild tracking)
+# Generate filtered asset files per category
+get_filename_component(ASSETS_DIR ${WORKSPACE_ASSETS} DIRECTORY)
+set(FILTERED_SHADERS ${ASSETS_DIR}/assets_filtered_shaders.txt)
+set(FILTERED_AUDIO ${ASSETS_DIR}/assets_filtered_audio.txt)
+set(FILTERED_MODELS ${ASSETS_DIR}/assets_filtered_models.txt)
+set(FILTERED_DATA ${ASSETS_DIR}/assets_filtered_data.txt)
+
+# Filter assets by category at configure time
+file(STRINGS ${WORKSPACE_ASSETS} ALL_ASSET_LINES)
+set(SHADERS_LINES "")
+set(AUDIO_LINES "")
+set(MODELS_LINES "")
+set(DATA_LINES "")
+
+foreach(LINE ${ALL_ASSET_LINES})
+ string(STRIP "${LINE}" LINE)
+ if(LINE MATCHES "^#" OR LINE STREQUAL "")
+ list(APPEND SHADERS_LINES "${LINE}")
+ list(APPEND AUDIO_LINES "${LINE}")
+ list(APPEND MODELS_LINES "${LINE}")
+ list(APPEND DATA_LINES "${LINE}")
+ else()
+ string(REGEX REPLACE "^[^,]+,[^,]+,[ ]*([^,]+).*" "\\1" FILENAME "${LINE}")
+ if(FILENAME MATCHES "\\.wgsl$")
+ list(APPEND SHADERS_LINES "${LINE}")
+ elseif(FILENAME MATCHES "\\.(spec|track)$")
+ list(APPEND AUDIO_LINES "${LINE}")
+ elseif(FILENAME MATCHES "\\.obj$")
+ list(APPEND MODELS_LINES "${LINE}")
+ elseif(FILENAME MATCHES "\\.(bin|png)$" OR FILENAME MATCHES "PROC\\(")
+ list(APPEND DATA_LINES "${LINE}")
+ endif()
+ endif()
+endforeach()
+
+string(REPLACE ";" "\n" SHADERS_CONTENT "${SHADERS_LINES}")
+string(REPLACE ";" "\n" AUDIO_CONTENT "${AUDIO_LINES}")
+string(REPLACE ";" "\n" MODELS_CONTENT "${MODELS_LINES}")
+string(REPLACE ";" "\n" DATA_CONTENT "${DATA_LINES}")
+
+file(WRITE ${FILTERED_SHADERS} "${SHADERS_CONTENT}\n")
+file(WRITE ${FILTERED_AUDIO} "${AUDIO_CONTENT}\n")
+file(WRITE ${FILTERED_MODELS} "${MODELS_CONTENT}\n")
+file(WRITE ${FILTERED_DATA} "${DATA_CONTENT}\n")
+
+# Parse dependencies per category
+parse_asset_list(${FILTERED_SHADERS} SHADERS_DEPS)
+parse_asset_list(${FILTERED_AUDIO} AUDIO_DEPS)
+parse_asset_list(${FILTERED_MODELS} MODELS_DEPS)
+parse_asset_list(${FILTERED_DATA} DATA_DEPS)
+
+# Single unified output (avoids duplicate symbols)
+set(GEN_DEMO_H ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/assets.h)
+set(GEN_DEMO_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/assets_data.cc)
+
+# Category-specific targets for granular rebuilds
+add_custom_command(
+ OUTPUT ${GEN_DEMO_H}.shaders_stamp
+ COMMAND ${CMAKE_COMMAND} -E touch ${GEN_DEMO_H}.shaders_stamp
+ DEPENDS ${ASSET_PACKER_DEPENDS} ${WORKSPACE_ASSETS} ${SHADERS_DEPS}
+ COMMENT "Checking shader assets..."
+)
+add_custom_target(generate_demo_shaders DEPENDS ${GEN_DEMO_H}.shaders_stamp)
+
+add_custom_command(
+ OUTPUT ${GEN_DEMO_H}.audio_stamp
+ COMMAND ${CMAKE_COMMAND} -E touch ${GEN_DEMO_H}.audio_stamp
+ DEPENDS ${ASSET_PACKER_DEPENDS} ${WORKSPACE_ASSETS} ${AUDIO_DEPS}
+ COMMENT "Checking audio assets..."
+)
+add_custom_target(generate_demo_audio DEPENDS ${GEN_DEMO_H}.audio_stamp)
+
+add_custom_command(
+ OUTPUT ${GEN_DEMO_H}.models_stamp
+ COMMAND ${CMAKE_COMMAND} -E touch ${GEN_DEMO_H}.models_stamp
+ DEPENDS ${ASSET_PACKER_DEPENDS} ${WORKSPACE_ASSETS} ${MODELS_DEPS}
+ COMMENT "Checking model assets..."
+)
+add_custom_target(generate_demo_models DEPENDS ${GEN_DEMO_H}.models_stamp)
+
+add_custom_command(
+ OUTPUT ${GEN_DEMO_H}.data_stamp
+ COMMAND ${CMAKE_COMMAND} -E touch ${GEN_DEMO_H}.data_stamp
+ DEPENDS ${ASSET_PACKER_DEPENDS} ${WORKSPACE_ASSETS} ${DATA_DEPS}
+ COMMENT "Checking data assets..."
+)
+add_custom_target(generate_demo_data DEPENDS ${GEN_DEMO_H}.data_stamp)
+
+# Unified asset generation (triggered when any category changes)
+add_custom_command(
+ OUTPUT ${GEN_DEMO_H} ${GEN_DEMO_CC}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/src/generated
+ COMMAND ${ASSET_PACKER_CMD} ${WORKSPACE_ASSETS} ${GEN_DEMO_H} ${GEN_DEMO_CC}
+ DEPENDS ${ASSET_PACKER_DEPENDS} ${WORKSPACE_ASSETS}
+ ${GEN_DEMO_H}.shaders_stamp
+ ${GEN_DEMO_H}.audio_stamp
+ ${GEN_DEMO_H}.models_stamp
+ ${GEN_DEMO_H}.data_stamp
+ COMMENT "Generating unified assets..."
+)
+
+# Combined target for compatibility
+add_custom_target(generate_demo_assets DEPENDS ${GEN_DEMO_H} ${GEN_DEMO_CC})
+
+# Test assets (unchanged)
pack_test_assets(test_assets ${CMAKE_CURRENT_SOURCE_DIR}/workspaces/test/assets.txt GEN_TEST_H GEN_TEST_CC generate_test_assets)
# Mark generated files so CMake always checks if they need rebuilding
diff --git a/cmake/DemoCommon.cmake b/cmake/DemoCommon.cmake
index 1c63b26..401ea05 100644
--- a/cmake/DemoCommon.cmake
+++ b/cmake/DemoCommon.cmake
@@ -197,3 +197,34 @@ macro(add_demo_test NAME TEST_NAME LABEL)
add_test(NAME ${TEST_NAME} COMMAND ${NAME})
set_tests_properties(${TEST_NAME} PROPERTIES LABELS "${LABEL}")
endmacro()
+
+# =============================================================================
+# demo_add_asset_deps(TARGET CATEGORY)
+# =============================================================================
+# Adds asset category dependencies to a target
+#
+# Arguments:
+# TARGET - CMake target name
+# CATEGORY - Asset category (shaders, audio, models, data, all, test)
+#
+# Usage:
+# demo_add_asset_deps(test_synth audio)
+# demo_add_asset_deps(test_shader_compilation shaders)
+# demo_add_asset_deps(demo64k all)
+function(demo_add_asset_deps TARGET CATEGORY)
+ if(CATEGORY STREQUAL "all")
+ add_dependencies(${TARGET} generate_demo_shaders generate_demo_audio generate_demo_models generate_demo_data)
+ elseif(CATEGORY STREQUAL "test")
+ add_dependencies(${TARGET} generate_test_assets)
+ elseif(CATEGORY STREQUAL "shaders")
+ add_dependencies(${TARGET} generate_demo_shaders)
+ elseif(CATEGORY STREQUAL "audio")
+ add_dependencies(${TARGET} generate_demo_audio)
+ elseif(CATEGORY STREQUAL "models")
+ add_dependencies(${TARGET} generate_demo_models)
+ elseif(CATEGORY STREQUAL "data")
+ add_dependencies(${TARGET} generate_demo_data)
+ else()
+ message(FATAL_ERROR "Unknown asset category: ${CATEGORY}")
+ endif()
+endfunction()
diff --git a/cmake/DemoLibraries.cmake b/cmake/DemoLibraries.cmake
index 3a2207a..f1891fb 100644
--- a/cmake/DemoLibraries.cmake
+++ b/cmake/DemoLibraries.cmake
@@ -3,8 +3,8 @@
# Utility library
add_library(util STATIC ${UTIL_SOURCES})
-add_dependencies(util generate_demo_assets generate_test_assets)
target_include_directories(util PUBLIC ${CORE_INCLUDES})
+add_dependencies(util generate_demo_assets)
# Procedural generation library
add_library(procedural STATIC ${PROCEDURAL_SOURCES})
@@ -12,18 +12,18 @@ target_include_directories(procedural PUBLIC ${CORE_INCLUDES})
# Audio synthesis and processing library
add_library(audio STATIC ${AUDIO_SOURCES})
-add_dependencies(audio generate_demo_assets)
target_include_directories(audio PUBLIC ${CORE_INCLUDES})
+add_dependencies(audio generate_demo_assets)
# 3D rendering library
add_library(3d STATIC ${3D_SOURCES})
-add_dependencies(3d generate_demo_assets)
target_include_directories(3d PUBLIC ${CORE_INCLUDES})
+add_dependencies(3d generate_demo_assets)
# GPU effects library
add_library(gpu STATIC ${GPU_SOURCES})
-add_dependencies(gpu generate_demo_assets)
target_include_directories(gpu PUBLIC ${CORE_INCLUDES})
+add_dependencies(gpu generate_demo_assets)
# Note: Static libraries do not strictly need to link dependencies,
# but if they did, PRIVATE would propagate to the executable.
diff --git a/cmake/DemoSourceLists.cmake b/cmake/DemoSourceLists.cmake
index d4cdd21..2d6cf42 100644
--- a/cmake/DemoSourceLists.cmake
+++ b/cmake/DemoSourceLists.cmake
@@ -26,24 +26,67 @@ set(PROCEDURAL_SOURCES src/procedural/generator.cc)
# Utility sources (unconditional)
set(UTIL_SOURCES src/util/asset_manager.cc src/util/file_watcher.cc)
+# Common effect sources (shared between headless and normal modes)
+set(COMMON_GPU_EFFECTS
+ src/gpu/effect.cc
+ src/effects/heptagon_effect.cc
+ src/effects/particles_effect.cc
+ src/effects/passthrough_effect.cc
+ src/effects/moving_ellipse_effect.cc
+ src/effects/particle_spray_effect.cc
+ src/effects/gaussian_blur_effect.cc
+ src/effects/solarize_effect.cc
+ src/effects/scene1_effect.cc
+ src/effects/chroma_aberration_effect.cc
+ src/effects/vignette_effect.cc
+ cnn_v1/src/cnn_v1_effect.cc
+ cnn_v2/src/cnn_v2_effect.cc
+ src/gpu/post_process_helper.cc
+ src/gpu/shaders.cc
+ src/effects/hybrid_3d_effect.cc
+ src/effects/flash_cube_effect.cc
+ src/effects/theme_modulation_effect.cc
+ src/effects/fade_effect.cc
+ src/effects/flash_effect.cc
+ src/gpu/shader_composer.cc
+ src/effects/circle_mask_effect.cc
+ src/effects/rotating_cube_effect.cc
+ src/gpu/texture_manager.cc
+ src/gpu/texture_readback.cc
+ src/effects/sdf_test_effect.cc
+)
+
# GPU sources (conditional: HEADLESS / STRIP_EXTERNAL / NORMAL)
demo_set_conditional_sources(GPU_SOURCES
# Headless mode: Functional stubs (timeline/audio work)
- "src/gpu/headless_gpu.cc;src/gpu/demo_effects.cc;src/gpu/effect.cc;src/effects/heptagon_effect.cc;src/effects/particles_effect.cc;src/effects/passthrough_effect.cc;src/effects/moving_ellipse_effect.cc;src/effects/particle_spray_effect.cc;src/effects/gaussian_blur_effect.cc;src/effects/solarize_effect.cc;src/effects/scene1_effect.cc;src/effects/chroma_aberration_effect.cc;src/effects/vignette_effect.cc;src/effects/cnn_effect.cc;src/effects/cnn_v2_effect.cc;src/gpu/post_process_helper.cc;src/gpu/shaders.cc;src/effects/hybrid_3d_effect.cc;src/effects/flash_cube_effect.cc;src/effects/theme_modulation_effect.cc;src/effects/fade_effect.cc;src/effects/flash_effect.cc;src/gpu/shader_composer.cc;src/effects/circle_mask_effect.cc;src/effects/rotating_cube_effect.cc;src/gpu/texture_manager.cc;src/gpu/texture_readback.cc;src/effects/sdf_test_effect.cc"
+ "src/gpu/headless_gpu.cc;src/gpu/demo_effects.cc;${COMMON_GPU_EFFECTS}"
# Strip mode: Minimal GPU stubs only
"src/gpu/stub_gpu.cc"
# Normal mode: Full GPU implementation
- "src/gpu/gpu.cc;src/gpu/effect.cc;src/effects/heptagon_effect.cc;src/effects/particles_effect.cc;src/effects/passthrough_effect.cc;src/effects/moving_ellipse_effect.cc;src/effects/particle_spray_effect.cc;src/effects/gaussian_blur_effect.cc;src/effects/solarize_effect.cc;src/effects/scene1_effect.cc;src/effects/chroma_aberration_effect.cc;src/effects/vignette_effect.cc;src/effects/cnn_effect.cc;src/effects/cnn_v2_effect.cc;src/gpu/post_process_helper.cc;src/gpu/shaders.cc;src/effects/hybrid_3d_effect.cc;src/effects/flash_cube_effect.cc;src/effects/theme_modulation_effect.cc;src/effects/fade_effect.cc;src/effects/flash_effect.cc;src/gpu/shader_composer.cc;src/effects/circle_mask_effect.cc;src/effects/rotating_cube_effect.cc;src/gpu/texture_manager.cc;src/gpu/texture_readback.cc;src/effects/sdf_test_effect.cc"
+ "src/gpu/gpu.cc;${COMMON_GPU_EFFECTS}"
+)
+
+# Common 3D sources (shared between headless and normal modes)
+set(COMMON_3D_FILES
+ src/3d/renderer.cc
+ src/3d/renderer_draw.cc
+ src/3d/renderer_pipelines.cc
+ src/3d/renderer_resources.cc
+ src/3d/renderer_helpers.cc
+ src/3d/visual_debug.cc
+ src/3d/bvh.cc
+ src/3d/physics.cc
+ src/3d/scene_loader.cc
)
# 3D sources (conditional: HEADLESS / STRIP_EXTERNAL / NORMAL)
demo_set_conditional_sources(3D_SOURCES
# Headless mode: Full 3D (needed for Hybrid3DEffect)
- "src/3d/renderer.cc;src/3d/renderer_draw.cc;src/3d/renderer_pipelines.cc;src/3d/renderer_resources.cc;src/3d/renderer_helpers.cc;src/3d/visual_debug.cc;src/3d/bvh.cc;src/3d/physics.cc;src/3d/scene_loader.cc"
+ "${COMMON_3D_FILES}"
# Strip mode: Stub 3D (depends on WebGPU)
"src/3d/bvh.cc;src/3d/physics.cc;src/3d/scene_loader.cc"
# Normal mode: Full 3D implementation
- "src/3d/renderer.cc;src/3d/renderer_draw.cc;src/3d/renderer_pipelines.cc;src/3d/renderer_resources.cc;src/3d/renderer_helpers.cc;src/3d/visual_debug.cc;src/3d/bvh.cc;src/3d/physics.cc;src/3d/scene_loader.cc"
+ "${COMMON_3D_FILES}"
)
# Platform sources (conditional: HEADLESS / STRIP_EXTERNAL / NORMAL)
diff --git a/cmake/DemoTests.cmake b/cmake/DemoTests.cmake
index fa64284..b511620 100644
--- a/cmake/DemoTests.cmake
+++ b/cmake/DemoTests.cmake
@@ -3,7 +3,7 @@
add_demo_test(test_window HammingWindowTest audio src/tests/audio/test_window.cc ${GEN_DEMO_CC})
target_link_libraries(test_window PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_window generate_demo_assets)
+demo_add_asset_deps(test_window audio)
add_demo_test(test_maths MathUtilsTest util src/tests/util/test_maths.cc)
@@ -12,71 +12,78 @@ target_link_libraries(test_file_watcher PRIVATE util ${DEMO_LIBS})
add_demo_test(test_synth SynthEngineTest audio src/tests/audio/test_synth.cc ${GEN_DEMO_CC})
target_link_libraries(test_synth PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_synth generate_demo_assets)
+demo_add_asset_deps(test_synth audio)
add_demo_test(test_dct DctTest audio src/tests/audio/test_dct.cc ${GEN_DEMO_CC})
target_link_libraries(test_dct PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_dct generate_demo_assets)
+demo_add_asset_deps(test_dct audio)
add_demo_test(test_fft FftTest audio src/tests/audio/test_fft.cc ${GEN_DEMO_CC})
target_link_libraries(test_fft PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_fft generate_demo_assets)
+demo_add_asset_deps(test_fft audio)
add_demo_test(test_spectral_brush SpectralBrushTest audio src/tests/audio/test_spectral_brush.cc ${GEN_DEMO_CC})
target_link_libraries(test_spectral_brush PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_spectral_brush generate_demo_assets)
+demo_add_asset_deps(test_spectral_brush audio)
add_demo_test(test_audio_gen AudioGenTest audio src/tests/audio/test_audio_gen.cc ${GEN_DEMO_CC})
target_link_libraries(test_audio_gen PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_audio_gen generate_demo_assets)
+demo_add_asset_deps(test_audio_gen audio)
add_demo_test(test_audio_backend AudioBackendTest audio src/tests/audio/test_audio_backend.cc ${GEN_DEMO_CC})
target_link_libraries(test_audio_backend PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_audio_backend generate_demo_assets)
+demo_add_asset_deps(test_audio_backend audio)
add_demo_test(test_silent_backend SilentBackendTest audio src/tests/audio/test_silent_backend.cc src/tests/common/audio_test_fixture.cc ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_silent_backend PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_silent_backend generate_demo_assets generate_tracker_music)
+demo_add_asset_deps(test_silent_backend audio)
+add_dependencies(test_silent_backend generate_tracker_music)
add_demo_test(test_mock_backend MockAudioBackendTest audio src/tests/audio/test_mock_backend.cc src/audio/backend/mock_audio_backend.cc ${GEN_DEMO_CC})
target_link_libraries(test_mock_backend PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_mock_backend generate_demo_assets)
+demo_add_asset_deps(test_mock_backend audio)
add_demo_test(test_wav_dump WavDumpBackendTest audio src/tests/audio/test_wav_dump.cc src/tests/common/audio_test_fixture.cc src/audio/backend/wav_dump_backend.cc ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_wav_dump PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_wav_dump generate_demo_assets generate_tracker_music)
+demo_add_asset_deps(test_wav_dump audio)
+add_dependencies(test_wav_dump generate_tracker_music)
add_demo_test(test_jittered_audio JitteredAudioBackendTest audio src/tests/audio/test_jittered_audio.cc src/audio/backend/jittered_audio_backend.cc ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_jittered_audio PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_jittered_audio generate_demo_assets generate_tracker_music)
+demo_add_asset_deps(test_jittered_audio audio)
+add_dependencies(test_jittered_audio generate_tracker_music)
add_demo_test(test_tracker_timing TrackerTimingTest audio src/tests/audio/test_tracker_timing.cc src/tests/common/audio_test_fixture.cc src/audio/backend/mock_audio_backend.cc ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_tracker_timing PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_tracker_timing generate_demo_assets generate_tracker_music)
+demo_add_asset_deps(test_tracker_timing audio)
+add_dependencies(test_tracker_timing generate_tracker_music)
add_demo_test(test_variable_tempo VariableTempoTest audio src/tests/audio/test_variable_tempo.cc src/tests/common/audio_test_fixture.cc src/audio/backend/mock_audio_backend.cc ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_variable_tempo PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_variable_tempo generate_demo_assets generate_tracker_music)
+demo_add_asset_deps(test_variable_tempo audio)
+add_dependencies(test_variable_tempo generate_tracker_music)
add_demo_test(test_tracker TrackerSystemTest audio src/tests/audio/test_tracker.cc src/tests/common/audio_test_fixture.cc ${GEN_DEMO_CC} ${GENERATED_TEST_DEMO_MUSIC_CC})
target_link_libraries(test_tracker PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_tracker generate_demo_assets generate_test_demo_music)
+demo_add_asset_deps(test_tracker audio)
+add_dependencies(test_tracker generate_test_demo_music)
add_demo_test(test_audio_engine AudioEngineTest audio src/tests/audio/test_audio_engine.cc src/tests/common/audio_test_fixture.cc ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_audio_engine PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_audio_engine generate_demo_assets generate_tracker_music)
+demo_add_asset_deps(test_audio_engine audio)
+add_dependencies(test_audio_engine generate_tracker_music)
add_demo_test(test_shader_assets ShaderAssetValidation gpu src/tests/gpu/test_shader_assets.cc ${GEN_DEMO_CC})
target_link_libraries(test_shader_assets PRIVATE util procedural ${DEMO_LIBS})
-add_dependencies(test_shader_assets generate_demo_assets)
+demo_add_asset_deps(test_shader_assets shaders)
add_demo_test(test_shader_compilation ShaderCompilationTest gpu src/tests/gpu/test_shader_compilation.cc ${PLATFORM_SOURCES} ${GEN_DEMO_CC})
target_link_libraries(test_shader_compilation PRIVATE gpu util procedural ${DEMO_LIBS})
-add_dependencies(test_shader_compilation generate_demo_assets)
+demo_add_asset_deps(test_shader_compilation shaders)
add_demo_test(test_noise_functions NoiseFunctionsTest gpu src/tests/gpu/test_noise_functions.cc ${PLATFORM_SOURCES} ${GEN_DEMO_CC})
target_link_libraries(test_noise_functions PRIVATE gpu util procedural ${DEMO_LIBS})
-add_dependencies(test_noise_functions generate_demo_assets)
+demo_add_asset_deps(test_noise_functions shaders)
add_demo_test(test_uniform_helper UniformHelperTest gpu src/tests/gpu/test_uniform_helper.cc)
target_link_libraries(test_uniform_helper PRIVATE gpu util ${DEMO_LIBS})
@@ -84,18 +91,20 @@ target_link_libraries(test_uniform_helper PRIVATE gpu util ${DEMO_LIBS})
add_demo_executable(test_spectool src/tests/gpu/test_spectool.cc ${PLATFORM_SOURCES} ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_compile_definitions(test_spectool PRIVATE DEMO_BUILD_TOOLS)
target_link_libraries(test_spectool PRIVATE audio util procedural ${DEMO_LIBS})
-add_dependencies(test_spectool generate_tracker_music generate_demo_assets)
+demo_add_asset_deps(test_spectool audio)
+add_dependencies(test_spectool generate_tracker_music)
add_demo_test(test_assets AssetManagerTest assets src/tests/assets/test_assets.cc ${GEN_TEST_CC})
target_include_directories(test_assets PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src/generated_test)
target_compile_definitions(test_assets PRIVATE USE_TEST_ASSETS)
target_link_libraries(test_assets PRIVATE util procedural ${DEMO_LIBS})
-add_dependencies(test_assets generate_test_assets)
+demo_add_asset_deps(test_assets test)
set_source_files_properties(src/tests/assets/test_assets.cc PROPERTIES COMPILE_DEFINITIONS "USE_TEST_ASSETS")
add_demo_test(test_sequence SequenceSystemTest assets src/tests/assets/test_sequence.cc ${GEN_DEMO_CC} ${GENERATED_TIMELINE_CC} ${PLATFORM_SOURCES})
target_link_libraries(test_sequence PRIVATE 3d gpu util procedural ${DEMO_LIBS})
-add_dependencies(test_sequence generate_timeline generate_demo_assets)
+demo_add_asset_deps(test_sequence all)
+add_dependencies(test_sequence generate_timeline)
add_demo_test(test_procedural ProceduralGenTest util src/tests/util/test_procedural.cc)
target_link_libraries(test_procedural PRIVATE procedural ${DEMO_LIBS})
@@ -109,27 +118,30 @@ add_demo_test(test_shader_composer ShaderComposerTest gpu src/tests/gpu/test_sha
target_compile_definitions(test_shader_composer PRIVATE USE_TEST_ASSETS)
target_include_directories(test_shader_composer PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src/generated_test ${CORE_INCLUDES})
target_link_libraries(test_shader_composer PRIVATE gpu util procedural ${DEMO_LIBS})
-add_dependencies(test_shader_composer generate_test_assets)
+demo_add_asset_deps(test_shader_composer test)
add_demo_executable(test_3d_render src/tests/3d/test_3d_render.cc src/tests/common/test_3d_helpers.cc ${PLATFORM_SOURCES} ${GENERATED_TIMELINE_CC} ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_3d_render PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
-add_dependencies(test_3d_render generate_timeline generate_demo_assets generate_tracker_music)
+demo_add_asset_deps(test_3d_render all)
+add_dependencies(test_3d_render generate_timeline generate_tracker_music)
add_demo_executable(test_3d_physics src/tests/3d/test_3d_physics.cc src/tests/common/test_3d_helpers.cc ${PLATFORM_SOURCES} ${GENERATED_TIMELINE_CC} ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_3d_physics PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
-add_dependencies(test_3d_physics generate_timeline generate_demo_assets generate_tracker_music)
+demo_add_asset_deps(test_3d_physics all)
+add_dependencies(test_3d_physics generate_timeline generate_tracker_music)
add_demo_executable(test_mesh src/tests/3d/test_mesh.cc src/tests/common/test_3d_helpers.cc ${PLATFORM_SOURCES} ${GENERATED_TIMELINE_CC} ${GEN_DEMO_CC} ${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_mesh PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
-add_dependencies(test_mesh generate_timeline generate_demo_assets generate_tracker_music)
+demo_add_asset_deps(test_mesh all)
+add_dependencies(test_mesh generate_timeline generate_tracker_music)
add_demo_executable(test_platform src/tests/util/test_platform.cc ${PLATFORM_SOURCES})
target_link_libraries(test_platform PRIVATE util ${DEMO_LIBS})
add_demo_executable(test_scene_loader src/tests/3d/test_scene_loader.cc ${PLATFORM_SOURCES} ${GEN_DEMO_CC})
target_link_libraries(test_scene_loader PRIVATE 3d util procedural ${DEMO_LIBS})
-add_dependencies(test_scene_loader generate_demo_assets)
+demo_add_asset_deps(test_scene_loader models)
add_test(NAME SceneLoaderTest COMMAND test_scene_loader)
set_tests_properties(SceneLoaderTest PROPERTIES LABELS "3d")
@@ -144,7 +156,8 @@ add_demo_test(test_effect_base EffectBaseTest gpu
${GENERATED_TIMELINE_CC}
${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_effect_base PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
-add_dependencies(test_effect_base generate_timeline generate_demo_assets generate_tracker_music)
+demo_add_asset_deps(test_effect_base shaders)
+add_dependencies(test_effect_base generate_timeline generate_tracker_music)
# GPU Effects Test Infrastructure (Phase 2.1: Effect Classes)
add_demo_test(test_demo_effects DemoEffectsTest gpu
@@ -157,7 +170,8 @@ add_demo_test(test_demo_effects DemoEffectsTest gpu
${GENERATED_TIMELINE_CC}
${GENERATED_MUSIC_DATA_CC})
target_link_libraries(test_demo_effects PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
-add_dependencies(test_demo_effects generate_timeline generate_demo_assets generate_tracker_music)
+demo_add_asset_deps(test_demo_effects shaders)
+add_dependencies(test_demo_effects generate_timeline generate_tracker_music)
# GPU Effects Test Infrastructure (Phase 2.2: Post-Process Utilities)
add_demo_test(test_post_process_helper PostProcessHelperTest gpu
@@ -167,7 +181,7 @@ add_demo_test(test_post_process_helper PostProcessHelperTest gpu
${PLATFORM_SOURCES}
${GEN_DEMO_CC})
target_link_libraries(test_post_process_helper PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
-add_dependencies(test_post_process_helper generate_demo_assets)
+demo_add_asset_deps(test_post_process_helper shaders)
# TextureManager tests
add_demo_test(test_texture_manager TextureManagerTest gpu
@@ -176,7 +190,7 @@ add_demo_test(test_texture_manager TextureManagerTest gpu
${PLATFORM_SOURCES}
${GEN_DEMO_CC})
target_link_libraries(test_texture_manager PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
-add_dependencies(test_texture_manager generate_demo_assets)
+demo_add_asset_deps(test_texture_manager shaders)
# GPU Procedural Texture Test
add_demo_test(test_gpu_procedural GpuProceduralTest gpu
@@ -184,7 +198,7 @@ add_demo_test(test_gpu_procedural GpuProceduralTest gpu
${PLATFORM_SOURCES}
${GEN_DEMO_CC})
target_link_libraries(test_gpu_procedural PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
-add_dependencies(test_gpu_procedural generate_demo_assets)
+demo_add_asset_deps(test_gpu_procedural shaders)
# CNN shader testing tool (only when STRIP_ALL is OFF)
if(NOT DEMO_STRIP_ALL)
@@ -204,7 +218,7 @@ if(NOT DEMO_STRIP_ALL)
target_link_libraries(cnn_test PRIVATE
gpu util procedural ${DEMO_LIBS})
- add_dependencies(cnn_test generate_demo_assets)
+ demo_add_asset_deps(cnn_test shaders)
# Define STB_IMAGE macros
target_compile_definitions(cnn_test PRIVATE
@@ -218,7 +232,7 @@ add_demo_test(test_gpu_composite GpuCompositeTest gpu
${PLATFORM_SOURCES}
${GEN_DEMO_CC})
target_link_libraries(test_gpu_composite PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
-add_dependencies(test_gpu_composite generate_demo_assets)
+demo_add_asset_deps(test_gpu_composite shaders)
# Subsystem test targets
diff --git a/cnn_v1/README.md b/cnn_v1/README.md
new file mode 100644
index 0000000..052f22a
--- /dev/null
+++ b/cnn_v1/README.md
@@ -0,0 +1,64 @@
+# CNN v1: Original Post-Processing Neural Network
+
+**Architecture:** 3-layer convolution, generated shader weights
+**Status:** Active (used in timeline), legacy architecture
+
+## Overview
+
+Original CNN implementation with per-layer WGSL shaders. Supports multiple kernel sizes (1×1, 3×3, 5×5, 7×7) with generated weight arrays.
+
+**For new work, use CNN v2** (`cnn_v2/`) which provides:
+- Storage buffer architecture (~3.2 KB vs generated WGSL)
+- 7D static features (RGBD + UV + sin + bias)
+- Sigmoid activation with stable training
+- Dynamic layer configuration
+
+## Quick Reference
+
+**Training:**
+```bash
+./cnn_v1/training/train_cnn.py --input training/input --target training/output \
+ --layers 3 --kernel_sizes 3,5,3 --epochs 5000
+```
+
+**Integration:**
+- **C++:** `cnn_v1/src/cnn_effect.{h,cc}`
+- **Assets:** `workspaces/main/assets.txt` (lines 40-46)
+- **Timeline:** `workspaces/main/timeline.seq` (CNNEffect)
+
+## Documentation
+
+- [CNN.md](docs/CNN.md) - Architecture overview
+- [CNN_V1_EFFECT.md](docs/CNN_V1_EFFECT.md) - Implementation details
+- [CNN_TEST_TOOL.md](docs/CNN_TEST_TOOL.md) - Testing guide
+- [CNN_DEBUG.md](docs/CNN_DEBUG.md) - Debugging notes
+
+## Directory Structure
+
+```
+cnn_v1/
+├── README.md # This file
+├── src/
+│ ├── cnn_effect.h # Effect header
+│ └── cnn_effect.cc # Effect implementation
+├── shaders/ # WGSL shaders (7 files)
+├── training/ # Python training script
+└── docs/ # Documentation (7 markdown files)
+```
+
+## Differences from CNN v2
+
+| Feature | CNN v1 | CNN v2 |
+|---------|--------|--------|
+| Architecture | Generated WGSL weights | Storage buffer weights |
+| Input Features | 4D (RGBA/prev layer) | 12D (4D + 8D static) |
+| Activation | ReLU | Sigmoid + ReLU |
+| Size | ~Variable (WGSL gen) | ~3.2 KB (binary) |
+| Training | Full-image | Patch-based (default) |
+| Layer Config | Compile-time | Runtime (dynamic) |
+
+## Migration Notes
+
+CNN v1 remains in the timeline for historical validation. For new effects or experiments, use CNN v2's enhanced feature set and compact binary format.
+
+See `cnn_v2/docs/CNN_V2.md` for CNN v2 architecture details.
diff --git a/doc/CNN.md b/cnn_v1/docs/CNN.md
index 2dc3362..5d9a667 100644
--- a/doc/CNN.md
+++ b/cnn_v1/docs/CNN.md
@@ -8,7 +8,7 @@ Have the input 3d scene be processed by a multi-layer CNN trained on the side.
Input: some rendered scene.
Output: 'stylized' scene with CNN post-processing.
-**See `doc/CNN_EFFECT.md` for implementation details, usage, and API reference.**
+**See `CNN_V1_EFFECT.md` for implementation details, usage, and API reference.**
## Shader implementation
diff --git a/doc/CNN_BIAS_FIX_2026-02.md b/cnn_v1/docs/CNN_BIAS_FIX_2026-02.md
index 26db8eb..26db8eb 100644
--- a/doc/CNN_BIAS_FIX_2026-02.md
+++ b/cnn_v1/docs/CNN_BIAS_FIX_2026-02.md
diff --git a/doc/CNN_DEBUG.md b/cnn_v1/docs/CNN_DEBUG.md
index ba220a0..ba220a0 100644
--- a/doc/CNN_DEBUG.md
+++ b/cnn_v1/docs/CNN_DEBUG.md
diff --git a/doc/CNN_FLATTEN_ANALYSIS.md b/cnn_v1/docs/CNN_FLATTEN_ANALYSIS.md
index bf63c5d..8664157 100644
--- a/doc/CNN_FLATTEN_ANALYSIS.md
+++ b/cnn_v1/docs/CNN_FLATTEN_ANALYSIS.md
@@ -183,7 +183,7 @@ These yield better size/performance than shader architecture changes.
## References
-- `doc/CNN_EFFECT.md` - CNN implementation details
-- `doc/CNN.md` - High-level CNN design
-- `src/effects/cnn_effect.cc` - Current implementation
+- `CNN_V1_EFFECT.md` - CNN implementation details
+- `CNN.md` - High-level CNN design
+- `../src/cnn_effect.cc` - Current implementation
- `workspaces/main/shaders/cnn_*.wgsl` - Shader snippets
diff --git a/doc/CNN_RGBD_GRAYSCALE_SUMMARY.md b/cnn_v1/docs/CNN_RGBD_GRAYSCALE_SUMMARY.md
index 3439f2c..3439f2c 100644
--- a/doc/CNN_RGBD_GRAYSCALE_SUMMARY.md
+++ b/cnn_v1/docs/CNN_RGBD_GRAYSCALE_SUMMARY.md
diff --git a/doc/CNN_TEST_TOOL.md b/cnn_v1/docs/CNN_TEST_TOOL.md
index 4307894..4307894 100644
--- a/doc/CNN_TEST_TOOL.md
+++ b/cnn_v1/docs/CNN_TEST_TOOL.md
diff --git a/doc/CNN_EFFECT.md b/cnn_v1/docs/CNN_V1_EFFECT.md
index 40f095e..40f095e 100644
--- a/doc/CNN_EFFECT.md
+++ b/cnn_v1/docs/CNN_V1_EFFECT.md
diff --git a/workspaces/main/shaders/cnn/cnn_activation.wgsl b/cnn_v1/shaders/cnn_activation.wgsl
index 4fe771e..4fe771e 100644
--- a/workspaces/main/shaders/cnn/cnn_activation.wgsl
+++ b/cnn_v1/shaders/cnn_activation.wgsl
diff --git a/workspaces/main/shaders/cnn/cnn_conv1x1.wgsl b/cnn_v1/shaders/cnn_conv1x1.wgsl
index f77cfa8..f77cfa8 100644
--- a/workspaces/main/shaders/cnn/cnn_conv1x1.wgsl
+++ b/cnn_v1/shaders/cnn_conv1x1.wgsl
diff --git a/workspaces/main/shaders/cnn/cnn_conv3x3.wgsl b/cnn_v1/shaders/cnn_conv3x3.wgsl
index f7d11b1..f7d11b1 100644
--- a/workspaces/main/shaders/cnn/cnn_conv3x3.wgsl
+++ b/cnn_v1/shaders/cnn_conv3x3.wgsl
diff --git a/workspaces/main/shaders/cnn/cnn_conv5x5.wgsl b/cnn_v1/shaders/cnn_conv5x5.wgsl
index 9328d75..9328d75 100644
--- a/workspaces/main/shaders/cnn/cnn_conv5x5.wgsl
+++ b/cnn_v1/shaders/cnn_conv5x5.wgsl
diff --git a/workspaces/main/shaders/cnn/cnn_conv7x7.wgsl b/cnn_v1/shaders/cnn_conv7x7.wgsl
index e68d644..e68d644 100644
--- a/workspaces/main/shaders/cnn/cnn_conv7x7.wgsl
+++ b/cnn_v1/shaders/cnn_conv7x7.wgsl
diff --git a/workspaces/main/shaders/cnn/cnn_layer.wgsl b/cnn_v1/shaders/cnn_layer.wgsl
index cbd1686..cbd1686 100644
--- a/workspaces/main/shaders/cnn/cnn_layer.wgsl
+++ b/cnn_v1/shaders/cnn_layer.wgsl
diff --git a/workspaces/main/shaders/cnn/cnn_weights_generated.wgsl b/cnn_v1/shaders/cnn_weights_generated.wgsl
index 510f86f..510f86f 100644
--- a/workspaces/main/shaders/cnn/cnn_weights_generated.wgsl
+++ b/cnn_v1/shaders/cnn_weights_generated.wgsl
diff --git a/src/effects/cnn_effect.cc b/cnn_v1/src/cnn_v1_effect.cc
index 49c5239..1f44619 100644
--- a/src/effects/cnn_effect.cc
+++ b/cnn_v1/src/cnn_v1_effect.cc
@@ -1,7 +1,7 @@
// CNN post-processing effect implementation
// Neural network-based stylization with modular WGSL
-#include "effects/cnn_effect.h"
+#include "cnn_v1_effect.h"
#include "gpu/bind_group_builder.h"
#include "gpu/effect.h"
#include "gpu/pipeline_builder.h"
@@ -33,7 +33,7 @@ static WGPURenderPipeline create_cnn_pipeline(WGPUDevice device,
return pipeline;
}
-CNNEffect::CNNEffect(const GpuContext& ctx)
+CNNv1Effect::CNNv1Effect(const GpuContext& ctx)
: PostProcessEffect(ctx), layer_index_(0), total_layers_(1),
blend_amount_(1.0f), input_view_(nullptr), original_view_(nullptr),
bind_group_(nullptr) {
@@ -41,7 +41,7 @@ CNNEffect::CNNEffect(const GpuContext& ctx)
create_cnn_pipeline(ctx_.device, ctx_.format, cnn_layer_shader_wgsl);
}
-CNNEffect::CNNEffect(const GpuContext& ctx, const CNNEffectParams& params)
+CNNv1Effect::CNNv1Effect(const GpuContext& ctx, const CNNv1EffectParams& params)
: PostProcessEffect(ctx), layer_index_(params.layer_index),
total_layers_(params.total_layers), blend_amount_(params.blend_amount),
input_view_(nullptr), original_view_(nullptr), bind_group_(nullptr) {
@@ -49,7 +49,7 @@ CNNEffect::CNNEffect(const GpuContext& ctx, const CNNEffectParams& params)
create_cnn_pipeline(ctx_.device, ctx_.format, cnn_layer_shader_wgsl);
}
-void CNNEffect::init(MainSequence* demo) {
+void CNNv1Effect::init(MainSequence* demo) {
PostProcessEffect::init(demo);
demo_ = demo;
params_buffer_.init(ctx_.device);
@@ -62,11 +62,11 @@ void CNNEffect::init(MainSequence* demo) {
// Initialize uniforms BEFORE any bind group creation
uniforms_.update(ctx_.queue, get_common_uniforms());
- CNNLayerParams params = {layer_index_, blend_amount_, {0.0f, 0.0f}};
+ CNNv1LayerParams params = {layer_index_, blend_amount_, {0.0f, 0.0f}};
params_buffer_.update(ctx_.queue, params);
}
-void CNNEffect::resize(int width, int height) {
+void CNNv1Effect::resize(int width, int height) {
if (width == width_ && height == height_)
return;
@@ -78,7 +78,7 @@ void CNNEffect::resize(int width, int height) {
}
}
-void CNNEffect::render(WGPURenderPassEncoder pass,
+void CNNv1Effect::render(WGPURenderPassEncoder pass,
const CommonPostProcessUniforms& uniforms) {
if (!bind_group_) {
fprintf(stderr, "CNN render: no bind_group\n");
@@ -90,7 +90,7 @@ void CNNEffect::render(WGPURenderPassEncoder pass,
effective_blend = blend_amount_ * uniforms.beat_phase * beat_scale_;
}
- CNNLayerParams params = {layer_index_, effective_blend, {0.0f, 0.0f}};
+ CNNv1LayerParams params = {layer_index_, effective_blend, {0.0f, 0.0f}};
params_buffer_.update(ctx_.queue, params);
wgpuRenderPassEncoderSetPipeline(pass, pipeline_);
@@ -98,7 +98,7 @@ void CNNEffect::render(WGPURenderPassEncoder pass,
wgpuRenderPassEncoderDraw(pass, 3, 1, 0, 0);
}
-void CNNEffect::update_bind_group(WGPUTextureView input_view) {
+void CNNv1Effect::update_bind_group(WGPUTextureView input_view) {
input_view_ = input_view;
// Update common uniforms (CRITICAL for UV calculation!)
diff --git a/src/effects/cnn_effect.h b/cnn_v1/src/cnn_v1_effect.h
index cdcd656..e820275 100644
--- a/src/effects/cnn_effect.h
+++ b/cnn_v1/src/cnn_v1_effect.h
@@ -5,23 +5,23 @@
#include "gpu/effect.h"
#include "gpu/uniform_helper.h"
-struct CNNLayerParams {
+struct CNNv1LayerParams {
int layer_index;
float blend_amount; // Blend: mix(input, output, blend_amount)
float _pad[2];
};
-static_assert(sizeof(CNNLayerParams) == 16);
+static_assert(sizeof(CNNv1LayerParams) == 16);
-struct CNNEffectParams {
+struct CNNv1EffectParams {
int layer_index = 0; // Which layer to render (0-based)
int total_layers = 1; // Total number of layers in the CNN
float blend_amount = 1.0f; // Final blend with original input
};
-class CNNEffect : public PostProcessEffect {
+class CNNv1Effect : public PostProcessEffect {
public:
- explicit CNNEffect(const GpuContext& ctx);
- explicit CNNEffect(const GpuContext& ctx, const CNNEffectParams& params);
+ explicit CNNv1Effect(const GpuContext& ctx);
+ explicit CNNv1Effect(const GpuContext& ctx, const CNNv1EffectParams& params);
void init(MainSequence* demo) override;
void resize(int width, int height) override;
@@ -47,7 +47,7 @@ class CNNEffect : public PostProcessEffect {
float beat_scale_ = 1.0f;
WGPUTextureView input_view_;
WGPUTextureView original_view_;
- UniformBuffer<CNNLayerParams> params_buffer_;
+ UniformBuffer<CNNv1LayerParams> params_buffer_;
WGPUBindGroup bind_group_;
MainSequence* demo_ = nullptr;
};
diff --git a/training/train_cnn.py b/cnn_v1/training/train_cnn.py
index 4171dcb..4171dcb 100755
--- a/training/train_cnn.py
+++ b/cnn_v1/training/train_cnn.py
diff --git a/cnn_v2/README.md b/cnn_v2/README.md
new file mode 100644
index 0000000..ef0cf44
--- /dev/null
+++ b/cnn_v2/README.md
@@ -0,0 +1,60 @@
+# CNN v2: Parametric Post-Processing Neural Network
+
+**Architecture:** 3-layer compute, storage buffer (~3.2 KB)
+**Features:** 7D static (RGBD + UV + sin + bias), sigmoid activation
+
+## Quick Start
+
+```bash
+./cnn_v2/scripts/train_cnn_v2_full.sh
+```
+
+## Documentation
+
+- [CNN_V2.md](docs/CNN_V2.md) - Architecture and implementation details
+- [CNN_V2_BINARY_FORMAT.md](docs/CNN_V2_BINARY_FORMAT.md) - Weight format specification
+- [CNN_V2_WEB_TOOL.md](docs/CNN_V2_WEB_TOOL.md) - Validation tool documentation
+- [CNN_V2_DEBUG_TOOLS.md](docs/CNN_V2_DEBUG_TOOLS.md) - Debugging and analysis tools
+
+## Integration
+
+- **C++:** `cnn_v2/src/cnn_v2_effect.{h,cc}`
+- **Assets:** `workspaces/main/assets.txt` (lines 47-49)
+- **Test:** `src/tests/gpu/test_demo_effects.cc` (line 93)
+
+## Directory Structure
+
+```
+cnn_v2/
+├── README.md # This file
+├── src/
+│ ├── cnn_v2_effect.h # Effect header
+│ └── cnn_v2_effect.cc # Effect implementation
+├── shaders/ # WGSL shaders (6 files)
+├── weights/ # Binary weights (3 files)
+├── training/ # Python training scripts (4 files)
+├── scripts/ # Shell scripts (train_cnn_v2_full.sh)
+├── tools/ # Validation tools (HTML)
+└── docs/ # Documentation (4 markdown files)
+```
+
+## Training Pipeline
+
+1. **Train model:** `./cnn_v2/scripts/train_cnn_v2_full.sh`
+2. **Export weights:** Automatic (binary format, ~3.2 KB)
+3. **Validate:** HTML tool at `cnn_v2/tools/cnn_v2_test/index.html`
+
+For detailed training options: `./cnn_v2/scripts/train_cnn_v2_full.sh --help`
+
+## Key Features
+
+- **Parametric static features:** 7D input (RGBD + UV + sin encoding + bias)
+- **Storage buffer architecture:** Dynamic layer count, compact binary format
+- **Sigmoid activation:** Smooth gradients, prevents training collapse
+- **Patch-based training:** Sample-efficient, focuses on salient regions
+- **Sub-10KB target:** Achieved with 3-layer model (~3.2 KB)
+
+## Next Steps
+
+- **8-bit quantization:** 2× size reduction (~1.6 KB) via quantization-aware training (QAT)
+- **CNN v3:** U-Net architecture for enhanced quality (separate directory)
diff --git a/doc/CNN_V2.md b/cnn_v2/docs/CNN_V2.md
index b7fd6f8..b7fd6f8 100644
--- a/doc/CNN_V2.md
+++ b/cnn_v2/docs/CNN_V2.md
diff --git a/doc/CNN_V2_BINARY_FORMAT.md b/cnn_v2/docs/CNN_V2_BINARY_FORMAT.md
index 59c859d..59c859d 100644
--- a/doc/CNN_V2_BINARY_FORMAT.md
+++ b/cnn_v2/docs/CNN_V2_BINARY_FORMAT.md
diff --git a/doc/CNN_V2_DEBUG_TOOLS.md b/cnn_v2/docs/CNN_V2_DEBUG_TOOLS.md
index 8d1289a..8d1289a 100644
--- a/doc/CNN_V2_DEBUG_TOOLS.md
+++ b/cnn_v2/docs/CNN_V2_DEBUG_TOOLS.md
diff --git a/doc/CNN_V2_WEB_TOOL.md b/cnn_v2/docs/CNN_V2_WEB_TOOL.md
index b6f5b0b..b6f5b0b 100644
--- a/doc/CNN_V2_WEB_TOOL.md
+++ b/cnn_v2/docs/CNN_V2_WEB_TOOL.md
diff --git a/scripts/train_cnn_v2_full.sh b/cnn_v2/scripts/train_cnn_v2_full.sh
index 078ea28..a21c1ac 100755
--- a/scripts/train_cnn_v2_full.sh
+++ b/cnn_v2/scripts/train_cnn_v2_full.sh
@@ -53,7 +53,7 @@ cd "$PROJECT_ROOT"
# Helper functions
export_weights() {
- python3 training/export_cnn_v2_weights.py "$1" --output-weights "$2" --quiet
+ python3 "$SCRIPT_DIR/../training/export_cnn_v2_weights.py" "$1" --output-weights "$2" --quiet
}
find_latest_checkpoint() {
@@ -64,6 +64,10 @@ build_target() {
cmake --build build -j4 --target "$1" > /dev/null 2>&1
}
+# Path resolution for running from any directory
+SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
+PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
+
# Default configuration
INPUT_DIR="training/input"
TARGET_DIR="training/target_1"
@@ -82,7 +86,7 @@ MIP_LEVEL=0
GRAYSCALE_LOSS=false
FULL_IMAGE_MODE=false
IMAGE_SIZE=256
-OUTPUT_WEIGHTS="workspaces/main/weights/cnn_v2_weights.bin"
+OUTPUT_WEIGHTS="${PROJECT_ROOT}/workspaces/main/weights/cnn_v2_weights.bin"
# Parse arguments
VALIDATE_ONLY=false
@@ -306,7 +310,7 @@ if [ "$VALIDATE_ONLY" = false ]; then
# Step 1: Train model
echo "[1/4] Training CNN v2 model..."
-python3 training/train_cnn_v2.py \
+python3 "$SCRIPT_DIR/../training/train_cnn_v2.py" \
--input "$INPUT_DIR" \
--target "$TARGET_DIR" \
$TRAINING_MODE_ARGS \
diff --git a/workspaces/main/shaders/cnn_v2/cnn_v2_compute.wgsl b/cnn_v2/shaders/cnn_v2_compute.wgsl
index cdbfd74..cdbfd74 100644
--- a/workspaces/main/shaders/cnn_v2/cnn_v2_compute.wgsl
+++ b/cnn_v2/shaders/cnn_v2_compute.wgsl
diff --git a/workspaces/main/shaders/cnn_v2/cnn_v2_layer_0.wgsl b/cnn_v2/shaders/cnn_v2_layer_0.wgsl
index 8e14957..8e14957 100644
--- a/workspaces/main/shaders/cnn_v2/cnn_v2_layer_0.wgsl
+++ b/cnn_v2/shaders/cnn_v2_layer_0.wgsl
diff --git a/workspaces/main/shaders/cnn_v2/cnn_v2_layer_1.wgsl b/cnn_v2/shaders/cnn_v2_layer_1.wgsl
index f490d13..f490d13 100644
--- a/workspaces/main/shaders/cnn_v2/cnn_v2_layer_1.wgsl
+++ b/cnn_v2/shaders/cnn_v2_layer_1.wgsl
diff --git a/workspaces/main/shaders/cnn_v2/cnn_v2_layer_2.wgsl b/cnn_v2/shaders/cnn_v2_layer_2.wgsl
index 2f9836a..2f9836a 100644
--- a/workspaces/main/shaders/cnn_v2/cnn_v2_layer_2.wgsl
+++ b/cnn_v2/shaders/cnn_v2_layer_2.wgsl
diff --git a/workspaces/main/shaders/cnn_v2/cnn_v2_layer_template.wgsl b/cnn_v2/shaders/cnn_v2_layer_template.wgsl
index 1bf6819..1bf6819 100644
--- a/workspaces/main/shaders/cnn_v2/cnn_v2_layer_template.wgsl
+++ b/cnn_v2/shaders/cnn_v2_layer_template.wgsl
diff --git a/workspaces/main/shaders/cnn_v2/cnn_v2_static.wgsl b/cnn_v2/shaders/cnn_v2_static.wgsl
index 309e832..309e832 100644
--- a/workspaces/main/shaders/cnn_v2/cnn_v2_static.wgsl
+++ b/cnn_v2/shaders/cnn_v2_static.wgsl
diff --git a/src/effects/cnn_v2_effect.cc b/cnn_v2/src/cnn_v2_effect.cc
index 7127aae..60538d4 100644
--- a/src/effects/cnn_v2_effect.cc
+++ b/cnn_v2/src/cnn_v2_effect.cc
@@ -1,6 +1,6 @@
// CNN v2 Effect Implementation
-#include "effects/cnn_v2_effect.h"
+#include "cnn_v2_effect.h"
#if defined(USE_TEST_ASSETS)
#include "test_assets.h"
diff --git a/src/effects/cnn_v2_effect.h b/cnn_v2/src/cnn_v2_effect.h
index 7960b4f..7960b4f 100644
--- a/src/effects/cnn_v2_effect.h
+++ b/cnn_v2/src/cnn_v2_effect.h
diff --git a/tools/cnn_v2_test/README.md b/cnn_v2/tools/cnn_v2_test/README.md
index d41a00f..d41a00f 100644
--- a/tools/cnn_v2_test/README.md
+++ b/cnn_v2/tools/cnn_v2_test/README.md
diff --git a/tools/cnn_v2_test/index.html b/cnn_v2/tools/cnn_v2_test/index.html
index 84702d5..84702d5 100644
--- a/tools/cnn_v2_test/index.html
+++ b/cnn_v2/tools/cnn_v2_test/index.html
diff --git a/training/export_cnn_v2_shader.py b/cnn_v2/training/export_cnn_v2_shader.py
index 1c74ad0..8692a62 100755
--- a/training/export_cnn_v2_shader.py
+++ b/cnn_v2/training/export_cnn_v2_shader.py
@@ -13,6 +13,10 @@ import numpy as np
import torch
from pathlib import Path
+# Path resolution for running from any directory
+SCRIPT_DIR = Path(__file__).parent
+PROJECT_ROOT = SCRIPT_DIR.parent.parent
+
def export_layer_shader(layer_idx, weights, kernel_size, output_dir, mip_level=0, is_output_layer=False):
"""Generate WGSL compute shader for a single CNN layer.
@@ -203,7 +207,7 @@ def export_checkpoint(checkpoint_path, output_dir):
def main():
parser = argparse.ArgumentParser(description='Export CNN v2 checkpoint to WGSL shaders')
parser.add_argument('checkpoint', type=str, help='Path to checkpoint .pth file')
- parser.add_argument('--output-dir', type=str, default='workspaces/main/shaders',
+ parser.add_argument('--output-dir', type=str, default=str(PROJECT_ROOT / 'workspaces/main/shaders'),
help='Output directory for shaders')
args = parser.parse_args()
diff --git a/training/export_cnn_v2_weights.py b/cnn_v2/training/export_cnn_v2_weights.py
index f64bd8d..d66b980 100755
--- a/training/export_cnn_v2_weights.py
+++ b/cnn_v2/training/export_cnn_v2_weights.py
@@ -11,6 +11,10 @@ import torch
import struct
from pathlib import Path
+# Path resolution for running from any directory
+SCRIPT_DIR = Path(__file__).parent
+PROJECT_ROOT = SCRIPT_DIR.parent.parent
+
def export_weights_binary(checkpoint_path, output_path, quiet=False):
"""Export CNN v2 weights to binary format.
@@ -261,9 +265,9 @@ fn main(@builtin(global_invocation_id) id: vec3<u32>) {
def main():
parser = argparse.ArgumentParser(description='Export CNN v2 weights to binary format')
parser.add_argument('checkpoint', type=str, help='Path to checkpoint .pth file')
- parser.add_argument('--output-weights', type=str, default='workspaces/main/weights/cnn_v2_weights.bin',
+ parser.add_argument('--output-weights', type=str, default=str(PROJECT_ROOT / 'workspaces/main/weights/cnn_v2_weights.bin'),
help='Output binary weights file')
- parser.add_argument('--output-shader', type=str, default='workspaces/main/shaders',
+ parser.add_argument('--output-shader', type=str, default=str(PROJECT_ROOT / 'workspaces/main/shaders'),
help='Output directory for shader template')
parser.add_argument('--quiet', action='store_true',
help='Suppress detailed output')
diff --git a/training/gen_identity_weights.py b/cnn_v2/training/gen_identity_weights.py
index 7865d68..08eecc6 100755
--- a/training/gen_identity_weights.py
+++ b/cnn_v2/training/gen_identity_weights.py
@@ -21,6 +21,10 @@ import numpy as np
import struct
from pathlib import Path
+# Path resolution for running from any directory
+SCRIPT_DIR = Path(__file__).parent
+PROJECT_ROOT = SCRIPT_DIR.parent.parent
+
def generate_identity_weights(output_path, kernel_size=1, mip_level=0, mix=False, p47=False):
"""Generate identity weights: output = input (ignores static features).
@@ -149,7 +153,7 @@ def generate_identity_weights(output_path, kernel_size=1, mip_level=0, mix=False
def main():
parser = argparse.ArgumentParser(description='Generate identity CNN v2 weights')
parser.add_argument('output', type=str, nargs='?',
- default='workspaces/main/weights/cnn_v2_identity.bin',
+ default=str(PROJECT_ROOT / 'workspaces/main/weights/cnn_v2_identity.bin'),
help='Output .bin file path')
parser.add_argument('--kernel-size', type=int, default=1,
help='Kernel size (default: 1×1)')
diff --git a/training/train_cnn_v2.py b/cnn_v2/training/train_cnn_v2.py
index 9e5df2f..9e5df2f 100755
--- a/training/train_cnn_v2.py
+++ b/cnn_v2/training/train_cnn_v2.py
diff --git a/cnn_v3/README.md b/cnn_v3/README.md
new file mode 100644
index 0000000..fdbf648
--- /dev/null
+++ b/cnn_v3/README.md
@@ -0,0 +1,36 @@
+# CNN v3
+
+Enhanced CNN post-processing with next-generation features.
+
+## Directory Structure
+
+```
+cnn_v3/
+├── docs/ # Documentation and design notes
+├── scripts/ # Training and build automation scripts
+├── shaders/ # WGSL compute shaders
+├── src/ # C++ implementation
+├── tools/ # Testing and validation tools
+├── training/ # Training pipeline
+│ ├── input/ # Source images for training
+│ ├── target_1/ # Style 1 target images
+│ └── target_2/ # Style 2 target images
+└── weights/ # Trained model weights (binary format)
+```
+
+## Training Data
+
+Training images are tracked in the repository:
+- `training/input/` - Original input images
+- `training/target_1/` - First style transformation targets
+- `training/target_2/` - Second style transformation targets
+
+Multiple target directories allow training different stylistic transformations from the same input set.
+
+Add images directly to these directories and commit them.
+
+## Status
+
+**TODO:** Define CNN v3 architecture and feature set.
+
+See `cnn_v2/` for reference implementation.
diff --git a/cnn_v3/training/input/photo1.jpg b/cnn_v3/training/input/photo1.jpg
new file mode 100644
index 0000000..1c1c2b2
--- /dev/null
+++ b/cnn_v3/training/input/photo1.jpg
Binary files differ
diff --git a/cnn_v3/training/input/photo2.jpg b/cnn_v3/training/input/photo2.jpg
new file mode 100644
index 0000000..a662fa8
--- /dev/null
+++ b/cnn_v3/training/input/photo2.jpg
Binary files differ
diff --git a/cnn_v3/training/input/photo3.jpg b/cnn_v3/training/input/photo3.jpg
new file mode 100644
index 0000000..703645e
--- /dev/null
+++ b/cnn_v3/training/input/photo3.jpg
Binary files differ
diff --git a/cnn_v3/training/input/photo4.jpg b/cnn_v3/training/input/photo4.jpg
new file mode 100644
index 0000000..5035993
--- /dev/null
+++ b/cnn_v3/training/input/photo4.jpg
Binary files differ
diff --git a/cnn_v3/training/target_1/photo1_out.png b/cnn_v3/training/target_1/photo1_out.png
new file mode 100644
index 0000000..36a36a7
--- /dev/null
+++ b/cnn_v3/training/target_1/photo1_out.png
Binary files differ
diff --git a/cnn_v3/training/target_1/photo2_1_out.png b/cnn_v3/training/target_1/photo2_1_out.png
new file mode 100644
index 0000000..5398232
--- /dev/null
+++ b/cnn_v3/training/target_1/photo2_1_out.png
Binary files differ
diff --git a/cnn_v3/training/target_1/photo2_2_out.png b/cnn_v3/training/target_1/photo2_2_out.png
new file mode 100644
index 0000000..b0a76bd
--- /dev/null
+++ b/cnn_v3/training/target_1/photo2_2_out.png
Binary files differ
diff --git a/cnn_v3/training/target_1/photo4_out.png b/cnn_v3/training/target_1/photo4_out.png
new file mode 100644
index 0000000..56f6274
--- /dev/null
+++ b/cnn_v3/training/target_1/photo4_out.png
Binary files differ
diff --git a/doc/AUXILIARY_TEXTURE_INIT.md b/doc/AUXILIARY_TEXTURE_INIT.md
index 9cac70b..036cbf7 100644
--- a/doc/AUXILIARY_TEXTURE_INIT.md
+++ b/doc/AUXILIARY_TEXTURE_INIT.md
@@ -18,7 +18,7 @@ entry.seq->resize(width, height); // Too late - textures already created
**Affected:**
- CircleMaskEffect (circle_mask texture)
-- CNNEffect (captured_frame texture)
+- CNNv1Effect (captured_frame texture)
- RotatingCubeEffect (consumer, hardcoded resolution in uniforms)
---
diff --git a/doc/BUILD.md b/doc/BUILD.md
index d3434f4..fd0c3d9 100644
--- a/doc/BUILD.md
+++ b/doc/BUILD.md
@@ -95,9 +95,11 @@ Use Xcode Metal debugger for shader performance analysis.
## Build System Internals
**Asset Dependency Tracking:**
-- CMake tracks 42 demo + 17 test assets
-- Editing shaders/audio/sequences auto-triggers rebuild
-- Asset lists parsed to extract individual file dependencies
+- CMake tracks 42 demo + 17 test assets split into 4 categories
+- **Granular rebuilds:** Changing a shader only rebuilds shader-dependent targets
+- **Categories:** `shaders` (.wgsl), `audio` (.spec, .track), `models` (.obj), `data` (.bin, .png, PROC)
+- Asset lists parsed at configure time to extract category-specific file dependencies
+- Unified output (`assets_data.cc`) avoids duplicate symbols while preserving granular tracking
**Header Organization:**
- `asset_manager_dcl.h`: Forward declarations
diff --git a/doc/CMAKE_MODULES.md b/doc/CMAKE_MODULES.md
index 2ea7d00..9f71d91 100644
--- a/doc/CMAKE_MODULES.md
+++ b/doc/CMAKE_MODULES.md
@@ -90,6 +90,18 @@ Creates an executable for the demo (legacy macro).
### `add_demo_test(NAME TEST_NAME LABEL SOURCES...)`
Creates a test executable and registers it with CTest (legacy macro).
+### `demo_add_asset_deps(TARGET CATEGORY)`
+Adds asset category dependencies to a target for granular rebuilds.
+
+**Categories:** `shaders`, `audio`, `models`, `data`, `all`, `test`
+
+**Example:**
+```cmake
+demo_add_asset_deps(test_synth audio) # Only depends on audio assets
+demo_add_asset_deps(test_shader_compilation shaders) # Only depends on shaders
+demo_add_asset_deps(demo64k all) # Depends on all asset categories
+```
+
---
## Conditional Inclusion
@@ -107,12 +119,13 @@ This reduces parse time when building without tests/tools.
## Adding New Components
### New Effect
-- Add sources to `cmake/DemoSourceLists.cmake` (GPU_SOURCES list)
-- No other CMake changes needed
+- Add sources to `cmake/DemoSourceLists.cmake` (`COMMON_GPU_EFFECTS` list)
+- No other CMake changes needed (automatically included in headless and normal modes)
### New Test
-- Add to `cmake/DemoTests.cmake` using `demo_add_test_with_deps()`
-- Use LINK and DEPENDS parameters for libraries/assets
+- Add to `cmake/DemoTests.cmake` using `add_demo_test()`
+- Use `demo_add_asset_deps()` to specify asset category dependencies (e.g., `shaders`, `audio`)
+- This enables granular rebuilds—only changed asset categories trigger test recompilation
### New Library
- Add to `cmake/DemoLibraries.cmake` with appropriate dependencies
@@ -132,6 +145,7 @@ This reduces parse time when building without tests/tools.
4. **Reusability:** Shared macros—eliminate 200+ lines of repetition
5. **Clarity:** Top-level CMakeLists.txt is 54-line roadmap
6. **Scalability:** Easy to add new tests/tools/libraries without bloating main file
+7. **Granular Rebuilds:** Asset categories enable 3-5× faster incremental builds for typical changes
---
diff --git a/doc/COMPLETED.md b/doc/COMPLETED.md
index 55fac50..8d30cca 100644
--- a/doc/COMPLETED.md
+++ b/doc/COMPLETED.md
@@ -67,7 +67,7 @@ Use `read @doc/archive/FILENAME.md` to access archived documents.
- **Changes**:
- Added `get_common_uniforms()` helper to Effect base class
- Refactored all render()/compute() signatures from 5 parameters to single `CommonPostProcessUniforms&`
- - Fixed uninitialized uniforms in CircleMaskEffect and CNNEffect
+ - Fixed uninitialized uniforms in CircleMaskEffect and CNNv1Effect
- Updated 19 effect implementations + headers
- Fixed WGSL syntax error in FlashEffect (u.audio_intensity → audio_intensity)
- **Impact**:
@@ -93,7 +93,7 @@ Use `read @doc/archive/FILENAME.md` to access archived documents.
- All 36 tests pass (100%)
- Processes 64×64 test image successfully
- Ready for ground-truth validation vs Python training script
- - Documented in `doc/CNN_TEST_TOOL.md`
+ - Documented in `cnn_v1/docs/CNN_TEST_TOOL.md`
## Recently Completed (February 10, 2026)
@@ -103,7 +103,7 @@ Use `read @doc/archive/FILENAME.md` to access archived documents.
- Created `BindGroupLayoutBuilder` and `BindGroupBuilder` for declarative bind group creation
- Created `RenderPipelineBuilder` to simplify pipeline setup with ShaderComposer integration
- Created `SamplerCache` singleton to deduplicate sampler instances
- - Refactored `post_process_helper.cc`, `cnn_effect.cc`, `rotating_cube_effect.cc`
+ - Refactored `post_process_helper.cc`, `cnn_v1_effect.cc`, `rotating_cube_effect.cc`
- **Result**:
- Bind group creation: 19 instances reduced from 14→4 lines each
- Pipeline creation: 30-50 lines reduced to 8 lines
diff --git a/doc/HOWTO.md b/doc/HOWTO.md
index 0dc9ec7..4cafaa2 100644
--- a/doc/HOWTO.md
+++ b/doc/HOWTO.md
@@ -100,7 +100,7 @@ make run_util_tests # Utility tests
Extracts patches at salient points, trains on center pixels only (matches WGSL sliding window):
```bash
# Train with 32×32 patches at detected corners/edges
-./training/train_cnn.py \
+./cnn_v1/training/train_cnn.py \
--input training/input/ --target training/output/ \
--patch-size 32 --patches-per-image 64 --detector harris \
--layers 3 --kernel_sizes 3,5,3 --epochs 5000 --batch_size 16 \
@@ -117,7 +117,7 @@ Extracts patches at salient points, trains on center pixels only (matches WGSL s
### Full-Image
Processes entire image with sliding window (matches WGSL):
```bash
-./training/train_cnn.py \
+./cnn_v1/training/train_cnn.py \
--input training/input/ --target training/output/ \
--layers 3 --kernel_sizes 3,5,3 --epochs 10000 --batch_size 8 \
--checkpoint-every 1000
@@ -126,10 +126,10 @@ Processes entire image with sliding window (matches WGSL):
### Export & Validation
```bash
# Generate shaders from checkpoint
-./training/train_cnn.py --export-only checkpoints/checkpoint_epoch_5000.pth
+./cnn_v1/training/train_cnn.py --export-only checkpoints/checkpoint_epoch_5000.pth
# Generate ground truth (sliding window, no tiling)
-./training/train_cnn.py --infer input.png \
+./cnn_v1/training/train_cnn.py --infer input.png \
--export-only checkpoints/checkpoint_epoch_5000.pth \
--output ground_truth.png
```
@@ -145,31 +145,31 @@ Enhanced CNN with parametric static features (7D input: RGBD + UV + sin encoding
**Complete Pipeline** (recommended):
```bash
# Train → Export → Build → Validate (default config)
-./scripts/train_cnn_v2_full.sh
+./cnn_v2/scripts/train_cnn_v2_full.sh
# Rapid debug (1 layer, 3×3, 5 epochs)
-./scripts/train_cnn_v2_full.sh --num-layers 1 --kernel-sizes 3 --epochs 5 --output-weights test.bin
+./cnn_v2/scripts/train_cnn_v2_full.sh --num-layers 1 --kernel-sizes 3 --epochs 5 --output-weights test.bin
# Custom training parameters
-./scripts/train_cnn_v2_full.sh --epochs 500 --batch-size 32 --checkpoint-every 100
+./cnn_v2/scripts/train_cnn_v2_full.sh --epochs 500 --batch-size 32 --checkpoint-every 100
# Custom architecture
-./scripts/train_cnn_v2_full.sh --kernel-sizes 3,5,3 --num-layers 3 --mip-level 1
+./cnn_v2/scripts/train_cnn_v2_full.sh --kernel-sizes 3,5,3 --num-layers 3 --mip-level 1
# Custom output path
-./scripts/train_cnn_v2_full.sh --output-weights workspaces/test/cnn_weights.bin
+./cnn_v2/scripts/train_cnn_v2_full.sh --output-weights workspaces/test/cnn_weights.bin
# Grayscale loss (compute loss on luminance instead of RGBA)
-./scripts/train_cnn_v2_full.sh --grayscale-loss
+./cnn_v2/scripts/train_cnn_v2_full.sh --grayscale-loss
# Custom directories
-./scripts/train_cnn_v2_full.sh --input training/input --target training/target_2
+./cnn_v2/scripts/train_cnn_v2_full.sh --input training/input --target training/target_2
# Full-image mode (instead of patch-based)
-./scripts/train_cnn_v2_full.sh --full-image --image-size 256
+./cnn_v2/scripts/train_cnn_v2_full.sh --full-image --image-size 256
# See all options
-./scripts/train_cnn_v2_full.sh --help
+./cnn_v2/scripts/train_cnn_v2_full.sh --help
```
**Defaults:** 200 epochs, 3×3 kernels, 8→4→4 channels, batch-size 16, patch-based (8×8, harris detector).
@@ -184,33 +184,33 @@ Enhanced CNN with parametric static features (7D input: RGBD + UV + sin encoding
**Validation Only** (skip training):
```bash
# Use latest checkpoint
-./scripts/train_cnn_v2_full.sh --validate
+./cnn_v2/scripts/train_cnn_v2_full.sh --validate
# Use specific checkpoint
-./scripts/train_cnn_v2_full.sh --validate checkpoints/checkpoint_epoch_50.pth
+./cnn_v2/scripts/train_cnn_v2_full.sh --validate checkpoints/checkpoint_epoch_50.pth
```
**Manual Training:**
```bash
# Default config
-./training/train_cnn_v2.py \
+./cnn_v2/training/train_cnn_v2.py \
--input training/input/ --target training/target_2/ \
--epochs 100 --batch-size 16 --checkpoint-every 5
# Custom architecture (per-layer kernel sizes)
-./training/train_cnn_v2.py \
+./cnn_v2/training/train_cnn_v2.py \
--input training/input/ --target training/target_2/ \
--kernel-sizes 1,3,5 \
--epochs 5000 --batch-size 16
# Mip-level for p0-p3 features (0=original, 1=half, 2=quarter, 3=eighth)
-./training/train_cnn_v2.py \
+./cnn_v2/training/train_cnn_v2.py \
--input training/input/ --target training/target_2/ \
--mip-level 1 \
--epochs 100 --batch-size 16
# Grayscale loss (compute loss on luminance Y = 0.299*R + 0.587*G + 0.114*B)
-./training/train_cnn_v2.py \
+./cnn_v2/training/train_cnn_v2.py \
--input training/input/ --target training/target_2/ \
--grayscale-loss \
--epochs 100 --batch-size 16
@@ -236,7 +236,7 @@ Use `--quiet` for streamlined output in scripts (used automatically by train_cnn
```
-**Validation:** Use HTML tool (`tools/cnn_v2_test/index.html`) for CNN v2 validation. See `doc/CNN_V2_WEB_TOOL.md`.
+**Validation:** Use HTML tool (`cnn_v2/tools/cnn_v2_test/index.html`) for CNN v2 validation. See `cnn_v2/docs/CNN_V2_WEB_TOOL.md`.
---
@@ -323,11 +323,11 @@ See `doc/ASSET_SYSTEM.md` and `doc/WORKSPACE_SYSTEM.md`.
**Status:**
- **CNN v2:** ✅ Fully functional, matches CNNv2Effect
-- **CNN v1:** ⚠️ Produces incorrect output, use CNNEffect in demo for validation
+- **CNN v1:** ⚠️ Produces incorrect output, use CNNv1Effect in demo for validation
**Note:** `--weights` loads layer count and kernel sizes from the binary file, overriding `--layers` and forcing CNN v2.
-See `doc/CNN_TEST_TOOL.md` for full documentation.
+See `cnn_v1/docs/CNN_TEST_TOOL.md` for full documentation.
---
diff --git a/src/app/test_demo.cc b/src/app/test_demo.cc
index 5775e74..ff2c105 100644
--- a/src/app/test_demo.cc
+++ b/src/app/test_demo.cc
@@ -20,8 +20,8 @@ extern float GetDemoDuration();
extern void LoadTimeline(MainSequence& main_seq, const GpuContext& ctx);
// Inline peak meter effect for debugging audio-visual sync
-#include "effects/cnn_effect.h"
-#include "effects/cnn_v2_effect.h"
+#include "../../cnn_v1/src/cnn_v1_effect.h"
+#include "../../cnn_v2/src/cnn_v2_effect.h"
#include "gpu/post_process_helper.h"
#include "gpu/shader_composer.h"
diff --git a/src/gpu/demo_effects.h b/src/gpu/demo_effects.h
index d4df20b..6b22f3f 100644
--- a/src/gpu/demo_effects.h
+++ b/src/gpu/demo_effects.h
@@ -18,8 +18,8 @@
// Individual Effect Headers
#include "effects/chroma_aberration_effect.h"
#include "effects/circle_mask_effect.h"
-#include "effects/cnn_effect.h"
-#include "effects/cnn_v2_effect.h"
+#include "../../cnn_v1/src/cnn_v1_effect.h"
+#include "../../cnn_v2/src/cnn_v2_effect.h"
#include "effects/distort_effect.h"
#include "effects/fade_effect.h"
#include "effects/flash_cube_effect.h"
diff --git a/src/tests/audio/test_audio_engine.cc b/src/tests/audio/test_audio_engine.cc
index 3f0ad4d..3d23a5c 100644
--- a/src/tests/audio/test_audio_engine.cc
+++ b/src/tests/audio/test_audio_engine.cc
@@ -65,20 +65,17 @@ void test_audio_engine_manual_resource_loading() {
// Manually preload first few samples
res_mgr->preload(0);
res_mgr->preload(1);
- res_mgr->preload(2);
const int after_preload = res_mgr->get_loaded_count();
printf(" Samples loaded after manual preload: %d\n", after_preload);
- assert(after_preload == 3); // Should have 3 samples loaded
+ assert(after_preload == 2); // Should have 2 samples loaded
// Verify samples are accessible
const Spectrogram* spec0 = res_mgr->get_spectrogram(0);
const Spectrogram* spec1 = res_mgr->get_spectrogram(1);
- const Spectrogram* spec2 = res_mgr->get_spectrogram(2);
assert(spec0 != nullptr);
assert(spec1 != nullptr);
- assert(spec2 != nullptr);
printf(" ✓ AudioEngine manual resource loading test passed\n");
}
@@ -97,10 +94,9 @@ void test_audio_engine_reset() {
// Manually load some samples
res_mgr->preload(0);
res_mgr->preload(1);
- res_mgr->preload(2);
const int loaded_before_reset = res_mgr->get_loaded_count();
- assert(loaded_before_reset == 3);
+ assert(loaded_before_reset == 2);
// Reset engine
fixture.engine().reset();
diff --git a/src/tests/gpu/test_demo_effects.cc b/src/tests/gpu/test_demo_effects.cc
index ec78c10..8726e55 100644
--- a/src/tests/gpu/test_demo_effects.cc
+++ b/src/tests/gpu/test_demo_effects.cc
@@ -12,7 +12,7 @@
#include "../common/effect_test_helpers.h"
#include "../common/webgpu_test_fixture.h"
-#include "effects/cnn_effect.h"
+#include "../../../cnn_v1/src/cnn_v1_effect.h"
#include "gpu/demo_effects.h"
#include "gpu/effect.h"
#include <cassert>
@@ -89,7 +89,7 @@ static void test_post_process_effects() {
{"ThemeModulationEffect",
std::make_shared<ThemeModulationEffect>(fixture.ctx())},
{"VignetteEffect", std::make_shared<VignetteEffect>(fixture.ctx())},
- {"CNNEffect", std::make_shared<CNNEffect>(fixture.ctx())},
+ {"CNNv1Effect", std::make_shared<CNNv1Effect>(fixture.ctx())},
{"CNNv2Effect", std::make_shared<CNNv2Effect>(fixture.ctx())},
};
diff --git a/tools/cnn_test.cc b/tools/cnn_test.cc
index 7d060ae..137d235 100644
--- a/tools/cnn_test.cc
+++ b/tools/cnn_test.cc
@@ -5,7 +5,7 @@
#error "cnn_test requires STRIP_ALL=OFF (tool builds only)"
#endif
-#include "effects/cnn_effect.h"
+#include "../cnn_v1/src/cnn_v1_effect.h"
#include "generated/assets.h"
#include "gpu/bind_group_builder.h"
#include "gpu/gpu.h"
diff --git a/training/README.md b/training/README.md
index e78b471..bddf4d5 100644
--- a/training/README.md
+++ b/training/README.md
@@ -174,6 +174,6 @@ pip install torch torchvision pillow opencv-python numpy
## References
-- **CNN Effect:** `doc/CNN_EFFECT.md`
+- **CNN Effect:** `cnn_v1/docs/CNN_V1_EFFECT.md`
- **Timeline:** `doc/SEQUENCE.md`
- **HOWTO:** `doc/HOWTO.md`
diff --git a/workspaces/main/assets.txt b/workspaces/main/assets.txt
index 972cc8b..189e965 100644
--- a/workspaces/main/assets.txt
+++ b/workspaces/main/assets.txt
@@ -37,16 +37,16 @@ SHADER_PASSTHROUGH, NONE, ../../common/shaders/passthrough.wgsl, "Passthrough Sh
SHADER_ELLIPSE, NONE, shaders/ellipse.wgsl, "Ellipse Shader"
SHADER_PARTICLE_SPRAY_COMPUTE, NONE, shaders/particle_spray_compute.wgsl, "Particle Spray Compute"
SHADER_GAUSSIAN_BLUR, NONE, shaders/gaussian_blur.wgsl, "Gaussian Blur Shader"
-SHADER_CNN_ACTIVATION, NONE, shaders/cnn/cnn_activation.wgsl, "CNN Activation Functions"
-SHADER_CNN_CONV1X1, NONE, shaders/cnn/cnn_conv1x1.wgsl, "CNN 1x1 Convolution"
-SHADER_CNN_CONV3X3, NONE, shaders/cnn/cnn_conv3x3.wgsl, "CNN 3x3 Convolution"
-SHADER_CNN_CONV5X5, NONE, shaders/cnn/cnn_conv5x5.wgsl, "CNN 5x5 Convolution"
-SHADER_CNN_CONV7X7, NONE, shaders/cnn/cnn_conv7x7.wgsl, "CNN 7x7 Convolution"
-SHADER_CNN_WEIGHTS, NONE, shaders/cnn/cnn_weights_generated.wgsl, "CNN Weights (Generated)"
-SHADER_CNN_LAYER, NONE, shaders/cnn/cnn_layer.wgsl, "CNN Layer Shader"
-SHADER_CNN_V2_STATIC, NONE, shaders/cnn_v2/cnn_v2_static.wgsl, "CNN v2 Static Features"
-SHADER_CNN_V2_COMPUTE, NONE, shaders/cnn_v2/cnn_v2_compute.wgsl, "CNN v2 Compute (Storage Buffer)"
-WEIGHTS_CNN_V2, NONE, weights/cnn_v2_weights.bin, "CNN v2 Binary Weights"
+SHADER_CNN_ACTIVATION, NONE, ../../cnn_v1/shaders/cnn_activation.wgsl, "CNN Activation Functions"
+SHADER_CNN_CONV1X1, NONE, ../../cnn_v1/shaders/cnn_conv1x1.wgsl, "CNN 1x1 Convolution"
+SHADER_CNN_CONV3X3, NONE, ../../cnn_v1/shaders/cnn_conv3x3.wgsl, "CNN 3x3 Convolution"
+SHADER_CNN_CONV5X5, NONE, ../../cnn_v1/shaders/cnn_conv5x5.wgsl, "CNN 5x5 Convolution"
+SHADER_CNN_CONV7X7, NONE, ../../cnn_v1/shaders/cnn_conv7x7.wgsl, "CNN 7x7 Convolution"
+SHADER_CNN_WEIGHTS, NONE, ../../cnn_v1/shaders/cnn_weights_generated.wgsl, "CNN Weights (Generated)"
+SHADER_CNN_LAYER, NONE, ../../cnn_v1/shaders/cnn_layer.wgsl, "CNN Layer Shader"
+SHADER_CNN_V2_STATIC, NONE, ../../cnn_v2/shaders/cnn_v2_static.wgsl, "CNN v2 Static Features"
+SHADER_CNN_V2_COMPUTE, NONE, ../../cnn_v2/shaders/cnn_v2_compute.wgsl, "CNN v2 Compute (Storage Buffer)"
+WEIGHTS_CNN_V2, NONE, ../../cnn_v2/weights/cnn_v2_weights.bin, "CNN v2 Binary Weights"
SHADER_SOLARIZE, NONE, shaders/solarize.wgsl, "Solarize Shader"
SHADER_DISTORT, NONE, shaders/distort.wgsl, "Distort Shader"
SHADER_CHROMA_ABERRATION, NONE, shaders/chroma_aberration.wgsl, "Chroma Aberration Shader"
diff --git a/workspaces/main/timeline.seq b/workspaces/main/timeline.seq
index 05d9026..b4663bb 100644
--- a/workspaces/main/timeline.seq
+++ b/workspaces/main/timeline.seq
@@ -29,12 +29,12 @@ SEQUENCE 16.00 2 "Hybrid3D + CNN"
EFFECT + ParticleSprayEffect 0.00 2.00
EFFECT = ParticlesEffect 2.00 4.00
EFFECT + Hybrid3DEffect 0.00 4.00
- EFFECT + CNNEffect 0.00 4.00 layers=3 blend=.9
+ EFFECT + CNNv1Effect 0.00 4.00 layers=3 blend=.9
SEQUENCE 20.00 0 "CNN effect"
EFFECT + HeptagonEffect 0.00 8.00
EFFECT + Scene1Effect 0.00 8.00
- EFFECT + CNNEffect 6.00 8.00 layers=3 blend=.5
+ EFFECT + CNNv1Effect 6.00 8.00 layers=3 blend=.5
SEQUENCE 28.00 0 "buggy"
EFFECT + HeptagonEffect 0.00 2.00