Import L1 (celery) as l1/

This commit is contained in:
giles
2026-02-24 23:07:19 +00:00
225 changed files with 57298 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
;; Halftone/dot effect - built from primitive xector operations
;;
;; Uses:
;; pool-frame - downsample to cell luminances
;; cell-indices - which cell each pixel belongs to
;; gather - look up cell value for each pixel
;; local-x/y-norm - position within cell [0,1]
;; where - conditional per-pixel
(require-primitives "xector")
(define-effect halftone
:params (
(cell-size :type int :default 12 :range [4 32] :desc "Size of halftone cells")
(dot-scale :type float :default 0.9 :range [0.1 1.0] :desc "Max dot radius")
(invert :type bool :default false :desc "Invert (white dots on black)")
)
(let* (
;; Pool frame to get luminance per cell
(pooled (pool-frame frame cell-size))
(cell-lum (nth pooled 3)) ; luminance is 4th element
;; For each output pixel, get its cell index
(cell-idx (cell-indices frame cell-size))
;; Get cell luminance for each pixel
(pixel-lum (α/ (gather cell-lum cell-idx) 255))
;; Position within cell, normalized to [-0.5, 0.5]
(lx (α- (local-x-norm frame cell-size) 0.5))
(ly (α- (local-y-norm frame cell-size) 0.5))
;; Distance from cell center (0 at center, ~0.7 at corners)
(dist (αsqrt (α+ (α² lx) (α² ly))))
;; Radius based on luminance (brighter = bigger dot)
(radius (α* (if invert (α- 1 pixel-lum) pixel-lum)
(α* dot-scale 0.5)))
;; Is this pixel inside the dot?
(inside (α< dist radius))
;; Output color
(fg (if invert 255 0))
(bg (if invert 0 255))
(out (where inside fg bg)))
;; Grayscale output
(rgb out out out)))