npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

fractal-brownian-noise

v1.0.1

Published

Fractal Brownian Motion (fBm) noise implementation for procedural generation

Readme

Fractal Brownian Motion (fBm) Noise Library

A TypeScript library for generating fractal Brownian motion noise with multiple octaves, perfect for procedural:

  • terrain generation,
  • textures,
  • and natural patterns.

Overview

Fractal Brownian Motion (fBm) combines multiple layers of noise at different scales (octaves) to create natural-looking patterns with detail at multiple levels. This technique is fundamental in procedural generation for games and simulations.

Installation

This library is designed to work with simplex-noise:

npm install simplex-noise

Basic Usage

import { createNoise2D } from "simplex-noise";
import { fbm2D } from "./index";

const noise2D = createNoise2D();

// Generate terrain height
const height = fbm2D(
  x,
  y,
  {
    octaves: 6,
    lacunarity: 2.0,
    gain: 0.5,
    frequency: 0.01,
  },
  noise2D
);

API Reference

fbm2D(x, y, options, noiseFunc)

Generates 2D fractal Brownian motion noise.

Parameters:

  • x: number - X coordinate
  • y: number - Y coordinate
  • options: FbmOptions - Configuration (optional)
  • noiseFunc: NoiseFunction2D - 2D noise function from simplex-noise

Returns: number - Noise value between -1 and 1

fbm3D(x, y, z, options, noiseFunc)

Generates 3D fractal Brownian motion noise. Great for animated effects using time as the third dimension.

fbm4D(x, y, z, w, options, noiseFunc)

Generates 4D fractal Brownian motion noise. Useful for seamlessly looping animated textures.

Configuration Options

interface FbmOptions {
  octaves?: number; // Number of noise layers (default: 4)
  lacunarity?: number; // Frequency multiplier per octave (default: 2.0)
  gain?: number; // Amplitude multiplier per octave (default: 0.5)
  amplitude?: number; // Initial amplitude (default: 1.0)
  frequency?: number; // Initial frequency (default: 1.0)
}

Understanding Parameters

  • Octaves: More octaves = more detail, but slower performance (typical: 4-8)
  • Lacunarity: How quickly frequency increases per octave (typical: 2.0)
  • Gain (Persistence): How quickly amplitude decreases per octave (typical: 0.5)
  • Frequency: Scale of the noise pattern (lower = larger features)
  • Amplitude: Overall strength of the noise

Advanced Functions

Ridged Multifractal

Creates sharp ridges, perfect for mountain ranges:

import { ridgedMultifractal2D } from "./index";

const mountainHeight = ridgedMultifractal2D(
  x,
  y,
  {
    octaves: 6,
    lacunarity: 2.5,
    gain: 0.5,
  },
  noise2D
);

Turbulence

Creates chaotic, turbulent patterns:

import { turbulence2D } from "./index";

const chaosValue = turbulence2D(x, y, { octaves: 4 }, noise2D);

Domain Warping

Warps the noise space for more organic, interesting patterns:

import { domainWarp2D } from "./index";

const warpedNoise = domainWarp2D(
  x,
  y,
  1.5, // warp strength
  { octaves: 5 },
  noise2D
);

Billow Noise

Creates puffy, cloud-like patterns:

import { billow2D } from "./index";

const cloudDensity = billow2D(x, y, { octaves: 4 }, noise2D);

Practical Examples

Terrain Generation

import { createNoise2D } from "simplex-noise";
import { fbm2D, ridgedMultifractal2D } from "./index";

const noise2D = createNoise2D();

function generateTerrain(x: number, y: number): number {
  // Base terrain
  const base = fbm2D(
    x,
    y,
    {
      octaves: 6,
      frequency: 0.005,
      lacunarity: 2.0,
      gain: 0.5,
    },
    noise2D
  );

  // Add mountains
  const mountains = ridgedMultifractal2D(
    x,
    y,
    {
      octaves: 4,
      frequency: 0.003,
      lacunarity: 2.5,
    },
    noise2D
  );

  // Combine
  return base * 0.7 + mountains * 0.3;
}

Animated Clouds

import { createNoise3D } from "simplex-noise";
import { fbm3D } from "./index";

