| Age | Commit message (Collapse) | Author |
|
|
|
|
|
- Replace _dbg_pixel() with _dbg_char(ascii, r, c) covering
printable ASCII 0x20-0x7E (95 glyphs, C64-style 8x8 bitmaps)
- Update debug_f32() to use ASCII codes directly
- Add debug_str(col, pos, origin, s: vec4u, len) for rendering
up to 16 chars packed 4-per-u32 big-endian
handoff(Claude): debug_print now supports full ASCII strings.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
The fullscreen post-process VS uses Y-up UVs (uv.y=0 = bottom), so
textureSample() Y-flips any rasterized offscreen texture. SDF effects
author their content Y-down and look correct after the flip. Rasterized
effects (RotatingCube, Hybrid3D) must pre-flip their geometry:
- mat4::perspective(): m[5] = -t (negated Y scale)
- Pipelines with cullMode=Back: frontFace = WGPUFrontFace_CW (Y-flip
reverses winding, so CW becomes the visible face)
- Remove incorrect transposes from GlobalUniforms::make(),
ObjectData::make(), and Uniforms::make() — mini_math is column-major,
no transpose needed for GPU upload
- Document the convention in doc/3D.md under "Rasterized 3D and the
Y-flip rule"
handoff(Gemini): Y-flip rule now documented; all rasterized 3D pipelines
must follow it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Add SHADER_DEBUG_DEBUG_PRINT to assets.txt and register it as
"debug/debug_print" in InitShaderComposer() so ntsc.wgsl #include works.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Renders a f32 value (±999.999, 3 decimal digits) at a given screen
position using authentic C64 8x8 bitmap glyphs in yellow.
Usage: col = debug_f32(col, pos.xy, vec2f(10.0, 10.0), value);
Include: #include "debug/debug_print"
handoff(Gemini): new snippet at src/shaders/debug/debug_print.wgsl
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
mini_math mat4 is row-major; WGSL mat4x4f is column-major. Matrices
uploaded without transposing were interpreted as their own transpose on
the GPU, causing RotatingCube and Renderer3D to render upside-down.
- Add gpu_upload_mat4() to post_process_helper for standalone uploads
- Add Uniforms::make() to RotatingCube::Uniforms (handles transpose)
- Add GlobalUniforms::make() and ObjectData::make() to renderer.h
- Update renderer_draw.cc and visual_debug.cc to use make()
handoff(Gemini): matrix layout bug fixed across all rasterized effects.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- asset_packer: include WGSL in --disk_load path storage (alongside SPEC/MP3)
- asset_manager: disk-load WGSL assets at runtime when !DEMO_STRIP_ALL
- DemoCodegen: pass ASSET_PACKER_FLAGS to pack_test_assets so test assets
also use disk-load paths in dev mode (fixes pre-existing SPEC/WGSL test failures)
- test_shader_composer: fix stale assertions (fn test_wgsl → fn snippet_a,
correct ordering check)
35/35 tests passing.
handoff(Claude): WGSL disk-loading implemented. Shaders now loaded from disk
in dev mode, enabling hot-reload without rebuild. Tests fixed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Updated 'src/tests/gpu/test_shader_composer.cc' to use 'ASSET_TEST_WGSL' and simplified the test.
- Overhauled 'src/tests/assets/test_assets.cc' to align with the new, more concise test asset manifest, resolving compilation errors and improving test focus.
|
|
Replaced the deleted 'AssetType::STATIC' with 'AssetType::BINARY' as the default return value for invalid asset IDs.
|
|
This commit introduces a dual-mode asset loading system to enhance developer workflow and optimize release builds.
Key changes include:
- **Dual-Mode Asset Loading:** Assets are now loaded from disk during development (when is OFF) for faster iteration, particularly for heavy assets like and files. For release builds ( ON), all assets are embedded directly into the binary, ensuring a single, self-contained executable.
- **Explicit Asset Typing:** Replaced generic asset type with specific types (, , , , ) in and the enum in for clearer categorization and more robust processing.
- **Build System Integration:** Modified to pass a flag to in development builds.
- **Asset Packer Updates:** now generates file paths for disk-loaded assets and embeds data for others based on the build mode.
- **Asset Manager Enhancements:** includes new logic in for loading and caching disk-based assets and updates to for proper memory deallocation.
- **Documentation:** Updated to reflect the new asset nomenclature and dual-mode loading strategy.
- **Project Rules:** Added a concise rule to mandating top-level documentation updates for medium/large sub-system changes.
handoff(Gemini): Implemented dual-mode asset loading and updated documentation.
|
|
conventions
- Add textureSampleYUp() helper to fullscreen_uv_vs.wgsl to correct
y-flip when sampling WebGPU textures with y-up UV coordinates
- Use textureSampleYUp() in passthrough, gaussian_blur, combined_postprocess
- Fix skybox.wgsl: remove erroneous (1.0 - uv.y) flip (double-flip bug)
- Document world/view/screen conventions in doc/3D.md, camera_common.wgsl,
and fullscreen_uv_vs.wgsl
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
- scripts/validate_shaders.py: compose #includes then validate with naga-cli
(mirrors InitShaderComposer snippet map; skips runtime-substitution shaders)
- src/effects/ntsc.wgsl: remove broken GLSL-syntax vignette() function
(GLSL const/param syntax, f32→vec2f assignment; inline vignette at line 55
already handles darkening)
handoff(Gemini): validator at scripts/validate_shaders.py; install naga with
cargo install naga-cli; 29/29 shaders pass
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Paths like ../../src/effects/ntsc.wgsl were stored non-normalized in
the DEPENDS list, preventing Ninja/Make from detecting file changes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
WGSL-only WgslEffect implementing barrel/fisheye distortion, RGB chroma
separation, scanlines, per-pixel temporal noise, rolling jitter line,
vignette, and warm NTSC phosphor tint. Applied across all main sequences.
handoff(Gemini): Ntsc effect added; 13 effects total, 35+1 tests expected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Replace boilerplate .h/.cc pairs for simple single-pass effects with a
generic WgslEffect base class that takes a shader string + optional
WgslEffectParams (binding 3). Port Flash, Passthrough, Heptagon, Scratch,
and GaussianBlur to thin header-only wrappers — no .cc files, no CMake
entries needed. Removes 5 .cc files (-243 lines).
Update EFFECT_WORKFLOW.md, CONTRIBUTING.md, and AI_RULES.md to document
the WgslEffect (Path A) vs full class (Path B) workflow. Doc cleanup:
fix stale GaussianBlurParams/PostProcessEffect references and test counts.
handoff(Claude): WgslEffect landed; 5 effects ported; docs updated.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
snippet
- src/shaders/render/scratch_lines.wgsl: reusable WGSL snippet registered as
"render/scratch_lines"; call scratch_lines(uv, resolution, time)->f32 from
any effect. Uses hash_1f from math/noise; 8 lines/frame, ~24fps flicker.
- src/effects/scratch.{wgsl,h,cc}: thin Scratch effect wrapping the snippet.
- Applied to "intro" and "rotating_cube" sequences as the final step.
- 35/35 tests passing.
handoff(Gemini): Scratch effect added. render/scratch_lines snippet is reusable.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
|
|
Without music loaded, synth renders silence; reading from the ring buffer
yielded all-zero samples causing the non_zero_count assertion to fail.
Replace the ring-buffer read path with a direct 440 Hz sine wave so the
test focuses on WAV format/encoding, not audio pipeline content.
handoff(Claude): WavDumpBackendTest now passes (35/35 tests green).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Remove erroneous Hann synthesis window from synth.cc (g_hann * tmp[j]).
Hann analysis at 50% overlap satisfies w[n]+w[n+H]=1, so rectangular
synthesis gives perfect reconstruction; applying Hann twice was wrong.
- Extract ola_encode()/ola_decode()/ola_num_frames() into src/audio/ola.h+cc.
spectool and test_wav_roundtrip now use the shared functions.
synth.cc lazy-decode path stays inlined (see TODO for future refactor).
- Drop dead <atomic> include and g_hann array from synth.cc.
- Drop dead window.h include from spectool.cc.
- Update PROJECT_CONTEXT.md, COMPLETED.md, TODO.md to reflect correct
analysis-only Hann window and new ola.h API.
handoff(Gemini): OLA synthesis bug fixed + ola.h factorized. synth.cc
lazy-decode still inline (TODO item added). 34/35 tests pass; WavDumpBackendTest
failure is pre-existing and unrelated.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- spectool --wav <input.spec> <output.wav>: decodes .spec to mono 16-bit
WAV at 32 kHz using IDCT-OLA synthesis (no synthesis window).
The analysis Hann window at 50% overlap satisfies w[n]+w[n+H]=1,
so the synthesis window must be rectangular for perfect reconstruction.
- Add imdct_512 / imdct_fft to audio lib (fft.cc, fft.h, idct.cc, dct.h)
for future MDCT-based synthesis.
- test_wav_roundtrip: in-process OLA analyze+decode SNR test (≥30 dB).
Currently measures 53 dB on a 440 Hz sine.
- Fix stale test_spectool.cc: version assertion updated from 1 to
SPEC_VERSION_V2_OLA (was always wrong since OLA fix landed).
- Docs: TOOLS_REFERENCE.md removes dead specview, documents --wav /
--normalize / test_gen. HOWTO.md adds decode section. TRACKER.md
notes spec v2 OLA format and decode command.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Two bugs kept the v2 OLA path permanently disabled:
1. SpectrogramResourceManager::load_asset() never set spec.version from
SpecHeader::version — all .spec assets loaded with version=0, so
ola_mode was always false in the voice.
2. spectool analyze_audio() used non-overlapping chunks (stride=DCT_SIZE),
hamming_window_512, and hardcoded header.version=1 — OLA analysis was
never implemented in the encoder.
Fixes: propagate header->version in load_asset(); switch spectool to
OLA_HOP_SIZE stride, hann_window_512, and SPEC_VERSION_V2_OLA.
Regenerated all .spec files.
handoff(Gemini): OLA enc/dec chain now correct end-to-end. .spec files
are v2 (50% overlap, Hann). No API changes; 33/34 tests pass
(WavDumpBackendTest pre-existing failure unrelated).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Adds a minimal test.mp3 fixture to the test workspace and verifies
GetAssetType returns AssetType::MP3 and GetAsset returns non-null data.
handoff(Gemini): MP3 asset test added, 34/34 tests passing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
enum, add MP3 type
- Add AssetType enum {STATIC, PROC, PROC_GPU, MP3} to AssetRecord
- Add GetAssetType() API to asset_manager.h/cc
- asset_packer: parse 'MP3' compression keyword in assets.txt
- tracker: remove magic-byte is_mp3_asset(); use GetAssetType() instead
- assets.txt: NEVER_MP3 now uses 'MP3' compression type
- doc/ASSET_SYSTEM.md: rewritten to document new types and API
handoff(Gemini): AssetType enum landed; MP3 detection is now explicit via asset metadata.
|
|
Add v2 spectrogram format (SPEC_VERSION_V2_OLA) using overlap-add IDCT
with 50% overlap (hop=256, OLA_OVERLAP=256) and Hann windowing.
- dct.h: OLA_HOP_SIZE=256, OLA_OVERLAP=256
- synth.h: SPEC_VERSION_V1/V2_OLA constants; version field on Spectrogram
- window.h/cc: hann_window_512() alongside existing hamming_window_512()
- synth.cc: g_hann[] precomputed at init; OLA path in synth_render when
ola_mode=true (IDCT -> Hann -> add overlap tail -> save new tail ->
output OLA_HOP_SIZE samples); v1 path unchanged for backward compat
- tracker.cc: MP3 encoder now uses sliding 512-sample Hann window with
OLA_HOP_SIZE advance per frame; sets version=SPEC_VERSION_V2_OLA;
.spec files propagate header->version; generated notes stay v1
Existing .spec files must be regenerated to benefit from click-free OLA.
handoff(Claude): OLA done. .spec files need regen via MP3 tool to activate v2.
|
|
Detect MP3 blobs by magic bytes in tracker_init(), decode to spectrogram
(hamming window + FDCT) using new mp3_decode(), and register with synth
exactly like .spec assets. STRIP_ALL builds guard with FATAL_CHECK.
handoff(Gemini): MP3 assets now usable in music.track with SAMPLE ASSET_*
syntax; see doc/TRACKER.md for usage. No synth/compiler/packer changes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Adds mp3_open/mp3_decode_range/mp3_close API backed by miniaudio
ma_decoder for in-memory MP3 assets. Guarded by #if !defined(STRIP_ALL);
any use in stripped builds is a compile error. No new dependencies:
drmp3 is already compiled via MINIAUDIO_IMPLEMENTATION in audio.cc.
handoff(Gemini): mp3_sample.{h,cc} in AUDIO_SOURCES. Usage:
Mp3Decoder* d = mp3_open(GetAsset(id, &sz), sz);
mp3_decode_range(d, start_frame, num_frames, pcm_out);
mp3_close(d);
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
src/effects/
Move 13 effect-specific shaders from workspaces/main/shaders/ to src/effects/
so each effect's .h, .cc, and .wgsl are together. Update assets.txt paths in
both main and test workspaces. Update EFFECT_WORKFLOW.md to reflect new location.
Shared/reusable snippets remain in src/shaders/.
handoff(Gemini): shaders moved; src/effects/ now has .h, .cc, and .wgsl per effect.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
- Fix assets.txt path: shaders/xxx.wgsl (not ../../src/shaders/)
- Fix shader output path to workspaces/main/shaders/
- Step 5: reference cmake/DemoSourceLists.cmake COMMON_GPU_EFFECTS (not CMakeLists.txt GPU_SOURCES)
- Add step for test_demo_effects.cc
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Relocates shared WGSL shaders under src/ where all source code lives,
eliminating the top-level common/ directory.
- Update asset references in workspaces/main/assets.txt and workspaces/test/assets.txt
- Update docs: PROJECT_CONTEXT.md, ARCHITECTURE.md, WORKSPACE_SYSTEM.md, SHADER_REUSE_INVESTIGATION.md
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- asset_manager_dcl.h: clarify purpose vs asset_manager.h
- camera_params.h: broaden description to include 3D rendering
- sdf_cpu.h: simplify calc_normal formatting
- platform.h: add missing newline at EOF
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
Keeps .h as declarations only; moves all method bodies to .cc.
Adds pipeline_builder.cc to COMMON_GPU_EFFECTS in DemoSourceLists.cmake.
handoff(Claude): pipeline_builder split to .h/.cc, builds clean.
|
|
get_or_create() and clear() moved out of the header-only class.
SamplerSpec and presets remain inline (trivial, no deps).
handoff(Gemini): sampler_cache split into .h/.cc, sampler_cache.cc added to COMMON_GPU_EFFECTS.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Delete unused SDFEffect base class (src/gpu/sdf_effect.h)
- Delete sdf_test.wgsl and SHADER_SDF_TEST from assets.txt
- Rewrite SDF_EFFECT_GUIDE.md based on Scene1 canonical pattern:
correct bindings (2/3), vec4f syntax, UniformsSequenceParams
- Fix missing newline at end of gpu.h
handoff(Claude): SDF cleanup done, guide updated to match current Effect API
|
|
handoff(Gemini): deleted src/gpu/demo_effects.cc (empty stub), removed from
headless GPU_SOURCES in DemoSourceLists.cmake, dropped stale #include from
post_process_helper.cc.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
|
|
- NodeRegistry: skip external nodes (texture==nullptr) in ~NodeRegistry()
and resize() to avoid double-releasing views set via set_external_view()
- test_shader_assets: update PASSTHROUGH check to match #include pattern
handoff(Claude): 35/35 tests passing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
snippet
- Fix vs_main return type (VertexOutput, not vec4<f32>)
- Fix #include paths in passthrough, gaussian_blur, heptagon, combined_postprocess
- ShaderComposer: assert + suggest correct path on missing #include (non-STRIP_ALL)
- VerifyIncludes: upgrade WARNING to ERROR + assert, add "did you mean?" hint
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
- Fix stack-use-after-scope dangling reference by storing mutable GpuContext in WebGPUTestFixture.
- Fix wgpuDevicePoll causing SIGTRAP and replace with target.read_pixels() to block for GPU teardown safely.
- Fix WGPUCommandEncoder leak.
|
|
Replaces all instances of `vec<f32>` with the more concise `vec*f` alias (e.g., `vec3f`) across all `.wgsl` shaders. This improves readability and aligns with common graphics programming conventions.
Also adds a new coding style rule to `doc/CODING_STYLE.md` to enforce this standard going forward.
Finally, this commit fixes a build error in `test_effect_base.cc` by replacing a call to the non-existent `wgpuDeviceTick` with `wgpuDevicePoll`, which resolves the test failure.
|
|
The test `test_sequence_render` was disabled due to an intermittent SIGTRAP. The issue was caused by the test application exiting before the GPU finished rendering.
This commit fixes the issue by adding a call to `wgpuDeviceTick()` after submitting the command buffer. This ensures that the GPU has completed its work before the test finishes.
The test is now re-enabled and passes consistently.
|
|
|
|
Adds two convenient methods to the struct:
- : Rotates the vector by a given quaternion.
- : Rotates the vector around a given axis by an angle in radians.
These functions provide a more intuitive and streamlined syntax for vector rotation, improving code readability and usability.
|
|
|