JNoise is a simple to use java-library for generating noise (including gradient noise) in Java.
JNoise was created in early 2020 by Articdive. It was created for a project in Minecraft for custom terrain generation. It works for all Java 17+ apps and is built using Gradle.
To add JNoise to your project using Gradle or Maven:
Repository (Maven) (Only required if using a snapshot version of JNoise):
<repository>
<id>sonatypeSnapshots</id>
<name>Sonatype Snapshots</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
Dependency (Maven):
<dependency>
<groupId>de.articdive</groupId>
<artifactId>jnoise-pipeline</artifactId>
<version>VERSION</version>
</dependency>
Repository (Gradle Kotlin DSL):
repositories {
mavenCentral()
// If using a snapshot version of JNoise: maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
}
Dependency (Gradle Kotlin DSL):
dependencies {
// JNoise Library
implementation("de.articdive:jnoise-pipeline:VERSION")
}
The JNoise library supports "Perlin", "OpenSimplex", "Value", "Worley" (Cellular) and "White" noise.
It also supports modules with which you can octavate (fractalize), e.g. Fractional Brownian Motion, and combine different noise types.
Furthermore, JNoise supports coordinate transformations (transformers), e.g. scaling and domain warping, and noise modification (modifiers), e.g. changing an interval from [-1, 1] to [0,1] . All in an easy to use pipeline syntax.
Every noise-type has different customizable features, e.g. Perlin Noise has different types of interpolation to choose from and Worley Noise's point distribution can be altered.
Normally if you are using an IDE, the code-completion is intuitive enough to use this library without having to check the source-code. There are also Javadocs available here.
Nevertheless, the Github Wiki contains more than enough information to acquire achieved results and is always looking for improvements.
Example: Creating a noise-generator using Perlin Noise with cosine interpolation.
public PerlinNoiseGenerator perlinCosine=PerlinNoiseGenerator.newBuilder().setSeed(3301).setInterpolation(Interpolation.COSINE).build();
Example using the JNoise Pipeline:
public JNoise noisePipeline=JNoise.newBuilder().perlin(3301,Interpolation.COSINE,FadeFunction.QUINTIC_POLY).build();
The Noise's dimension has to do with the amount of parameters. If you add two doubles after the evaluateNoise method, you will receive 2 dimensional noise.
All Noise Implementations support 1D, 2D, 3D and 4D noise.
Example: Getting 2D Perlin-Noise:
// 1D Noise at x = 1.0 and y = 0.5 in a 2D plane.
return perlinLinear.evaluateNoise(1.0,0.5);
Example: Getting 3D Perlin-Noise:
// 1D Noise at x = 1.0, y = 0.5 and z = 1.22 in a 3D plane.
return perlinLinear.evaluateNoise(1.0,0.5,1.22);
The main advantage of the JNoise Pipeline in contrary to just using the generators is the ability to easily apply modifiers, modules and transformers, this does come at a small performance cost for the abstraction.
Transformers change the input coordinates. The most used transformer is the ScaleTransformer
To apply the scale transformer via the Jnoise Pipeline (with a scaling factor of 0.5):
public JNoise noisePipeline=Jnoise.newBuilder().scale(0.5).[...].build();
As of version 4.1.0
JNoise supports domain warping. To apply domain
warping one requires another noise generator as the 'warping' input.
Here's an example for Worley Noise being warped by Simplex Noise:
public JNoise noise=JNoise.newBuilder()
.worley(WorleyNoiseGenerator.newBuilder())
.addDetailedTransformer(DomainWarpTransformer.newBuilder().setNoiseSource(SuperSimplexNoiseGenerator.newBuilder().build()).build())
.build();
The domain warping transformer has a vareity of options to control pinching, streching, twisting, bending and basically any deformation on noise.
Modules are basically noise generators that use other noise generators as an input. Currently, the 2 most used noise modules are:
- OctavationModule (Octavate (Fractalize) a noise generator)
- CombinationModule (Combine 2 noise generators)
Please note that modules are also noise generators, so a CombinationModule can have a different CombinationModule as an input.
In this case, the way to get octavated noise values is the exact same. However, we must add a NoiseModule ( the OctavationModule) to our JNoise instance.
Example: Creating a noise-generator using octavated Perlin Noise with cosine interpolation.
public PerlinNoiseGenerator perlinCosine=PerlinNoiseGenerator.newBuilder().setSeed(3301).setInterpolation(Interpolation.COSINE).build();
// In most cases, one would inline the perlinCosine value into the builder chain.
public OctavationModule octavtedPerlin=OctavationModule.newBuilder().setNoiseSource(perlinCosine).setOctaves(4).setPersistence(1.0).setLacunarity(1.0).build()
Example using the JNoise Pipeline (Variant 1):
public PerlinNoiseGenerator perlinCosine=PerlinNoiseGenerator.newBuilder().setSeed(3301).setInterpolation(Interpolation.COSINE).build();
// In most cases, one would inline the perlinCosine value into the builder chain.
public JNoise noisePipeline=JNoise.newBuilder().octavation(perlinCosine,4,1.0,1.0,FractalFunction.FBM,false).build();
Example using the JNoise Pipeline (Variant 2):
public JNoise noisePipeline=JNoise.newBuilder().perlin(3301,Interpolation.COSINE,FadeFunction.QUINTIC_POLY).octavate(4,1.0,1.0,FractalFunction.FBM,false).build();
Modifiers change the output value. They are mostly included to reduce the amount of modification a developer using JNoise has to do. There are various different modifiers, e.g.:
- AbsoluteValueModifier (absolute value of the noise output.)
- ClampModifier (clamps the noise output between two values.)
- InvertModifier (inverts the noise output.)
Most modifiers can be applied directly in the JNoise pipeline and their order is respected, e.g.:
public JNoise noisePipeline=Jnoise.newBuilder().[...].abs().clamp(0.5,0.75).invert().build();
Most noise types have a customizable seed.
- Interpolation function
- Fade function
- Distance function
- Feature point amount
- Combination of shortest distances.
- Fast & SuperSimplex algorithms
- Simplex variants
- Mean
- Standard Deviation
- The underlying noise type to be octavated
- Amount of octaves
- Lacunarity
- Gain (Persistence)
- Fractal functions (FBM, Turbelent & Ridged)
- Seed incrementation per octave (Increases the seed by 1 each octave)
- Addition
- Min/Max
- Multiplication
- Power
Since Worley Noise has a return type in form of a Tuple (The nearest point and numeric value) it must be accessed differentely. By using the method evaluateNoiseResult(...) defined in JNoiseDetailed you can access a small object containing more than just the numeric value.
public JNoiseDetailed<WorleyNoiseResult> worleyNoise=JNoise.newBuilder().worley(WorleyNoiseGenerator.newBuilder().[...].build()).buildDetailed();
{
worleyNoise.evaluateNoiseResult(x,y).getClosestPoint();
worleyNoise.evaluateNoiseResult(x,y).getValue()
}
@Ken Perlin's work on Perlin Noise.
@Kurt Spencer's work on OpenSimplex2 located here.
@Steven Worley's work on Worley Noise.
@Inigo Quilez's work on Smooth Voronoi (Worley) Noise and domain warping.