Add dynamic zoom and ripple amplitude to woods recipe
- Zoom now driven by audio energy via core:map-range - Ripple amplitude reads from dynamic_params in sexp_to_cuda - Crossfade transition with zoom in/out effect - Move git clone before COPY in Dockerfile for better caching Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -74,12 +74,12 @@ COPY --from=builder /decord-install /usr/local/lib/python3.11/dist-packages/
|
||||
COPY --from=builder /tmp/decord/build/libdecord.so /usr/local/lib/
|
||||
RUN ldconfig
|
||||
|
||||
# Copy application
|
||||
COPY . .
|
||||
|
||||
# Clone effects repo
|
||||
# Clone effects repo (before COPY so it gets cached)
|
||||
RUN git clone https://git.rose-ash.com/art-dag/effects.git /app/artdag-effects
|
||||
|
||||
# Copy application (this invalidates cache for any code change)
|
||||
COPY . .
|
||||
|
||||
# Create cache directory
|
||||
RUN mkdir -p /data/cache
|
||||
|
||||
|
||||
@@ -125,8 +125,8 @@
|
||||
dir (get cfg :dir)
|
||||
rot-max-a (get cfg :rot-a)
|
||||
rot-max-b (get cfg :rot-b)
|
||||
zoom-a (get cfg :zoom-a)
|
||||
zoom-b (get cfg :zoom-b)
|
||||
zoom-max-a (get cfg :zoom-a)
|
||||
zoom-max-b (get cfg :zoom-b)
|
||||
pair-angle (get pstate :angle)
|
||||
inv-a-on (> (get pstate :inv-a) 0)
|
||||
inv-b-on (> (get pstate :inv-b) 0)
|
||||
@@ -140,6 +140,10 @@
|
||||
angle-a (* dir pair-angle rot-max-a 0.01)
|
||||
angle-b (* dir pair-angle rot-max-b 0.01)
|
||||
|
||||
;; Energy-driven zoom (maps audio energy 0-1 to 1-max)
|
||||
zoom-a (core:map-range e 0 1 1 zoom-max-a)
|
||||
zoom-b (core:map-range e 0 1 1 zoom-max-b)
|
||||
|
||||
;; Define effect pipelines for each source
|
||||
;; These get compiled to single CUDA kernels!
|
||||
effects-a [{:op "zoom" :amount zoom-a}
|
||||
@@ -177,10 +181,20 @@
|
||||
;; Process active pair with fused pipeline
|
||||
active-frame (process-pair-fast active)
|
||||
|
||||
;; Crossfade during transition
|
||||
;; Crossfade with zoom during transition
|
||||
;; Old pair: zooms out (1.0 -> 2.0) and fades out
|
||||
;; New pair: starts small (0.1), zooms in (-> 1.0) and fades in
|
||||
result (if fading
|
||||
(let [next-frame (process-pair-fast next-idx)]
|
||||
(blending:blend-images active-frame next-frame fade-amt))
|
||||
(let [next-frame (process-pair-fast next-idx)
|
||||
;; Active zooms out as it fades
|
||||
active-zoom (+ 1.0 fade-amt)
|
||||
active-zoomed (streaming_gpu:fused-pipeline active-frame
|
||||
[{:op "zoom" :amount active-zoom}])
|
||||
;; Next starts small and zooms in
|
||||
next-zoom (+ 0.1 (* fade-amt 0.9))
|
||||
next-zoomed (streaming_gpu:fused-pipeline next-frame
|
||||
[{:op "zoom" :amount next-zoom}])]
|
||||
(blending:blend-images active-zoomed next-zoomed fade-amt))
|
||||
active-frame)
|
||||
|
||||
;; Final effects pipeline (fused!)
|
||||
@@ -198,4 +212,5 @@
|
||||
;; Apply final fused pipeline
|
||||
(streaming_gpu:fused-pipeline result final-effects
|
||||
:rotate_angle spin-angle
|
||||
:ripple_phase (* now 5)))))
|
||||
:ripple_phase (* now 5)
|
||||
:ripple_amplitude rip-amp))))
|
||||
|
||||
@@ -300,7 +300,7 @@ def _build_params(effects: List[dict], dynamic_params: dict) -> cp.ndarray:
|
||||
elif op == 'zoom':
|
||||
params.append(float(dynamic_params.get('zoom_amount', effect.get('amount', 1.0))))
|
||||
elif op == 'ripple':
|
||||
params.append(float(effect.get('amplitude', 10)))
|
||||
params.append(float(dynamic_params.get('ripple_amplitude', effect.get('amplitude', 10))))
|
||||
params.append(float(effect.get('frequency', 8)))
|
||||
params.append(float(effect.get('decay', 2)))
|
||||
params.append(float(dynamic_params.get('ripple_phase', effect.get('phase', 0))))
|
||||
|
||||
Reference in New Issue
Block a user