;; Film Grain effect - adds film grain texture
(require-primitives "core")

(define-effect film_grain
  :params (
    (intensity :type float :default 0.2 :range [0 1])
    (colored :type bool :default false)
  )
  (let ((grain-amount (* intensity 50)))
    (map-pixels frame
      (lambda (x y c)
        (if colored
            (rgb (clamp (+ (red c) (gaussian 0 grain-amount)) 0 255)
                 (clamp (+ (green c) (gaussian 0 grain-amount)) 0 255)
                 (clamp (+ (blue c) (gaussian 0 grain-amount)) 0 255))
            (let ((n (gaussian 0 grain-amount)))
              (rgb (clamp (+ (red c) n) 0 255)
                   (clamp (+ (green c) n) 0 255)
                   (clamp (+ (blue c) n) 0 255))))))))
