Files
rose-ash/l1/sexp_effects/effects/xector_inset_blend.sexp
2026-02-24 23:07:19 +00:00

58 lines
2.1 KiB
Common Lisp
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
;; Inset blend - fade a smaller frame into a larger background
;; Uses distance-based alpha for smooth transition (no hard edges)
(require-primitives "xector")
(define-effect xector_inset_blend
:params (
(x :type int :default 0 :desc "X position of inset")
(y :type int :default 0 :desc "Y position of inset")
(fade-width :type int :default 50 :desc "Width of fade region in pixels")
(overlay :type frame :default nil :desc "The smaller frame to inset")
)
(let* (
;; Get dimensions
(bg-h (first (list (nth (list (red frame)) 0)))) ;; TODO: need image:height
(bg-w bg-h) ;; placeholder
;; For now, create a simple centered circular blend
;; Distance from center of overlay position
(cx (+ x (/ (- bg-w (* 2 x)) 2)))
(cy (+ y (/ (- bg-h (* 2 y)) 2)))
;; Get coordinates as xectors
(px (x-coords frame))
(py (y-coords frame))
;; Distance from center
(dx (α- px cx))
(dy (α- py cy))
(dist (αsqrt (α+ (α* dx dx) (α* dy dy))))
;; Inner radius (fully overlay) and outer radius (fully background)
(inner-r (- (/ bg-w 2) x fade-width))
(outer-r (- (/ bg-w 2) x))
;; Blend factor: 1.0 inside inner-r, 0.0 outside outer-r, linear between
(t (α/ (α- dist inner-r) fade-width))
(blend (α- 1 (αclamp t 0 1)))
;; Extract channels from both frames
(bg-r (red frame))
(bg-g (green frame))
(bg-b (blue frame)))
;; If overlay provided, blend it
(if overlay
(let* ((ov-r (red overlay))
(ov-g (green overlay))
(ov-b (blue overlay))
;; Linear blend: result = bg * (1-blend) + overlay * blend
(r-out (α+ (α* bg-r (α- 1 blend)) (α* ov-r blend)))
(g-out (α+ (α* bg-g (α- 1 blend)) (α* ov-g blend)))
(b-out (α+ (α* bg-b (α- 1 blend)) (α* ov-b blend))))
(rgb r-out g-out b-out))
;; No overlay - just show the blend mask for debugging
(let ((mask-vis (α* blend 255)))
(rgb mask-vis mask-vis mask-vis)))))