From 47397444b30b0f461b1633297a68300179586fda Mon Sep 17 00:00:00 2001 From: skal Date: Tue, 10 Feb 2026 08:01:25 +0100 Subject: feat: Add CNN post-processing effect with modular WGSL architecture MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements multi-layer convolutional neural network shader for stylized post-processing of 3D rendered scenes: **Core Components:** - CNNEffect: C++ effect class with single-layer rendering (expandable to multi-pass) - Modular WGSL snippets: cnn_activation, cnn_conv3x3/5x5/7x7, cnn_weights_generated - Placeholder identity-like weights for initial testing (to be replaced by trained weights) **Architecture:** - Flexible kernel sizes (3×3, 5×5, 7×7) via separate snippet files - ShaderComposer integration (#include resolution) - Residual connections (input + processed output) - Supports parallel convolutions (design ready, single conv implemented) **Size Impact:** - ~3-4 KB shader code (snippets + main shader) - ~2-4 KB weights (depends on network architecture when trained) - Total: ~5-8 KB (acceptable for 64k demo) **Testing:** - CNNEffect added to test_demo_effects.cc - 36/36 tests passing (100%) **Next Steps:** - Training script (scripts/train_cnn.py) to generate real weights - Multi-layer rendering with ping-pong textures - Weight quantization for size optimization handoff(Claude): CNN effect foundation complete, ready for training integration --- workspaces/main/shaders/cnn/cnn_layer.wgsl | 46 ++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 workspaces/main/shaders/cnn/cnn_layer.wgsl (limited to 'workspaces/main/shaders/cnn/cnn_layer.wgsl') diff --git a/workspaces/main/shaders/cnn/cnn_layer.wgsl b/workspaces/main/shaders/cnn/cnn_layer.wgsl new file mode 100644 index 0000000..e026ce8 --- /dev/null +++ b/workspaces/main/shaders/cnn/cnn_layer.wgsl @@ -0,0 +1,46 @@ +// CNN layer shader - uses modular convolution snippets +// Supports multi-pass rendering with residual connections + +@group(0) @binding(0) var smplr: sampler; +@group(0) @binding(1) var txt: texture_2d; + +#include "common_uniforms" +#include "cnn_activation" +#include "cnn_conv3x3" +#include "cnn_weights_generated" + +struct CNNLayerParams { + layer_index: i32, + use_residual: i32, + _pad: vec2, +}; + +@group(0) @binding(2) var uniforms: CommonUniforms; +@group(0) @binding(3) var params: CNNLayerParams; + +@vertex fn vs_main(@builtin(vertex_index) i: u32) -> @builtin(position) vec4 { + var pos = array, 3>( + vec2(-1.0, -1.0), vec2(3.0, -1.0), vec2(-1.0, 3.0) + ); + return vec4(pos[i], 0.0, 1.0); +} + +@fragment fn fs_main(@builtin(position) p: vec4) -> @location(0) vec4 { + let uv = p.xy / uniforms.resolution; + var result = vec4(0.0); + + // Single layer for now (layer 0) + if (params.layer_index == 0) { + result = cnn_conv3x3(txt, smplr, uv, uniforms.resolution, + weights_layer0, bias_layer0); + result = cnn_tanh(result); + } + + // Residual connection + if (params.use_residual != 0) { + let input = textureSample(txt, smplr, uv); + result = input + result * 0.3; + } + + return result; +} -- cgit v1.2.3