// This file is part of the 64k demo project. // It declares the concrete effects used in the demo. #pragma once #include "3d/camera.h" #include "3d/renderer.h" #include "3d/scene.h" #include "effect.h" #include "gpu/effects/flash_effect.h" // FlashEffect with params support #include "gpu/effects/post_process_helper.h" #include "gpu/effects/shaders.h" #include "gpu/gpu.h" #include "gpu/texture_manager.h" #include "gpu/uniform_helper.h" #include static const int NUM_PARTICLES = 10000; struct Particle { float pos[4]; float vel[4]; float rot[4]; float color[4]; }; class HeptagonEffect : public Effect { public: HeptagonEffect(const GpuContext& ctx); void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; private: RenderPass pass_; }; class ParticlesEffect : public Effect { public: ParticlesEffect(const GpuContext& ctx); void compute(WGPUCommandEncoder encoder, float time, float beat, float intensity, float aspect_ratio) override; void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; private: ComputePass compute_pass_; RenderPass render_pass_; GpuBuffer particles_buffer_; }; class PassthroughEffect : public PostProcessEffect { public: PassthroughEffect(const GpuContext& ctx); void update_bind_group(WGPUTextureView input_view) override; }; class MovingEllipseEffect : public Effect { public: MovingEllipseEffect(const GpuContext& ctx); void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; private: RenderPass pass_; }; class ParticleSprayEffect : public Effect { public: ParticleSprayEffect(const GpuContext& ctx); void compute(WGPUCommandEncoder encoder, float time, float beat, float intensity, float aspect_ratio) override; void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; private: ComputePass compute_pass_; RenderPass render_pass_; GpuBuffer particles_buffer_; }; class GaussianBlurEffect : public PostProcessEffect { public: GaussianBlurEffect(const GpuContext& ctx); void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; void update_bind_group(WGPUTextureView input_view) override; }; class SolarizeEffect : public PostProcessEffect { public: SolarizeEffect(const GpuContext& ctx); void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; void update_bind_group(WGPUTextureView input_view) override; }; class DistortEffect : public PostProcessEffect { public: DistortEffect(const GpuContext& ctx); void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; void update_bind_group(WGPUTextureView input_view) override; }; // Parameters for ChromaAberrationEffect (set at construction time) struct ChromaAberrationParams { float offset_scale = 0.02f; // Default: 2% screen offset float angle = 0.0f; // Default: horizontal (0 radians) }; // Uniform data sent to GPU shader struct ChromaUniforms { float time; // offset 0 float beat; // offset 4 float intensity; // offset 8 float aspect_ratio; // offset 12 float width; // offset 16 float height; // offset 20 float offset_scale; // offset 24 float angle; // offset 28 }; static_assert(sizeof(ChromaUniforms) == 32, "ChromaUniforms must be 32 bytes for WGSL alignment"); class ChromaAberrationEffect : public PostProcessEffect { public: // Backward compatibility constructor (uses default params) ChromaAberrationEffect(const GpuContext& ctx); // New parameterized constructor ChromaAberrationEffect(const GpuContext& ctx, const ChromaAberrationParams& params); void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; void update_bind_group(WGPUTextureView input_view) override; private: ChromaAberrationParams params_; UniformBuffer uniforms_; }; class Hybrid3DEffect : public Effect { public: Hybrid3DEffect(const GpuContext& ctx); void init(MainSequence* demo) override; void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; private: Renderer3D renderer_; TextureManager texture_manager_; Scene scene_; Camera camera_; int width_ = 1280; int height_ = 720; }; class FlashCubeEffect : public Effect { public: FlashCubeEffect(const GpuContext& ctx); void init(MainSequence* demo) override; void resize(int width, int height) override; void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; private: Renderer3D renderer_; TextureManager texture_manager_; Scene scene_; Camera camera_; int width_ = 1280; int height_ = 720; float last_beat_; float flash_intensity_; }; class ThemeModulationEffect : public PostProcessEffect { public: ThemeModulationEffect(const GpuContext& ctx); void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; void update_bind_group(WGPUTextureView input_view) override; }; class FadeEffect : public PostProcessEffect { public: FadeEffect(const GpuContext& ctx); void render(WGPURenderPassEncoder pass, float time, float beat, float intensity, float aspect_ratio) override; void update_bind_group(WGPUTextureView input_view) override; }; // FlashEffect now defined in gpu/effects/flash_effect.h (included above) // Auto-generated functions void LoadTimeline(MainSequence& main_seq, const GpuContext& ctx); float GetDemoDuration(); // Returns demo end time in seconds, or -1 if not // specified