SimplexNoise

Seeded Simplex noise, fractals, domain warping, modifiers, batch sampling and PNG rendering

simplex-noise
procedural-generation
fbm
open-simplex
moon add ZSeanYves/SimplexNoise@0.2.0
Download zip
Author
Version
0.2.0
License
Apache-2.0
Last updated
27 days ago
Downloads
25

Dependencies

README

#SimplexNoise for MoonBit

Build Status License

SimplexNoise 0.2.0 is a deterministic procedural-noise library for MoonBit. It provides Classic Simplex in 2D/3D/4D, FastNoiseLite-compatible OpenSimplex2 and OpenSimplex2S in 2D/3D, validated fractal combiners, stateless domain warping, strictly periodic 2D noise, composable modifiers, allocation-free grid filling, and optional PNG rendering.

The project is tested with Moon 0.1.20260713 on wasm, wasm-gc, js, and native.

OpenSimplex2SfBm
OpenSimplex2S grayscale examplefBm color example

#Install

moon add ZSeanYves/SimplexNoise

Import only the packages you need:

import {
"ZSeanYves/SimplexNoise/core",
"ZSeanYves/SimplexNoise/fractal",
}

#Sampling

let classic = @core.Simplex::new(42U)
let open2 = @core.OpenSimplex2::new(42U)
let open2s = @core.OpenSimplex2S::new(42U)

let a = classic.sample4(0.1, 0.2, 0.3, 0.4)
let b = open2.sample3(0.1, 0.2, 0.3)
let c = open2s.sample2(0.1, 0.2)

Sources are immutable and should be constructed once and reused.

All samplers accept finite coordinates in [-100000000, 100000000]. NaN, infinity, and coordinates outside that range return NaN. This avoids backend-dependent integer saturation at the lattice conversion boundary. The reference families and external corpus are documented in the numerical contracts.

For dense fields, fill a caller-owned buffer without per-sample allocation:

let pixels = FixedArray::make(256 * 256, 0.0)
@core.fill2(open2s, pixels, 256, 256, step_x=0.01, step_y=0.01).unwrap()

#Fractals and warping

let config = @fractal.FbmConfig::new(
octaves=6,
persistence=0.5,
lacunarity=2.0,
frequency=0.01,
).unwrap()

let source = @core.OpenSimplex2S::new(42U)
let fbm = @fractal.Fbm::new(source, config)
let terrain = fbm.sample2(128.0, 64.0)

let warp_config = @fractal.WarpConfig::new(
strength=2.0,
frequency=0.02,
limit=1.5,
mode=Progressive,
octaves=3,
).unwrap()
let warped = @fractal.DomainWarp2::new(
source,
@core.OpenSimplex2S::new(73U),
warp_config,
)
let warped_value = warped.sample2(128.0, 64.0)

Each fBm/Billow/Ridged octave is recreated with seed + octave through the Seedable trait. Ridged implements feedback-weighted RidgedMulti behavior; Ridged::with_attenuation changes its default attenuation of 2.0. DomainWarp2 and DomainWarp3 support Single, Progressive, and Independent modes.

#Modifiers

The fractal package provides ScaleBias, Clamp, AddNoise, MultiplyNoise, Blend, Select, Curve, Terrace, and dimension-specific Transform2/Transform3/Transform4. Constructors validate finite parameters, bounds, and ordered control points before the sampling hot path.

#Strict 2D tiling

Tileable2 embeds two periodic coordinates into four dimensions. Its source must implement Noise4; Classic Simplex is the built-in choice.

let tiled = @fractal.Tileable2::new(
@core.Simplex::new(9U),
width=256.0,
height=256.0,
).unwrap()

let left = tiled.sample2(0.0, 32.0)
let right = tiled.sample2(256.0, 32.0)

#PNG demo

The renderer is isolated from the algorithm packages. Run the demo with an optional output prefix, image size, and seed:

moon run src/cmd/noise-demo --target native -- noise-demo 256 42

This writes noise-demo-simplex.png and noise-demo-fbm.png. Malformed sizes/seeds and sizes outside 1..8192 terminate with a non-zero exit status. PNG encoder and filesystem errors are propagated.

#Package layout

src/core/ sources, Seedable, coordinate contract, fill2/fill3 src/fractal/ fractals, 2D/3D warp, tiling, modifiers/transforms src/render/ grayscale/hue PNG encoding and file output src/cmd/noise-demo/ runnable image example

core has no third-party dependency. Image and filesystem dependencies are confined to render.

#Migration from 0.1.x

0.1.x0.2.0
arrays of coordinates, gradients, and permutation tablesimmutable source objects with fixed-dimensional methods
create2d / simplex2d@core.Simplex::new(seed).sample2(x, y)
seven positional fBm parametersvalidated FbmConfig plus Fbm
every octave reused one sourceindependently seeded octave sources
global new_maxwarp stateimmutable WarpConfig plus DomainWarp2
approximate 2D/3D/4D tile helpersstrict 2D Tileable2 contract
image functions in the root package@render.render_png / write_png
3D/4D batch slice helpersremoved; capture z/w in a render callback and loop explicitly

The old APIs were removed intentionally. See the captured 0.1.1 baseline. Classic 2D/3D values also change because 0.2.0 fixes the intermediate-corner unskew signs; Classic 2D now uses Gustavson's 12-entry grad3 projection and normalization factor 70. Fractal values change because octaves now use independent seeds and Ridged now includes feedback attenuation.

#Verify

moon update moon fmt --check moon check --target all --deny-warn --warn-list +73 moon test --target all moon test --target native --enable-coverage moon coverage report -f summary moon bench src/core src/fractal --target native --release moon package --frozen

OpenSimplex reference tests use vectors generated from FastNoiseLite 1.1.1. Derived code and attribution are documented in NOTICE. The current native results are recorded in the 0.2.0 benchmark snapshot.

#License

Apache-2.0. See LICENSE.