diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-16 11:54:46 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-16 11:54:46 +0100 |
| commit | af5d0e4c3a6cb773a4fb51ac32f4c33a7f8d8224 (patch) | |
| tree | a76464ca40a43d6042ed5431547008cfbe746c34 /src/effects/hybrid_3d_effect.cc | |
| parent | 8eeadaf0d5653c21b948103e4d328f634b739a17 (diff) | |
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 <noreply@anthropic.com>
Diffstat (limited to 'src/effects/hybrid_3d_effect.cc')
| -rw-r--r-- | src/effects/hybrid_3d_effect.cc | 147 |
1 files changed, 0 insertions, 147 deletions
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 <cassert> -#include <cmath> -#include <iostream> - -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); -} |
