summaryrefslogtreecommitdiff
path: root/cnn_v3
AgeCommit message (Collapse)Author
24 hoursrefactor(shaders): extract oct-normal encode/decode into math/normal snippetskal
New src/shaders/math/normal.wgsl: oct_encode, oct_decode, oct_encode_unorm, oct_decode_unorm. Registered in InitShaderComposer as "math/normal". Removed inline copies from gbuf_raster.wgsl and gbuf_pack.wgsl. 18/18 tests passing.
24 hoursfeat(cnn_v3): GBufDeferredEffect — simple deferred render (albedo * shadow)skal
New effect unpacks feat_tex0/feat_tex1 and outputs albedo * shadow. Replaces CNNv3Effect in cnn_v3_test sequence until training is complete. 37/37 tests passing. handoff(Gemini): GBufDeferredEffect wired in timeline; CNN v3 pipeline: GBufferEffect → GBufDeferredEffect → sink.
24 hoursfix(cnn_v3): call set_scene() in constructor + orbiting cameraskal
- GBufferEffect::render() was a no-op (scene_ready_=false) because set_scene() was never called from the timeline sequence constructor. Fixed by calling set_scene() at the end of the constructor. - Camera now orbits the scene at 0.3 rad/s (R=6, y=2.5). handoff(Gemini): cnn_v3_test sequence now renders G-buffer + GBufViewEffect with animated orbiting camera.
24 hoursrefactor(cnn_v3): GBufferEffect cleanupskal
Remove dead code and reduce duplication: - drop create_bilinear_sampler() (never called) - drop update_pack_bind_group() stub and pack_bind_group_ member - drop node_feat0_/node_feat1_; use output_nodes_[0/1] directly - Compose({}, src) consistently for all three pipelines - extract clear_r8_node() helper to replace two identical 10-line blocks No behavior change. 36/36 tests pass.
24 hoursfeat(cnn_v3): Phase 4 — type-aware SDF in shadow passskal
dfWithID() in gbuf_shadow.wgsl now branches on obj.params.x (ObjectType) instead of using sdBox for everything: 0=CUBE → sdBox(lp, vec3(1)) 1=SPHERE → sdSphere(lp, 1.0) 2=PLANE → sdPlane(lp, vec3(0,1,0), obj.params.y) 3=TORUS → sdTorus(lp, vec2(0.8, 0.2)) 36/36 tests pass.
24 hoursfeat(cnn_v3): GBufferEffect Pass 2 — SDF shadow raymarchingskal
Implements gbuf_shadow.wgsl: fullscreen render pass that reads depth from Pass 1, reconstructs world-space positions, evaluates a proxy-box SDF for each object (via inv_model), computes soft shadows for both directional lights using shadowWithStoredDistance(), and writes shadow factor to the RGBA8Unorm node_shadow_ target consumed by gbuf_pack.wgsl. Bind layout: B0=GlobalUniforms, B1=ObjectsBuffer (storage-read), B2=texture_depth_2d, B3=GBufLightsUniforms. Sky fragments (depth=1.0) are output as 1.0 (fully lit). Falls back to clear(1.0) if pipeline is not ready. 36/36 tests pass. handoff(Gemini): Pass 2 done. Pass 3 (transparency) still TODO. Phase 4 (type-aware SDF) optional after visual validation.
25 hoursfeat(cnn_v3): GBufferEffect internal scene + GBufViewEffect debug wiringskal
GBufferEffect: - set_scene() now owns Scene/Camera internally; no external pointers needed - 20 randomly rotating cubes (xorshift32 seed, axis-angle animation) - 4 pumping spheres (radius = base_r * (1 + audio_intensity * 0.8)) - Camera at (0,2.5,6) looking at origin; aspect updated per-frame - GBufLightsUniforms: 2 directional lights (warm key + cool fill) - object_type written to ObjectData.params.x (ready for SDF shadow) - shadow/transp nodes cleared via zero-draw render passes (placeholder) - bilinear sampler cached via create_linear_sampler() / sampler_.get() - dead placeholder textures removed GBufViewEffect: - gbuf_view.wgsl: all channels now fully grayscale (removed color tint) - seq_compiler.py: GBufViewEffect added to CLASS_TO_HEADER - timeline.seq: cnn_v3_test uses GBufViewEffect -> sink for debug view Docs: HOWTO.md §1 updated with set_scene() description + §1b implementation plan for Pass 2 SDF shadow (shader spec, bind layout, C++ additions) handoff(Gemini): GBufferEffect has internal scene, 36/36 tests green. Next: implement Pass 2 shadow (gbuf_shadow.wgsl) per §1b plan in HOWTO.md.
26 hoursadd full datasetskal
26 hoursfeat(cnn_v3/tools): zoom canvas shows region around clicked texelskal
27 hoursfix(cnn_v3/tools): don't destroy feat textures after runFromFeat (breaks viz)skal
27 hoursfix(cnn_v3/tools): refresh zoom canvas when new sample is loadedskal
27 hoursfix(cnn_v3/tools): zoom canvas fits remaining panel space (both axes, rAF ↵skal
measure)
27 hoursfix(cnn_v3/tools): fit zoom canvas to panel width by scaling canvas attributesskal
27 hoursfix(cnn_v3/tools): zoom channel via WebGPU re-render + fill panel widthskal
27 hoursfeat(cnn_v3/tools): click vignette to show enlarged channel below gridskal
28 hoursfix(cnn_v3/tools): remove unused sampler binding from FULL_PACK_SHADERskal
WebGPU auto-reflects the BGL from the shader; a declared-but-unused sampler binding is omitted from the layout, causing CreateBindGroup to reject it. Removed binding 6 (sampler) entirely — all reads use textureLoad(). Renumbered f0/f1 from 7/8 to 6/7 to match.
28 hoursfeat(cnn_v3): add G-buffer visualizer + web sample loader (Phase 7)skal
C++ GBufViewEffect: renders all 20 feature channels from feat_tex0/feat_tex1 in a 4×5 tiled grid. Custom BGL with WGPUTextureSampleType_Uint; bind group rebuilt per frame via wgpuRenderPipelineGetBindGroupLayout. Web tool: "Load sample directory" button — webkitdirectory picker, FULL_PACK_SHADER compute (matches gbuf_pack.wgsl packing), runFromFeat() skips photo-pack step, computePSNR() readback + comparison vs target.png side-by-side. 36/36 tests pass. Docs updated: HOWTO.md §9, README, PROJECT_CONTEXT, TODO, COMPLETED. handoff(Gemini): CNN v3 Phase 7 done. Next: run train_cnn_v3.py (see HOWTO §3).
31 hoursfix(cnn_v3/tools): fix getElementById illegal invocation + auto-preload weightsskal
- Bind document.getElementById in filmParams() to fix 'Illegal invocation' error - Add preload() that auto-fetches cnn_v3_weights.bin + cnn_v3_film_mlp.bin from workspaces/main/weights/ on init; skips silently if files not found - Add '↺ Reload from workspace weights/' button for manual re-fetch handoff(Gemini): cnn_v3 web tool fixed; serve from repo root via http.server
31 hoursfix(cnn_v3): fix texture format mismatches in cnn_v3_test sequenceskal
- seq_compiler: add gbuf_albedo/gbuf_rgba32uint to NODE_TYPES - timeline: declare gbuf_feat0/feat1 as gbuf_rgba32uint, route CNNv3Effect output through cnn_v3_out (gbuf_albedo) + Passthrough to sink (dec0 can't write directly to Rgba8Unorm sink) - cnn_v3_effect: fix update_bind_groups using .set() instead of .replace() causing FATAL assert on second frame - TODO: add CNN v3 "2D mode" (G-buffer-free) future task handoff(Gemini): CNNv3Effect now runs without crashes at --seek 48
31 hoursfeat(cnn_v3): wire trained weights into CNNv3Effect + add timeline test sequenceskal
- CNNv3Effect constructor loads ASSET_WEIGHTS_CNN_V3 via GetAsset on startup - seq_compiler.py: CLASS_TO_HEADER supports full #include paths for cnn_v3/ classes - timeline.seq: add cnn_v3_test sequence at 48s (GBufferEffect → CNNv3Effect) - test_cnn_v3_parity: zero_weights test now explicitly uploads zeros to override asset handoff(Gemini): CNNv3Effect ready; export weights to workspaces/main/weights/ and seek to 48s to test
31 hoursfeat(cnn_v3): add weight assets to assets.txt, update HOW_TO_CNN export docsskal
- Add WEIGHTS_CNN_V3 and WEIGHTS_CNN_V3_FILM_MLP to workspaces/main/assets.txt - Add opencv-python and pillow to export_cnn_v3_weights.py uv inline deps - Update HOW_TO_CNN.md §3 export target → workspaces/main/weights/ - Update HOW_TO_CNN.md §4 weight loading → SafeGetAsset (asset system) handoff(Gemini): cnn_v3 weight assets registered; export and C++ load path documented
32 hoursdocs(cnn_v3): add uv inline deps to export_cnn_v3_weights.pyskal
32 hoursfix sizeskal
https://colorifyai.art/photo-to-sketch/#playground with 'Ink Sketch' does a small zooming and resize
32 hoursfeat(cnn_v3): patch alignment search, resume, Ctrl-C saveskal
- --patch-search-window N: at dataset init, find per-patch (dx,dy) in [-N,N]² that minimises grayscale MSE between source albedo and target; result cached so __getitem__ pays only a list-lookup per sample. - --resume [CKPT]: restore model + Adam state from a checkpoint; omit path to auto-select the latest in --checkpoint-dir. - Ctrl-C (SIGINT) finishes the current batch, then saves a checkpoint before exiting; finally-block guarded so no spurious epoch-0 save. - Review: remove unused sd variable, lift patch_idx out of duplicate computation, move _LUMA to Constants block, update module docstring. handoff(Gemini): cnn_v3/training updated — no C++ or test changes.
32 hoursnormalize sample dimensionskal
33 hoursdocs(cnn_v3): add uv inline deps to train_cnn_v3.py + HOW_TO_CNN noteskal
handoff(Gemini): train_cnn_v3.py now has uv script metadata block (torch, torchvision, numpy, pillow, opencv-python). HOW_TO_CNN §2 Prerequisites updated with uv quick-start alternative.
33 hoursperf(cnn_v3): cache dataset images at init to avoid per-patch disk I/Oskal
handoff(Gemini): CNNv3Dataset now loads all samples once in __init__ into self._cache; __getitem__ reads from cache instead of reloading PNGs each call. Eliminates N×patches_per_image file loads per epoch.
33 hoursdocs(cnn_v3): add Windows 10 + CUDA training section to HOW_TO_CNN §2skal
33 hoursfix(cnn_v3): correct weight budget in docstring (3.9→5.4 KB f16)skal
33 hoursfix(cnn_v3): resize target to albedo dims when sizes differskal
target.png can have a different resolution than albedo.png in simple samples; patch slicing into the smaller target produced 0×0 tensors, crashing torch.stack in the DataLoader collate. handoff(Gemini): target resized in _load_sample (LANCZOS) + note in HOW_TO_CNN §1c.
33 hoursdocs(cnn_v3): add full Old House example to HOW_TO_CNN §1bskal
handoff(Gemini): added render + batch-pack example commands at end of section 1b
34 hoursfix(cnn_v3): native OPEN_EXR_MULTILAYER + quiet render + flexible channel namesskal
blender_export.py: - Replace broken compositor FileOutput approach with native OPEN_EXR_MULTILAYER render output; all enabled passes included automatically, no socket wiring needed - Suppress Fra:/Mem: render spam via os.dup2 fd redirect; per-frame progress printed to stderr via render_post handler pack_blender_sample.py: - get_pass_r: try .R/.X/.Y/.Z/'' suffixes + aliases param for Depth→Z fallback - combined_rgba loaded once via ("Combined","Image") loop; shared by transp+target - Remove unused sys import HOW_TO_CNN.md: update channel table to native EXR naming (Depth.Z, IndexOB.X, Shadow.X), fix example command, note Shadow defaults to 255 when absent handoff(Gemini): blender pipeline now produces correct multilayer EXR with all G-buffer passes; pack script handles native channel naming
34 hoursdocs(cnn_v3): blender4 alias + Blender 4.5 LTS requirement for training dataskal
34 hoursfix(blender_export): version detection + Blender 5.x warning + cleanupskal
- Use bpy.app.version for version detection instead of attribute sniffing - Blender 5.0.x: warn that per-pass compositor routing is broken (Combined only); compositing_node_group path kept ready for when Blender fixes this upstream - Remove all DEBUG prints and failed use_nodes=True experiment - configure_scene() returns only discard_dir (compositor always configured) - Move _SOCKET_ALIASES to module level; simplify slots/None fallback handoff(Gemini): blender_export.py stable for Blender 4.5 LTS; Blender 5.x path is forward-compatible but produces Combined-only output until upstream fix.
35 hoursfix(cnn_v3): blender_export Blender 5 compositor activation + document ↵skal
RenderLayer sockets - Activate compositor in Blender 5.0+ by relying on compositing_node_group assignment (no use_nodes needed, avoids deprecation warning) - Document full CompositorNodeRLayers output socket list for Blender 5.0.1 - Clean up SOCKET_ALIASES to match confirmed socket names
35 hoursfeat(cnn_v3): blender_export print pack_blender_sample.py batch command ↵skal
after render
35 hoursfix(cnn_v3): blender_export fallback socket name aliases for Shadow etc.skal
35 hoursfix(cnn_v3): blender_export discard dir next to --output, not in /tmpskal
35 hoursfix(cnn_v3): blender_export.py Blender 5 File Output node slots + file_nameskal
- Prefer file_output_items over file_slots; use explicit is-None checks so empty collections do not fall through to the legacy attribute. - Clear out_node.file_name so multilayer EXR frames are named 0001.exr instead of file_name0001.exr. handoff(Gemini): blender_export.py now produces frames/0001.exr on Blender 5.0.1.
35 hoursdocs(cnn_v3): clarify --output is a base dir, not a frame_### patternskal
35 hoursdocs(cnn_v3): update HOW_TO_CNN for Blender 5.x compatibilityskal
35 hoursfix(cnn_v3): blender_export.py Blender 5.x API compatibilityskal
- compositor: use compositing_node_group (Blender 5+) / node_tree (<=4.x) - file output: use file_output_items.new(type, name) (5+) / file_slots (older) - file output: use directory attr (5+) / base_path (older) - suppress default PNG output via mkdtemp + shutil.rmtree after render - link passes by name instead of positional index - add TODO for Shadow socket name variance across blend files - clean up: extract helpers, PASS_SOCKETS constant with socket types handoff(Gemini): blender_export.py now works on Blender 5.0.1
36 hoursfix(cnn_v3): blender_export --view-layer flag + fallback to layer[0]skal
Fixes KeyError when blend file uses a non-default view layer name. Adds --view-layer NAME arg; pass '?' to list available layers. Defaults to index 0 with a clear error if the name is not found. handoff(Gemini): blender_export.py view layer selection now robust
36 hoursfeat(cnn_v3): gen_sample tool + 7 simple training samplesskal
- pack_photo_sample.py: --target now required (no albedo fallback) - gen_sample.py: bash wrapper with positional args (input target output_dir) - input/photo7.jpg: copy of photo2 (second style target) - target_1: photo2_1_out→photo2_out, photo2_2_out→photo7_out - dataset/simple/sample_001..007: 7 packed photo/target pairs handoff(Gemini): training data ready; next step is train_cnn_v3.py run
36 hoursfeat(cnn_v3): gen_sample tool + 7 simple training samplesskal
- pack_photo_sample.py: --target now required (no albedo fallback) - gen_sample.py: bash wrapper with positional args (input target output_dir) - input/photo7.jpg: copy of photo2 (second style target) - target_1: photo2_1_out→photo2_out, photo2_2_out→photo7_out - dataset/simple/sample_001..007: 7 packed photo/target pairs handoff(Gemini): training data ready; next step is train_cnn_v3.py run
36 hoursfeat(cnn_v3): gen_sample tool + 7 simple training samplesskal
- pack_photo_sample.py: --target now required (no albedo fallback) - gen_sample.py: bash wrapper with positional args (input target output_dir) - input/photo7.jpg: copy of photo2 (second style target) - target_1: photo2_1_out→photo2_out, photo2_2_out→photo7_out - dataset/simple/sample_001..007: 7 packed photo/target pairs handoff(Gemini): training data ready; next step is train_cnn_v3.py run
36 hoursfeat(cnn_v3): gen_sample tool + 7 simple training samplesskal
- pack_photo_sample.py: --target now required (no albedo fallback) - gen_sample: bash wrapper with positional args (input target output_dir) - input/photo7.jpg: copy of photo2 (second style target) - target_1: photo2_1_out→photo2_out, photo2_2_out→photo7_out - dataset/simple/sample_001..007: 7 packed photo/target pairs handoff(Gemini): training data ready; next step is train_cnn_v3.py run
2 daysrefactor(cnn_v3): code review — comments, simplifications, test fixskal
C++: - cnn_v3_effect.cc: fix declare_nodes comment (output node declared by caller) - cnn_v3_effect.cc: add TODO(phase-7) marker for FiLM MLP replacement WGSL: - cnn_v3_bottleneck.wgsl: consolidate _pad fields onto one line, explain why array<u32,3> is invalid in uniform address space - cnn_v3_enc0.wgsl: fix "12xu8" → "12ch u8norm" in header comment - cnn_v3_dec0.wgsl: clarify parity note (sigmoid after FiLM+ReLU, not raw conv) - cnn_v3_common.wgsl: clarify unpack_8ch pack layout (low/high 16 bits) Python: - cnn_v3_utils.py: replace PIL-based _upsample_nearest (uint8 round-trip) with pure numpy index arithmetic; rename _resize_rgb → _resize_img (handles any channel count); add comment on normal zero-pad workaround - export_cnn_v3_weights.py: add cross-ref to cnn_v3_effect.cc constants; clarify weight count comments with Conv notation Test: - test_cnn_v3_parity.cc: enc0/dec1 layer failures now return 0 (were print-only) handoff(Gemini): CNN v3 review complete, 36/36 tests passing.
2 daysfeat(cnn_v3): HTML WebGPU tool (index.html + shaders.js + tester.js)skal
3-file tool, 939 lines total. Implements full U-Net+FiLM inference in the browser: Pack→Enc0→Enc1→Bottleneck→Dec1→Dec0 compute passes, layer visualisation (Feat/Enc0/Enc1/BN/Dec1/Output), FiLM MLP sliders, drag-drop weights + image/video, Save PNG, diff/blend view modes. HOW_TO_CNN.md §7 updated to reflect tool is implemented. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2 daysfeat(cnn_v3): export script + HOW_TO_CNN.md playbookskal
- export_cnn_v3_weights.py: .pth → cnn_v3_weights.bin (f16 packed u32) + cnn_v3_film_mlp.bin (f32) - HOW_TO_CNN.md: full pipeline playbook (data collection, training, export, C++ wiring, parity, HTML tool) - TODO.md: mark export script done Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>