Sign in

    SimplexNoise

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

    simplex-noise
    procedural-generation
    fbm
    open-simplex
    Download zip
    Author
    Version
    0.2.0
    License
    Apache-2.0
    Last updated
    3 months ago
    Downloads
    45

    #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.