Add the dependency

In your project’s ziran.toml; pin ref to a commit for reproducible builds.

[dependencies.noise]
git = "https://github.com/ziranlang/noise.git"
ref = "master"

Overview

FastNoise :: #import "noise/fast_noise";

state := FastNoise.NoiseCreate()
state.seed = 1337
state.noise_type = FastNoise.NoiseType.OpenSimplex2S
state.fractal_type = FastNoise.FractalType.FBm
state.octaves = 3
height := FastNoise.Noise2D(*state, x, z)
density := FastNoise.Noise3D(*state, x, y, z)
  • Noise types: OpenSimplex2, OpenSimplex2S, Perlin, ValueCubic, Value
  • Fractals: None, FBm, Ridged, PingPong (octaves, lacunarity, gain, weighted_strength, ping_pong_strength)
  • 3D rotation: None, ImproveXYPlanes, ImproveXZPlanes

NoiseCreate() returns FastNoiseLite's defaults. Noise2D and Noise3D only read the state, so one state can be shared between threads.

make test compares 2112 values captured from FastNoiseLite C.

License: MIT, including the FastNoiseLite notice (see LICENSE).

noise/src/fast_noise.zi

fast_noise

FastNoiseLite gradient noise in pure Ziran: OpenSimplex2, OpenSimplex2S, Perlin, ValueCubic and Value, with FBm, Ridged and PingPong fractals. Ported from FastNoiseLite 1.1 (MIT, Copyright (c) 2023 Jordan Peck and contributors, see LICENSE). Every call reads the state only, so one state can be shared between threads. Results follow the C float32 implementation.

Import with #import "noise/fast_noise".

NoiseType :: enum { OpenSimplex2 = 0; OpenSimplex2S = 1; Perlin = 2; ValueCubic = 3; Value = 4; }
FractalType :: enum { None = 0; FBm = 1; Ridged = 2; PingPong = 3; }
RotationType3D :: enum { None = 0; ImproveXYPlanes = 1; ImproveXZPlanes = 2; }
NoiseState :: struct { seed: s32; frequency: float32; noise_type: NoiseType; rotation_type_3d: RotationType3D; fractal_type: FractalType; octaves: s32; lacunarity: float32; gain: float32; weighted_strength: float32; ping_pong_strength: float32; }
NoiseCreate :: () -> NoiseState

FastNoiseLite's defaults: seed 1337, frequency 0.01, OpenSimplex2, no fractal, 3 octaves, lacunarity 2, gain 0.5, ping-pong strength 2.

Gradients2D: [256]float32
Gradients3D: [256]float32
PRIME_X :: 501125321
PRIME_Y :: 1136930381
PRIME_Z :: 1720413743
PRIME_X2 :: 1002250642

The primes doubled, wrapped to s32 as FastNoiseLite's int shifts do.

PRIME_Y2 :: -2021106534
PRIME_Z2 :: -854139810
Min :: (a: float32, b: float32) -> float32
Abs :: (f: float32) -> float32
FastFloor :: (f: float32) -> s32

FastNoiseLite's floor and round: negative integers step down one more, which the generated lattice depends on.

FastRound :: (f: float32) -> s32
Lerp :: (a: float32, b: float32, t: float32) -> float32
InterpHermite :: (t: float32) -> float32
InterpQuintic :: (t: float32) -> float32
CubicLerp :: (a: float32, b: float32, c: float32, d: float32, t: float32) -> float32
PingPong :: (value: float32) -> float32
FractalBounding :: (state: *NoiseState) -> float32
Hash2D :: (seed: s32, x: s32, y: s32) -> s32
Hash3D :: (seed: s32, x: s32, y: s32, z: s32) -> s32
ValCoord2D :: (seed: s32, x: s32, y: s32) -> float32
ValCoord3D :: (seed: s32, x: s32, y: s32, z: s32) -> float32
GradCoord2D :: (seed: s32, x: s32, y: s32, xd: float32, yd: float32) -> float32
GradCoord3D :: (seed: s32, x: s32, y: s32, z: s32, xd: float32, yd: float32, zd: float32) -> float32
Simplex2D :: (seed: s32, x: float32, y: float32) -> float32

OpenSimplex2 in 2D is ordinary simplex noise on the skewed coordinates.

OpenSimplex23D :: (seed: s32, x: float32, y: float32, z: float32) -> float32

OpenSimplex2 in 3D: two offset, rotated cube grids.

OpenSimplex2S2D :: (seed: s32, x: float32, y: float32) -> float32

OpenSimplex2S in 2D: a smoother simplex variant with a wider kernel.

OpenSimplex2S3D :: (seed: s32, x: float32, y: float32, z: float32) -> float32

OpenSimplex2S in 3D: two offset, rotated cube grids with a wider kernel.

Perlin2D :: (seed: s32, x: float32, y: float32) -> float32
Perlin3D :: (seed: s32, x: float32, y: float32, z: float32) -> float32
ValueCubicRow2D :: (seed: s32, x0: s32, x1: s32, x2: s32, x3: s32, y: s32, t: float32) -> float32
ValueCubic2D :: (seed: s32, x: float32, y: float32) -> float32
ValueCubicRow3D :: (seed: s32, x0: s32, x1: s32, x2: s32, x3: s32, y: s32, z: s32, t: float32) -> float32
ValueCubicPlane3D :: (seed: s32, x0: s32, x1: s32, x2: s32, x3: s32, y0: s32, y1: s32, y2: s32, y3: s32, z: s32, xs: float32, ys: float32) -> float32
ValueCubic3D :: (seed: s32, x: float32, y: float32, z: float32) -> float32
Value2D :: (seed: s32, x: float32, y: float32) -> float32
Value3D :: (seed: s32, x: float32, y: float32, z: float32) -> float32
Single2D :: (state: *NoiseState, seed: s32, x: float32, y: float32) -> float32
Single3D :: (state: *NoiseState, seed: s32, x: float32, y: float32, z: float32) -> float32
Fractal :: struct { sum: float32; amp: float32; }

Adds one octave. FastNoiseLite caps the 2D FBm weight at noise + 1 <= 2

Octave :: (state: *NoiseState, noise: float32, fractal: *Fractal, capped: bool)

Adds one octave. FastNoiseLite caps the 2D FBm weight at noise + 1 <= 2 but not the 3D one, so CAPPED selects the 2D form.

Noise2D :: (state: *NoiseState, x: float32, y: float32) -> float32

Noise at (x, y), in about -1 to 1.

Noise3D :: (state: *NoiseState, x: float32, y: float32, z: float32) -> float32

Noise at (x, y, z), in about -1 to 1.

Source ↗