Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Perlin noise function #174

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,19 @@ This can be used, for example, to draw a static sketch and then disable the draw

Example: [[https://github.com/vydd/sketch/blob/master/examples/control-flow.lisp][control-flow.lisp]].

*** Noise
=(noise &rest coords)= generates a correlated random value in the range 0-1. Similar inputs give similar outputs, hence the term "correlated". This can be useful for producing natural-looking textures and terrain, among other things. See [[https://en.wikipedia.org/wiki/Gradient_noise][Gradient noise]].

=(noise-seed seed)= seeds the noise so that its output is reproducible, where `seed` is an integer.

=(noise-detail &key lod falloff)= determines the 'character' of the noise, based on the =noiseDetail()= function from p5js.

* =lod= stands for Level Of Detail. It should be a positive integer value (default is 4), and determines how many noise values are generated and summed together to produce the final value. Lower values -> smoother and more efficient, higher values -> greater level of detail.
Kevinpgalligan marked this conversation as resolved.
Show resolved Hide resolved
* =falloff= should be between 0 and 1; its default value is 0.5. Each successive noise value in the sum is weighted by increasing powers of the falloff. A falloff of greater than 0.5 will possibly result in noise outputs of greater than 1.
* Another way to change the appearance of noise is to scale the inputs. Making the inputs smaller and closer together will make the output smoother. Scaling them up will have the opposite effect. The output value can also be scaled, obviously so that it goes outside the range 0-1.

Example: [[https://github.com/vydd/sketch/blob/master/examples/noise.lisp][noise.lisp]].

** Made with Sketch
- [[https://vydd.itch.io/qelt][QELT]]
- [[https://github.com/sjl/coding-math][sjl's implementation of coding math videos]]
Expand Down
16 changes: 16 additions & 0 deletions examples/noise.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
(in-package #:sketch-examples)

(defsketch noise-sketch
Kevinpgalligan marked this conversation as resolved.
Show resolved Hide resolved
((title "Noise")
(width 400)
(height 400)
(pixel-width 2)
(pixels (/ width pixel-width))
Kevinpgalligan marked this conversation as resolved.
Show resolved Hide resolved
(coord-scale 0.02))
(noise-seed 5)
(noise-detail :lod 1 :falloff 0.5)
(dotimes (i pixels)
(dotimes (j pixels)
Kevinpgalligan marked this conversation as resolved.
Show resolved Hide resolved
(with-pen (make-pen :fill (gray (noise (* coord-scale i) (* coord-scale j))))
(rect (* i pixel-width) (* j pixel-width) pixel-width pixel-width))))
(stop-loop))
4 changes: 3 additions & 1 deletion sketch.asd
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#:glu-tessellate
#:mathkit
#:md5
#:noisy
#:sdl2
#:cl-plus-c
#:sdl2-image
Expand Down Expand Up @@ -42,4 +43,5 @@
(:file "entities")
(:file "figures")
(:file "controllers")
(:file "canvas")))
(:file "canvas")
(:file "noise")))
43 changes: 43 additions & 0 deletions src/noise.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
;;;; noise.lisp

(in-package #:sketch)

;;; _ _ ____ _____ _____ ______
;;; | \ | |/ __ \_ _|/ ____| ____|
;;; | \| | | | || | | (___ | |__
;;; | . ` | | | || | \___ \| __|
;;; | |\ | |__| || |_ ____) | |____
;;; |_| \_|\____/_____|_____/|______|

(defun noise (&rest coordinates)
(when *sketch*
(if (null coordinates)
0
(let* ((noise-map (sketch-%noise-map *sketch*))
(d (length coordinates))
(state (gethash d noise-map)))
(when (not state)
(setf state (noisy:make-noise d
:seed (sketch-%noise-seed *sketch*)
:lod (sketch-%noise-lod *sketch*)
:falloff (sketch-%noise-falloff *sketch*)))
(setf (gethash d noise-map) state))
(apply #'noisy:noise-gen state coordinates)))))

(defun noise-seed (seed)
(when *sketch*
(setf (sketch-%noise-seed *sketch*) seed)
;; So that the noise state for each number of dimensions is reinitialised
;; with the new seed.
(reset-noise-map *sketch*)))

(defun noise-detail (&key lod falloff)
(when *sketch*
(when lod
(setf (sketch-%noise-lod *sketch*) lod))
(when falloff
(setf (sketch-%noise-falloff *sketch*) falloff))
(reset-noise-map *sketch*)))

(defun reset-noise-map (sketch)
(setf (sketch-%noise-map sketch) (make-hash-table)))
Kevinpgalligan marked this conversation as resolved.
Show resolved Hide resolved
5 changes: 5 additions & 0 deletions src/package.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,9 @@
;; Control flow
:start-loop
:stop-loop

;; Noise
:noise
:noise-seed
:noise-detail
))
4 changes: 4 additions & 0 deletions src/sketch.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
(%window :initform nil :accessor sketch-%window :initarg :window)
(%delayed-init-funs :initform (make-array 0 :adjustable t :fill-pointer t)
:accessor sketch-%delayed-init-funs)
(%noise-seed :initform 7 :accessor sketch-%noise-seed)
(%noise-map :initform (make-hash-table) :accessor sketch-%noise-map)
(%noise-lod :initform 4 :accessor sketch-%noise-lod)
(%noise-falloff :initform 0.5 :accessor sketch-%noise-falloff)
Kevinpgalligan marked this conversation as resolved.
Show resolved Hide resolved
(title :initform "Sketch" :accessor sketch-title :initarg :title)
(width :initform *default-width* :accessor sketch-width :initarg :width)
(height :initform *default-height* :accessor sketch-height :initarg :height)
Expand Down