-
Notifications
You must be signed in to change notification settings - Fork 13
Home
Clisk makes procedural image generation simple with a Clojure DSL.
The best way to get started using Clisk is to install it as a dependency from Clojars using either Leiningen or Maven. See details for the latest Clisk version on Clojars
Once installed you need to include clisk with something like the following code in your ns declaration:
(ns my-namespace
(:use [clisk live]))
The clisk.live
namespace contains everything you need to produce images with Clisk.
Images are made up by composing vector functions to create RGB values. The Clisk DSL allows you to declaratively define how the image will be computed. So when you are defining a Clisk image, what you are really doing is creating a function that computes the Red, Green and Blue values for each pixel as follows:
[red, green, blue] = f(x , y)
Where x and y are the co-ordinates of the pixel you are calculating in the image. By default, images are generated over for an (x,y) range of (0,0) to (1,1), with (0,0) being the top left corner. Interested reader smay note that (0,0) is conventionally top left in computer graphics but bottom left in mathematics. Don't ask me why :-)
As a simple example, you might want to create an image using the forllowing fomula:
[red, green, blue] = f(x , y) = [x, y, 0]
i.e. you want to use x
to determine the red component, y
to determine the green component and always set the blue component to zero. As the colour values x and y will change smoothly as you move across the image, this should give you a nice gradient-style blend of reds and greens.
In Clisk, you can view the image generated by this function as follows:
(show [x y 0])
As it happens, the current position vector [x y z t]
is very commonly used so you can use the shortcut pos
to get the same result. Although the pos
vector also includes z
and t
co-ordinates, both of these are zero by default so this produces the same result as [x y 0]
or [x y 0 0]
.
(show pos)
(for those who are curious about the implementation, x
, y
, z
and t
are actually scalar functions of the current texture position, and pos
is just a plain vector containing the symbols x, y, z and t)
You can create some interesting colours with formulae containing just x
, y
, z
and t
. However the real power of Clisk is that it enables you to build up complex image generation functions from a library of simple components, and methods to combine these in interesting ways.
The pre-defined checker
function, for example, creates a checkerboard from any two other colours or functions:
(def checker-pattern (checker 0 1)) ;; 0 and 1 are shortcuts for black=[0 0 0] and white=[1 1 1]
(show checker-pattern)
The scale
function enables you to scale a pattern appropriately. This allows to get a larger effective area of calculation - for example scaling by 0.25 (one quarter) will enable to to calculate the function over an effective (x,y) range of (0,0) to (4,4), so you will see 4x4=16 times as many features.
(show (scale 0.25 checker-pattern))
The offset
function allows you to twist an image using an offset provided by another function. The vnoise
function is particularly useful for this:
(show (scale 0.25 (offset vnoise checker-pattern) ))
Vector functions can also be used to provide colour. For example, if we multiply (using v*
) our chessboard by the vplasma
function, we get a nice colourful patterned effect. Multiplication can also be applied to our offset to get a greater level of distortion.
(show (scale 0.25 (offset (v* 6 vnoise) (v* vnoise checker-pattern)) ))
The gradient
function calculates the gradient of another function. If you apply this to a plasma
function, for example, it can be used to create a bumpy rock effect:
(show (v+ [0.9 0.6 0.3] (dot [0.2 0.2 0] (gradient plasma ))))
The seamless
function creates a seamless tileable 2D texture from any 4D texture. Again, the 4D noise
functions are good to use as a source:
(show (scale 0.25 (seamless 0.25 noise)))
You can also imitate 3D shaded objects
(show (viewport [-1 -1] [1 1]
(v*
(warp globe vplasma) ;; colour vector plasma texture, samples on the surface of a globe
(light-value [-1 -1 1] (height-normal globe))))) ;; diffuse lighting using globe as heightmap