| Age | Commit message (Collapse) | Author |
|
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.
|
|
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.
|
|
Replace GBufViewEffect with CNNv3Effect → Passthrough.
G-buffer confirmed working; now running full CNN inference pipeline.
|
|
- 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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
|
|
|
|
|
|
|
|
measure)
|
|
|
|
|
|
|
|
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.
|
|
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).
|
|
- 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
|
|
|
|
- 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
|
|
path
|
|
- 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
|
|
- 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
|
|
|
|
https://colorifyai.art/photo-to-sketch/#playground with 'Ink Sketch' does a small zooming
and resize
|
|
- --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.
|
|
|
|
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.
|
|
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.
|
|
|
|
|
|
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.
|
|
handoff(Gemini): added render + batch-pack example commands at end of section 1b
|
|
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
|
|
|
|
- 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.
|
|
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
|
|
after render
|
|
|
|
|
|
- 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.
|
|
|
|
|
|
|
|
- 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
|
|
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
|
|
- 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
|
|
- 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
|
|
- 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
|