code / hill-noise

Lines837 Lua675 GLSL103 Markdown59
(74 lines)

Hill Noise

This is a lua library implementation of 1D, 2D, and 3D Hill Noise. This random noise function generates continuous approximately uniformly distributed pseudorandom noise values in the range (0-1) with configurable resolution, level of detail, and shape characteristics.

API

  • make1d([opts]) Return 1D noise function and 1D noise gradient function.
  • make2d([opts]) Return 2D noise function and 2D noise gradient function.
  • make3d([opts]) Return 3D noise function and 3D noise gradient function.
  • make1dShader([opts]) Return 1D noise shader and 1D noise gradient shader (LÖVE only).
  • make2dShader([opts]) Return 2D noise shader and 2D noise gradient shader (LÖVE only).
  • make3dShader([opts]) Return 3D noise shader and 3D noise gradient shader (LÖVE only).

Usage

local Noise = require 'hill_noise'
local noise,noise_gradient = Noise.make3d{resolution=9}
local x,y,z = 1,2,3
local n = noise(x,y,z)
local dndx,dndy,dndz = noise_gradient(x,y,z)

Parameters

The noise construction functions all take the following options:

  • random: a random number function (default: math.random)
  • seed: if "random" is not provided, and the love.math module is loaded, a new pseudorandom number generator will be used with the specified seed
  • amplitudes: a list of sine wave amplitudes to use
  • resolution: if "amplitudes" is not provided, the number of sine waves to use (default: 5,7,9 for 1d,2d,3d functions, and 10,15,20 for 1d,2d,3d shaders)
  • distribution: if "amplitudes" is not provided, a function to evenly sample amplitudes from on the interval (0,1) (default: 0.1^x)

Runtime

The noise and noise gradient functions all run in O(resolution), and more resolution may be needed for higher dimensional noise and additional detail.

LÖVE

This library also include 1D, 2D, and 3D noise shaders for use with the LÖVE game engine. The shader versions are much faster for producing many noise values, as they run in parallel on the GPU. There is a demo available in the demo/ directory that can be run with LÖVE. If the demo fails to find hill_noise.lua, then just copy into the demo directory.

local noise_shader, noise_gradient_shader = Noise.make3dShader{resolution=11}
local canvas = love.graphics.newCanvas()
-- At each location on the texture, the noise function is sampled at a linear
--   interpolation between range_min and range_max, using the texture coordinates.
--   For 3D noise, the "z" value is passed as a parameter.
noise_shader:send("range_min", {0,20})
noise_shader:send("range_max", {0,20})
noise_shader:send('z', love.timer.getTime())
love.graphics.setShader(noise_shader)
love.graphics.draw(canvas)
love.graphics.setShader()

The noise gradient shaders populate the RGB channels with:

  • for 1D: sigmoid(2*dn/dx), sigmoid(2*dn/dx), sigmoid(2*dn/dx)
  • for 2D: sigmoid(1.5*dn/dx), sigmoid(1.5*dn/dy), 0
  • for 3D: sigmoid(4*dn/dx), sigmoid(4*dn/dy), sigmoid(4*dn/dz)

(coefficients were arbitrarily chosen to best squash typical gradients for the default parameters evenly into (0,1))

Additionally, the 1D noise shader has an extra variable draw_outline that, if set to true, makes the 1D shader render output as white or black if the y-coordinate is above/below the noise value for a given x-coordinate.

1 # Hill Noise
3 This is a lua library implementation of 1D, 2D, and 3D [Hill Noise](http://blog.bruce-hill.com/hill-noise/).
4 This random noise function generates continuous approximately uniformly distributed pseudorandom noise
5 values in the range (0-1) with configurable resolution, level of detail, and shape characteristics.
7 ## API
9 * `make1d([opts])` Return 1D noise function and 1D noise gradient function.
10 * `make2d([opts])` Return 2D noise function and 2D noise gradient function.
11 * `make3d([opts])` Return 3D noise function and 3D noise gradient function.
12 * `make1dShader([opts])` Return 1D noise shader and 1D noise gradient shader (LÖVE only).
13 * `make2dShader([opts])` Return 2D noise shader and 2D noise gradient shader (LÖVE only).
14 * `make3dShader([opts])` Return 3D noise shader and 3D noise gradient shader (LÖVE only).
16 ## Usage
18 ```lua
19 local Noise = require 'hill_noise'
20 local noise,noise_gradient = Noise.make3d{resolution=9}
21 local x,y,z = 1,2,3
22 local n = noise(x,y,z)
23 local dndx,dndy,dndz = noise_gradient(x,y,z)
24 ```
26 ## Parameters
27 The noise construction functions all take the following options:
29 * random: a random number function (default: math.random)
30 * seed: if "random" is not provided, and the love.math module is loaded, a new
31 pseudorandom number generator will be used with the specified seed
32 * amplitudes: a list of sine wave amplitudes to use
33 * resolution: if "amplitudes" is not provided, the number of sine waves to use
34 (default: 5,7,9 for 1d,2d,3d functions, and 10,15,20 for 1d,2d,3d shaders)
35 * distribution: if "amplitudes" is not provided, a function to evenly sample
36 amplitudes from on the interval (0,1) (default: 0.1^x)
38 ### Runtime
39 The noise and noise gradient functions all run in O(resolution), and more resolution
40 may be needed for higher dimensional noise and additional detail.
42 ## LÖVE
44 This library also include 1D, 2D, and 3D noise shaders for use with the [LÖVE game engine](https://love2d.org/).
45 The shader versions are much faster for producing many noise values, as they run in parallel on the GPU.
46 There is a demo available in the demo/ directory that can be run with LÖVE. If the demo
47 fails to find `hill_noise.lua`, then just copy into the demo directory.
49 ```lua
50 local noise_shader, noise_gradient_shader = Noise.make3dShader{resolution=11}
51 local canvas = love.graphics.newCanvas()
52 -- At each location on the texture, the noise function is sampled at a linear
53 -- interpolation between range_min and range_max, using the texture coordinates.
54 -- For 3D noise, the "z" value is passed as a parameter.
55 noise_shader:send("range_min", {0,20})
56 noise_shader:send("range_max", {0,20})
57 noise_shader:send('z', love.timer.getTime())
58 love.graphics.setShader(noise_shader)
59 love.graphics.draw(canvas)
60 love.graphics.setShader()
61 ```
63 The noise gradient shaders populate the RGB channels with:
65 * for 1D: `sigmoid(2*dn/dx)`, `sigmoid(2*dn/dx)`, `sigmoid(2*dn/dx)`
66 * for 2D: `sigmoid(1.5*dn/dx)`, `sigmoid(1.5*dn/dy)`, `0`
67 * for 3D: `sigmoid(4*dn/dx)`, `sigmoid(4*dn/dy)`, `sigmoid(4*dn/dz)`
69 (coefficients were arbitrarily chosen to best squash typical gradients for the default
70 parameters evenly into (0,1))
72 Additionally, the 1D noise shader has an extra variable `draw_outline` that, if set to
73 `true`, makes the 1D shader render output as white or black if the y-coordinate is
74 above/below the noise value for a given x-coordinate.