diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-11 11:34:08 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-11 11:34:08 +0100 |
| commit | d378da77eec4d506bc01e4c08c38644d72969cc7 (patch) | |
| tree | 5cc38517320ba3aefb46a2f9c939c9fdc8ed5fae /src/gpu/effect.cc | |
| parent | 4da0a3a5369142078fd7c681e3f0f1817bd6e2f3 (diff) | |
refactor: Simplify effect render API and fix uniform initialization
Root cause: Uniform buffers created but not initialized before bind group
creation, causing undefined UV coordinates in circle_mask_compute.wgsl.
Changes:
- Add get_common_uniforms() helper to Effect base class
- Refactor render()/compute() signatures: 5 params → CommonPostProcessUniforms&
- Fix uninitialized uniforms in CircleMaskEffect and CNNEffect
- Update all 19 effect implementations and headers
- Fix WGSL syntax error in FlashEffect (u.audio_intensity → audio_intensity)
- Update test files (test_sequence.cc)
Benefits:
- Cleaner API: construct uniforms once per frame, reuse across effects
- More maintainable: CommonPostProcessUniforms changes need no call site updates
- Fixes UV coordinate bug in circle_mask_compute.wgsl
All 36 tests passing (100%)
handoff(Claude): Effect API refactor complete
Diffstat (limited to 'src/gpu/effect.cc')
| -rw-r--r-- | src/gpu/effect.cc | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/src/gpu/effect.cc b/src/gpu/effect.cc index fba3353..528d7fc 100644 --- a/src/gpu/effect.cc +++ b/src/gpu/effect.cc @@ -12,8 +12,9 @@ #include <vector> // --- PostProcessEffect --- -void PostProcessEffect::render(WGPURenderPassEncoder pass, float, float, float, - float) { +void PostProcessEffect::render(WGPURenderPassEncoder pass, + const CommonPostProcessUniforms& uniforms) { + (void)uniforms; // Base implementation doesn't use uniforms if (pipeline_ && bind_group_) { wgpuRenderPassEncoderSetPipeline(pass, pipeline_); wgpuRenderPassEncoderSetBindGroup(pass, 0, bind_group_, 0, nullptr); @@ -256,9 +257,19 @@ void MainSequence::render_frame(float global_time, float beat, float peak, }); // 1. Compute + // Construct common uniforms once (reused for all effects) + CommonPostProcessUniforms base_uniforms = { + .resolution = {static_cast<float>(width_), static_cast<float>(height_)}, + ._pad = {0.0f, 0.0f}, + .aspect_ratio = aspect_ratio, + .time = 0.0f, // Will be set per-effect + .beat = beat, + .audio_intensity = peak, + }; + for (const SequenceItem* item : scene_effects) { - item->effect->compute(encoder, global_time - item->start_time, beat, peak, - aspect_ratio); + base_uniforms.time = global_time - item->start_time; + item->effect->compute(encoder, base_uniforms); } // 2. Scene Pass (to A) @@ -287,8 +298,8 @@ void MainSequence::render_frame(float global_time, float beat, float peak, wgpuRenderPassEncoderSetViewport(scene_pass, 0.0f, 0.0f, (float)width_, (float)height_, 0.0f, 1.0f); for (const SequenceItem* item : scene_effects) { - item->effect->render(scene_pass, global_time - item->start_time, beat, peak, - aspect_ratio); + base_uniforms.time = global_time - item->start_time; + item->effect->render(scene_pass, base_uniforms); } wgpuRenderPassEncoderEnd(scene_pass); @@ -326,7 +337,8 @@ void MainSequence::render_frame(float global_time, float beat, float peak, PostProcessEffect* passthrough = (PostProcessEffect*)passthrough_effect_.get(); passthrough->update_bind_group(framebuffer_view_a_); - passthrough->render(capture_pass, 0, 0, 0, aspect_ratio); + base_uniforms.time = 0.0f; + passthrough->render(capture_pass, base_uniforms); wgpuRenderPassEncoderEnd(capture_pass); } @@ -358,7 +370,8 @@ void MainSequence::render_frame(float global_time, float beat, float peak, wgpuCommandEncoderBeginRenderPass(encoder, &final_desc); wgpuRenderPassEncoderSetViewport(final_pass, 0.0f, 0.0f, (float)width_, (float)height_, 0.0f, 1.0f); - passthrough_effect_->render(final_pass, 0, 0, 0, aspect_ratio); + base_uniforms.time = 0.0f; + passthrough_effect_->render(final_pass, base_uniforms); wgpuRenderPassEncoderEnd(final_pass); } else { WGPUTextureView current_input = framebuffer_view_a_; @@ -395,8 +408,8 @@ void MainSequence::render_frame(float global_time, float beat, float peak, wgpuCommandEncoderBeginRenderPass(encoder, &pp_desc); wgpuRenderPassEncoderSetViewport(pp_pass, 0.0f, 0.0f, (float)width_, (float)height_, 0.0f, 1.0f); - pp->render(pp_pass, global_time - post_effects[i]->start_time, beat, peak, - aspect_ratio); + base_uniforms.time = global_time - post_effects[i]->start_time; + pp->render(pp_pass, base_uniforms); wgpuRenderPassEncoderEnd(pp_pass); current_input = current_output; } @@ -511,8 +524,15 @@ void MainSequence::simulate_until(float target_time, float step_rate, } } for (const SequenceItem* item : scene_effects) { - item->effect->compute(encoder, t - item->start_time, beat, 0.0f, - aspect_ratio); + CommonPostProcessUniforms test_uniforms = { + .resolution = {static_cast<float>(width_), static_cast<float>(height_)}, + ._pad = {0.0f, 0.0f}, + .aspect_ratio = aspect_ratio, + .time = t - item->start_time, + .beat = beat, + .audio_intensity = 0.0f, + }; + item->effect->compute(encoder, test_uniforms); } WGPUCommandBuffer commands = wgpuCommandEncoderFinish(encoder, nullptr); wgpuQueueSubmit(gpu_ctx.queue, 1, &commands); |
