Files
english/.opencode/skills/shader/references/glsl-fbm-fractional-brownian-motion-turbulence-octaves.md
2026-04-12 01:06:31 +07:00

3.0 KiB

Fractional Brownian Motion (fBm)

Layer noise octaves for natural-looking textures like clouds, terrain, and wood.

Basic fBm

float fbm(vec2 st) {
    float value = 0.0;
    float amplitude = 0.5;
    float frequency = 1.0;

    // 6 octaves
    for (int i = 0; i < 6; i++) {
        value += amplitude * noise(st * frequency);
        frequency *= 2.0;    // Lacunarity
        amplitude *= 0.5;    // Gain (persistence)
    }

    return value;
}

fBm Parameters

Parameter Effect Typical Value
Octaves Detail level 4-8
Lacunarity Frequency multiplier 2.0
Gain Amplitude multiplier 0.5
float fbm(vec2 st, int octaves, float lacunarity, float gain) {
    float value = 0.0;
    float amplitude = 0.5;
    float frequency = 1.0;

    for (int i = 0; i < octaves; i++) {
        value += amplitude * noise(st * frequency);
        frequency *= lacunarity;
        amplitude *= gain;
    }

    return value;
}

Turbulence

Use absolute value for sharper valleys:

float turbulence(vec2 st) {
    float value = 0.0;
    float amplitude = 0.5;
    float frequency = 1.0;

    for (int i = 0; i < 6; i++) {
        value += amplitude * abs(noise(st * frequency) * 2.0 - 1.0);
        frequency *= 2.0;
        amplitude *= 0.5;
    }

    return value;
}

Ridged Noise

Inverted turbulence for mountain ridges:

float ridged(vec2 st) {
    float value = 0.0;
    float amplitude = 0.5;
    float frequency = 1.0;
    float prev = 1.0;

    for (int i = 0; i < 6; i++) {
        float n = abs(noise(st * frequency) * 2.0 - 1.0);
        n = 1.0 - n;           // Invert
        n = n * n;             // Sharpen
        n *= prev;             // Weight by previous
        prev = n;
        value += n * amplitude;
        frequency *= 2.0;
        amplitude *= 0.5;
    }

    return value;
}

Warped fBm (Domain Warping)

Feed fBm into itself for organic distortion:

float warpedFbm(vec2 st) {
    vec2 q = vec2(fbm(st), fbm(st + vec2(5.2, 1.3)));
    vec2 r = vec2(
        fbm(st + 4.0 * q + vec2(1.7, 9.2)),
        fbm(st + 4.0 * q + vec2(8.3, 2.8))
    );
    return fbm(st + 4.0 * r);
}

Animated fBm

float animatedFbm(vec2 st, float time) {
    float value = 0.0;
    float amplitude = 0.5;
    float frequency = 1.0;

    for (int i = 0; i < 6; i++) {
        vec2 offset = vec2(time * 0.1 * float(i + 1));
        value += amplitude * noise(st * frequency + offset);
        frequency *= 2.0;
        amplitude *= 0.5;
    }

    return value;
}

Multifractal

Multiply instead of add for different character:

float multifractal(vec2 st, float H, float lacunarity, int octaves) {
    float value = 1.0;
    float frequency = 1.0;

    for (int i = 0; i < octaves; i++) {
        value *= noise(st * frequency) * pow(frequency, -H) + 1.0;
        frequency *= lacunarity;
    }

    return value;
}

See also: glsl-procedural-textures-clouds-marble-wood-terrain.md