From af5d0e4c3a6cb773a4fb51ac32f4c33a7f8d8224 Mon Sep 17 00:00:00 2001 From: skal Date: Mon, 16 Feb 2026 11:54:46 +0100 Subject: feat(sequence): complete v2 migration with DAG-based routing Phase 4 complete: V1 system removed, v2 fully operational. Architecture Changes: - Explicit Node system with typed buffers (u8x4_norm, f32x4, depth24) - DAG effect routing with multi-input/multi-output support - Python compiler (seq_compiler_v2.py) with topological sort and ping-pong optimization - Compile-time node aliasing for framebuffer reuse V1 Removal (~4KB): - Deleted effect.h/cc base classes (1.4KB) - Deleted 19 v1 effect pairs: heptagon, particles, passthrough, gaussian_blur, solarize, scene1, chroma_aberration, vignette, hybrid_3d, flash_cube, theme_modulation, fade, flash, circle_mask, rotating_cube, sdf_test, distort, moving_ellipse, particle_spray (2.7KB) V2 Effects Ported: - PassthroughEffectV2, PlaceholderEffectV2 - GaussianBlurEffectV2 (multi-pass with temp nodes) - HeptagonEffectV2 (scene effect with dummy texture) - ParticlesEffectV2 (compute + render, format fixed) - RotatingCubeEffectV2 (3D with depth node) - Hybrid3DEffectV2 (Renderer3D integration, dummy textures for noise/sky) Compiler Features: - DAG validation (cycle detection, connectivity checks) - Topological sort for execution order - Ping-pong optimization (aliased node detection) - Surface-based and encoder-based RenderV2Timeline generation - init_effect_nodes() automatic generation Fixes Applied: - WebGPU binding layout validation (standard v2 post-process layout) - Surface format mismatch (ctx.format for blit, RGBA8Unorm for framebuffers) - Depth attachment compatibility (removed forced depth from gpu_create_render_pass) - Renderer3D texture initialization (created dummy 1x1 white textures) - ParticlesEffectV2 format (changed from ctx.format to RGBA8Unorm) - Encoder-based RenderV2Timeline (added missing preprocess() call) Testing: - 34/36 tests passing (2 v1-dependent tests disabled) - demo64k runs successfully (no crashes) - All seek positions work (--seek 12, --seek 15 validated) Documentation: - Updated PROJECT_CONTEXT.md (v2 status, reference to SEQUENCE_v2.md) - Added completion entry to COMPLETED.md TODO (Future): - Port CNN effects to v2 - Implement flatten mode (--flatten code generation) - Port remaining 10+ effects - Update HTML timeline editor for v2 (deferred) handoff(Claude): Sequence v2 migration complete, v1 removed, system operational. Phase 5 (editor) deferred per user preference. Co-Authored-By: Claude Sonnet 4.5 --- src/effects/hybrid_3d_effect.cc | 147 ---------------------------------------- 1 file changed, 147 deletions(-) delete mode 100644 src/effects/hybrid_3d_effect.cc (limited to 'src/effects/hybrid_3d_effect.cc') diff --git a/src/effects/hybrid_3d_effect.cc b/src/effects/hybrid_3d_effect.cc deleted file mode 100644 index 61f3165..0000000 --- a/src/effects/hybrid_3d_effect.cc +++ /dev/null @@ -1,147 +0,0 @@ -// This file is part of the 64k demo project. -// It implements the Hybrid3DEffect. - -#include "effects/hybrid_3d_effect.h" -#include "generated/assets.h" -#include "util/asset_manager_utils.h" -#include -#include -#include - -Hybrid3DEffect::Hybrid3DEffect(const GpuContext& ctx) : Effect(ctx) { -} - -void Hybrid3DEffect::resize(int width, int height) { - if (width == width_ && height == height_) - return; - - Effect::resize(width, height); - - if (!initialized_) - return; - - renderer_.resize(width_, height_); -} - -void Hybrid3DEffect::init(MainSequence* demo) { - (void)demo; - WGPUTextureFormat format = - demo->gpu_ctx.format; // Get current format from MainSequence (might be - // different than constructor if resized) - - renderer_.init(ctx_.device, ctx_.queue, ctx_.format); - renderer_.resize(width_, height_); - initialized_ = true; - - // Texture Manager - texture_manager_.init(ctx_.device, ctx_.queue); - - // Load Noise Asset - TextureAsset noise_tex = GetTextureAsset(AssetId::ASSET_NOISE_TEX); - if (noise_tex.pixels && noise_tex.width == 256 && noise_tex.height == 256) { - texture_manager_.create_texture("noise", noise_tex.width, noise_tex.height, - noise_tex.pixels); - renderer_.set_noise_texture(texture_manager_.get_texture_view("noise")); - } else { - std::cerr << "Failed to load NOISE_TEX asset." << std::endl; - } - - // Setup Scene - scene_.clear(); - Object3D center(ObjectType::BOX); // Use BOX for bumps - center.position = vec3(0, 0, 0); - center.color = vec4(1, 0, 0, 1); - scene_.add_object(center); - - for (int i = 0; i < 8; ++i) { - ObjectType type = ObjectType::SPHERE; - if (i % 3 == 1) - type = ObjectType::TORUS; - if (i % 3 == 2) - type = ObjectType::BOX; - - Object3D obj(type); - - float angle = (i / 8.0f) * 6.28318f; - - obj.position = vec3(std::cos(angle) * 4.0f, 0, std::sin(angle) * 4.0f); - - obj.scale = vec3(0.7f, 0.7f, 0.7f); // Increased scale by 40% - - if (type == ObjectType::SPHERE) - obj.color = vec4(0, 1, 0, 1); - - else if (type == ObjectType::TORUS) - obj.color = vec4(0, 0.5, 1, 1); - else - obj.color = vec4(1, 1, 0, 1); - - scene_.add_object(obj); - } -} - -// Cubic ease-in/out function for non-linear motion - -static float ease_in_out_cubic(float t) { - t *= 2.0f; - - if (t < 1.0f) { - return 0.5f * t * t * t; - } - - t -= 2.0f; - - return 0.5f * (t * t * t + 2.0f); -} - -void Hybrid3DEffect::render(WGPURenderPassEncoder pass, - const CommonPostProcessUniforms& uniforms) { - // Animate Objects - - for (size_t i = 1; i < scene_.objects.size(); ++i) { - scene_.objects[i].rotation = - quat::from_axis(vec3(0, 1, 0), uniforms.time * 2.0f + i); - - scene_.objects[i].position.y = std::sin(uniforms.time * 3.0f + i) * 1.5f; - } - - // Camera jumps every other pattern (2 seconds) for dramatic effect - int pattern_num = (int)(uniforms.time / 2.0f); - int camera_preset = pattern_num % 4; // Cycle through 4 different angles - - vec3 cam_pos, cam_target; - - switch (camera_preset) { - case 0: // High angle, orbiting - { - float angle = uniforms.time * 0.5f; - cam_pos = vec3(std::sin(angle) * 12.0f, 8.0f, std::cos(angle) * 12.0f); - cam_target = vec3(0, 0, 0); - } break; - case 1: // Low angle, close-up - { - float angle = uniforms.time * 0.3f + 1.57f; // Offset angle - cam_pos = vec3(std::sin(angle) * 6.0f, 2.0f, std::cos(angle) * 6.0f); - cam_target = vec3(0, 1, 0); - } break; - case 2: // Side view, sweeping - { - float sweep = std::sin(uniforms.time * 0.4f) * 10.0f; - cam_pos = vec3(sweep, 5.0f, 8.0f); - cam_target = vec3(0, 0, 0); - } break; - case 3: // Top-down, rotating - { - float angle = uniforms.time * 0.6f; - cam_pos = vec3(std::sin(angle) * 5.0f, 12.0f, std::cos(angle) * 5.0f); - cam_target = vec3(0, 0, 0); - } break; - } - - camera_.set_look_at(cam_pos, cam_target, vec3(0, 1, 0)); - camera_.aspect_ratio = uniforms.aspect_ratio; - - // Draw - - renderer_.draw(pass, scene_, camera_, uniforms.time); -} -- cgit v1.2.3