A Java-based 3D procedural terrain generator built using LWJGL (Lightweight Java Game Library) and OpenGL, leveraging Perlin noise with fractal Brownian motion for realistic terrain generation. This project supports customizable terrain through seed and metric inputs, features an ImGUI interface for real-time parameter adjustments, and is optimized with chunk culling and texture atlasing. The terrain includes grass and sand biomes, with a WASD movement system and an interactive cursor mode for adjusting metrics.
- Procedural Terrain: Generates 3D terrain using Perlin noise with fractal Brownian motion layering for natural-looking landscapes.
- Customizable Input: Supports seed values and adjustable metrics (e.g., terrain height, scale) via an ImGUI interface.
- Biomes: Includes grass, lakes, and sand biomes, rendered with texture atlasing for smooth visuals.
- Optimization: Implements chunk-based rendering (16x16 chunks) with culling to improve performance.
- Input System:
- WASD for camera movement.
- Press
Enterto toggle a visible cursor for interacting with ImGUI metric sliders.
- Tech Stack:
- Java 21
- LWJGL for OpenGL rendering
- Built with Gradle
- Rendering: Uses texture atlasing for efficient biome texture application.
- Scale:
- Default value:
0.078(float, range: 0.01–0.2) - Description: Determines the spatial frequency of Perlin noise by scaling the input coordinates
(x * scale, z * scale). A smaller value creates larger, more spread-out terrain features (e.g., broad hills or mountains), while a larger value produces smaller, denser features (e.g., tightly packed ridges).
- Default value:
- Octaves:
- Default value:
5(integer, range: 1–10) - Description: Specifies the number of Perlin noise layers combined in Fractal Brownian Motion. Each octave adds finer details by increasing the frequency and reducing the amplitude of the noise.
- Default value:
- Persistence:
- Default value:
0.5(float, range: 1.0–4.0) - Description: Controls the amplitude reduction of each successive octave in FBM. Higher values give smaller-scale details more influence, making the terrain rougher and more jagged.
- Default value:
- Lacunarity:
- Default value:
2.6(float, range: 1.0–4.0) - Description: Determines the frequency multiplier for each octave in FBM. Higher values increase the frequency of details, adding finer features to the terrain.
- Default value:
- Height Scale:
- Default value:
8.7(float, range: 1.0–16.0) - Description: Scales the Perlin noise output to determine the terrain's vertical height. The noise value (0–1) is multiplied by
heightScaleand added tobaseHeightto compute block heights.
- Default value:
- Base Height:
- Default value:
3.1(float, range: 0.0–8.0) - Description: Sets the minimum height of the terrain by adding a constant offset to the scaled noise value. Ensures a baseline elevation for all terrain.
- Default value:
- Sand Height Threshold:
- Default value:
6(integer, range: 0–16) - Description: Defines the maximum y-coordinate (height) below which blocks are set as sand (block type 3). Blocks at or below this height, if solid, become sand instead of grass or stone.
- Default value:
- Seed:
- Default value:
67890(long) - Description: Initializes the random number generator for Perlin noise, ensuring consistent terrain generation for the same seed. Different seeds produce unique landscapes.
- Default value:
- Noise Type:
- Default value:
"Standard"(string, options: Standard, Ridged, Billowy, Hybrid) - Description: Specifies the Perlin noise variant used for terrain generation:
- Standard: Classic Perlin noise, producing smooth, natural hills and valleys.
- Ridged: Emphasizes sharp ridges and creases, ideal for mountainous terrain.
- Billowy: Creates soft, rolling hills with a cloud-like appearance.
- Hybrid: Combines Standard and Ridged for varied terrain with both smooth and sharp features.
- Default value:
-
Hills and lakes
- scale:
0.123 - octaves:
9 - persistance:
0.100 - lacunarity:
1.000 - height scale:
15.695 - base height:
5.041 - sand height treshold:
4 - seed:
-2115347812888387989 - noise type:
billowy
- scale:
-
Grass dune:
- scale:
0.088 - octaves:
3 - persistance:
0.173 - lacunarity:
1.000 - height scale:
14.720 - base height:
3.740 - sand height treshold:
4 - seed:
4459600708594632311 - noise type:
billowy
- scale:
- Java 21: Ensure you have JDK 21 installed.
- Gradle: Required for building and managing dependencies.
- LWJGL: Configured via Gradle for OpenGL rendering.
- A compatible GPU with OpenGL 4.1+ support.
- Arch Linux:
Linux 6.12.30-1-lts - JDK:
openjdk 21.0.7 2025-04-15 - Gradle:
8.14.1 - OpenGL:
4.6.0
- Download
ProcTerrain3DGen.jarfrom the Releases page. - Run the JAR:
java -jar ProcTerrain3DGen.jar
- Controls:
- WASD: Move camera
- Enter: Toggle ImGUI cursor
- Adjust terrain parameters (scale, octaves, etc.) via ImGUI sliders
- Clone the Repository:
git clone https://github.com/kosa12/proc_terrain_3D_gen cd proc_terrain_3D_gen - Build the Project:
gradle build
- Run the Application:
gradle run
- Navigation: Use WASD keys to move the camera around the 3D terrain.
- Metric Adjustments: Press Enter to toggle the cursor and interact with the ImGUI interface. Adjust sliders to modify terrain parameters like height, scale, or seed.
- Biomes: Explore grass and sand biomes, rendered with texture atlasing for smooth visuals.
- Performance: The terrain is divided into 16x16 chunks with culling to ensure efficient rendering.
src
└── main
├── java
│ └── edu
│ └── kosa
│ └── terrainproject
│ ├── app
│ │ └── Main.java
│ ├── graphics
│ │ ├── Camera.java
│ │ ├── Mesh.java
│ │ ├── Renderer.java
│ │ ├── ShaderProgram.java
│ │ ├── TextureLoader.java
│ │ └── WindowManager.java
│ ├── input
│ │ └── InputHandler.java
│ ├── noise
│ │ ├── FbmGenerator.java
│ │ ├── GradientTable.java
│ │ ├── NoiseConfig.java
│ │ ├── NoiseGenerator.java
│ │ ├── NoiseVariant.java
│ │ ├── PerlinNoiseGenerator.java
│ │ └── PermutationTable.java
│ └── terrain
│ ├── Chunk.java
│ ├── ChunkPos.java
│ ├── TerrainConfig.java
│ └── World.java
└── resources
├── logback.xml
└── textures
└── atlas.pngContributions are welcome! Please follow these steps:
- Fork the repository.
- Create a feature branch (
git checkout -b feature/your-feature). - Commit your changes (
git commit -m 'Add your feature'). - Push to the branch (
git push origin feature/your-feature). - Open a pull request.
- I'll take a look at your so-called feature.
- Thanks Grok for making this
READMEand understanding the math behind the Perlin noise. - Thanks Kebab for the initial inspiration: Kebab's Youtube video


