Creating a glow effect

Posted: October 4, 2012 in clisk, Uncategorized
Tags: , ,

Quick tutorial on how to create a “glow” effect for any image / shape in Clojure with Clisk.


The idea behind the glow effect is to do the following:

  • Start with an image that has an alpha channel indicating which areas are transparent
  • Extract the alpha channel to get the pure shape of the object
  • Create a glow effect by applying a blur filter to the shape
  • Superimpose the original object on top of the glow

So lets start with an object in our case an image of a moon with an alpha channel:

(def moon (viewport [-2 -2] [2 2]
  (vif (z globe)
    (v+ [0 0 0 1]
      (v* [1.0 0.8 0.7]
          (warp globe plasma)
          (v+ [0.4 0.5 0.6]
              (light-value [-1 -1 1] (height-normal globe)))))
    [0 0 0 0])))


We now want to extract the alpha channel and add a blur to it. This is reasonably easy:

(def blur-filter
     (doto (com.jhlabs.image.GaussianFilter.) (.setRadius 40)))

(def moon-glow
     (image-filter blur-filter (v* [0.0 1.0 0.0] (alpha moon))))

(show moon-glow)


Finally we superimpose the original moon back on top of the glow. The easiest way to do this is via linear interpolation (“lerp”), again using the alpha channel of the moon image to determine whether we should be drawing the moon or the background glow for each individual pixel:

(show (lerp (alpha moon) moon-glow moon))


And there you have it – a moon with a suspicious evil green glow.

The nice thing about all this is that you can encapsulate all this functionality into a higher order function to apply a glow effect to anything: here’s the source code for the new “add-glow” function in effects.clj:

(defn add-glow
  "Adds a glow effect to any image with an alpha channel"
   & {:keys [glow-radius glow-colour glow-background blur-image-size]      :or {glow-radius 0.2
           glow-colour yellow
           glow-background [0.0 0.0 0.0 0.0]
           blur-image-size 256}}]
  (let [alpha-channel (alpha image-with-alpha)
        blur-filter (doto
                      (.setRadius (int (* glow-radius blur-image-size))))
        glow-effect (lerp
                      (image-filter blur-filter alpha-channel)
  (lerp alpha-channel glow-effect image-with-alpha)))


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s