const noise3D = createNoise3D();

function getCloudDensity(x: number, y: number, time: number): number {
  return fbm3D(
    x,
    y,
    time * 0.1,
    {
      octaves: 4,
      frequency: 0.01,
      gain: 0.6,
    },
    noise3D
  );
}

Wood Texture

import { createNoise2D } from "simplex-noise";
import { fbm2D } from "./index";

const noise2D = createNoise2D();

function woodGrain(x: number, y: number): number {
  const distance = Math.sqrt(x * x + y * y);
  const rings = Math.sin(distance * 0.5);
  const distortion = fbm2D(x, y, { octaves: 3 }, noise2D) * 0.3;

  return rings + distortion;
}

Procedural Biomes

import { createNoise2D } from "simplex-noise";
import { fbm2D, domainWarp2D } from "./index";

const noise2D = createNoise2D();

function getBiome(x: number, y: number): string {
  const temperature = fbm2D(
    x,
    y,
    {
      octaves: 4,
      frequency: 0.002,
    },
    noise2D
  );

  const moisture = domainWarp2D(
    x,
    y,
    2.0,
    {
      octaves: 3,
      frequency: 0.003,
    },
    noise2D
  );

  if (temperature > 0.5 && moisture < 0) return "desert";
  if (temperature < -0.3) return "tundra";
  if (moisture > 0.4) return "rainforest";
  return "grassland";
}

Curried Functions

For convenience, you can create pre-configured noise generators:

import { createNoise2D } from "simplex-noise";
import { createFbm2D } from "./index";

// Create a reusable terrain noise generator
const terrainNoise = createFbm2D(createNoise2D(), {
  octaves: 6,
  lacunarity: 2.5,
  gain: 0.5,
  frequency: 0.01,
});

// Use it easily
const height1 = terrainNoise(100, 200);
const height2 = terrainNoise(150, 250);

Performance Tips

  1. Cache noise generators: Create once, reuse many times
  2. Limit octaves: Each octave doubles computation time
  3. Use appropriate frequency: Scale coordinates before sampling
  4. Pre-generate textures: Generate noise maps at load time when possible
  5. Use 2D when possible: Higher dimensions are slower

Performance Comparison

| Octaves | Relative Speed | Use Case | | ------- | -------------- | --------------------- | | 1 | 1x | Simple gradients | | 2 | 2x | Basic terrain | | 4 | 4x | Detailed terrain | | 6 | 6x | Very detailed terrain | | 8 | 8x | Maximum detail |

Common Patterns

Combining Multiple Noise Types

const height =
  fbm2D(x, y, { octaves: 5 }, noise2D) * 0.6 +
  ridgedMultifractal2D(x, y, { octaves: 3 }, noise2D) * 0.4;

Masking with Noise

const mask = (fbm2D(x, y, { octaves: 2 }, noise2D) + 1) * 0.5; // 0-1
const detail = fbm2D(x, y, { octaves: 6 }, noise2D);
const masked = detail * mask;

Creating Islands

const centerX = 0,
  centerY = 0;
const distance = Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2);
const gradient = Math.max(0, 1 - distance / 1000);
const height = fbm2D(x, y, { octaves: 6 }, noise2D);
const island = height * gradient;

Testing

This library includes a comprehensive test suite using Vitest.

Running Tests

# Install dependencies
npm install

# Run tests once
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with UI
npm run test:ui

# Run tests with coverage
npm run test:coverage

Test Coverage

The test suite covers:

  • All fBm functions (2D, 3D, 4D)
  • Ridged multifractal
  • Turbulence
  • Domain warping
  • Billow noise
  • Curried function creators
  • Edge cases and error handling
  • Statistical properties
  • Performance characteristics

Writing Tests

Tests are located in src/__tests__/. To add new tests:

import { describe, it, expect } from "vitest";
import { fbm2D } from "../index";
import { createNoise2D } from "simplex-noise";

describe("My Feature", () => {
  it("should work correctly", () => {
    const noise2D = createNoise2D();
    const result = fbm2D(10, 20, { octaves: 4 }, noise2D);
    expect(result).toBeTypeOf("number");
  });
});

License

MIT

See Also