Skip to content

Project

perlin

Landscape generator by perlin noise map

Java70Updated Oct 2026
View on GitHub ↗

Perlin Noise Procedural Landscape Generator

A 3D procedural terrain generator using Perlin noise algorithm, now featuring a first-person immersive experience, implemented in Java (Swing/AWT) with real-time 3D visualization.

Showcase Image

Features

First-Person Experience

  • WASD Movement: Navigate freely through the terrain (forward, backward, strafe left/right)
  • Mouse Look: Control camera orientation with mouse movement for immersive exploration
  • Vertical Control: Q/E keys to ascend and descend
  • Collision Detection: Prevents clipping through terrain with smooth collision response
  • Bilinear Height Interpolation: Smooth terrain surface traversal

Terrain Generation

  • Perlin Noise Algorithm: Pure implementation of Ken Perlin's noise algorithm for natural-looking terrain
  • Octave Noise: Multiple noise frequencies combined for realistic fractal terrain details
  • Expanded Generation: 200x200 vertex grid for detailed expansive landscapes (4x original size)
  • Async Generation: Non-blocking terrain generation with visual feedback
  • Procedural Customization: Click "Regenerate Terrain" to create new landscapes with different seeds

Advanced Rendering

  • 3D Visualization: Real-time 3D rendering with perspective projection
  • Frustum Culling: Intelligent triangle culling to render only visible geometry
  • Render Distance: Configurable rendering radius around player position
  • Color-coded Elevation:
    • Deep blue: Deep water
    • Light blue: Shallow water
    • Tan: Sandy beaches
    • Green: Grasslands
    • Brown: Rocky mountains
    • White: Snow-capped peaks

Enhanced UI

  • Heads-Up Display (HUD):
    • Real-time position coordinates (X, Y, Z)
    • Performance metrics (FPS counter)
    • Current viewing direction/bearing
    • Mini-map with player position and direction indicator
    • Compass rose for cardinal direction reference
  • Modern Styling: Dark theme with blue accent colors and decorative borders
  • Responsive Controls: Visual feedback on button interactions
  • Status Indicators: Real-time updates on terrain generation status

Project Structure

1src/dev/aster/2├── app/3│   └── Main.java              - Application entry point and GUI setup4├── noise/5│   └── PerlinNoise.java       - Perlin noise algorithm implementation6├── terrain/7│   └── Terrain.java           - Terrain generation and height mapping8├── camera/9│   ├── Camera.java            - First-person camera system with WASD + mouse look10│   └── CollisionDetector.java - Terrain collision detection and camera constraints11├── render/12│   ├── Renderer3D.java        - 3D rendering engine with first-person perspective13│   └── ViewFrustum.java       - Camera frustum for rendering optimization14└── ui/15    └── HeadsUpDisplay.java    - HUD rendering with stats and mini-map

Each concern lives in its own package (app, noise, terrain, camera, render, ui) - the JEP 458 source launcher resolves them automatically from the launched file's path, so no build tooling is needed.

[!NOTE] See QUICKSTART.md for step-by-step instructions on running and customizing the project

Building & Running

No build tool is required. The project uses Java's multi-file source launch (JEP 458), so a single command compiles and runs it:

1java src/dev/aster/app/Main.java

That's it - there is no Gradle/Maven step, since the app only uses the JDK's built-in Swing/AWT.

Controls

Input Action
W Move forward
S Move backward
A Strafe left
D Strafe right
Q Ascend (move up)
E Descend (move down)
Mouse Movement Look around / rotate camera
Button Click Generate new terrain with different seed

Technical Details

Perlin Noise Algorithm

The implementation uses:

  • Permutation table with Fisher-Yates shuffle for pseudo-randomness
  • Gradient interpolation with smooth fade curves
  • Octave layering for fractal detail (default: 5 octaves)
  • Configurable persistence for detail control

First-Person Camera System

  • Full 6-DOF camera movement (forward/back, left/right, up/down)
  • Euler angle rotation (pitch and yaw) with mouse input
  • Smooth frame-rate independent movement using delta time
  • Camera height offset from terrain surface
  • Automatic boundary clamping to keep player within terrain bounds

3D Rendering

  • Perspective projection with configurable FOV (90°)
  • First-person camera perspective transformation
  • Rotation matrices for camera orientation (yaw and pitch)
  • Triangular mesh generation from height map
  • Painter's algorithm for depth sorting
  • View frustum culling to optimize rendering

Performance Optimization

  • Render Distance: Only renders terrain within ~120 units of player
  • Frustum Culling: Near/far plane checks skip off-screen geometry
  • Uniform Wireframe Mesh: Every triangle carries its border, giving the demo its signature polygon-y look (geometric LOD was deliberately rejected: merging heightfield cells cracks the mesh without edge stitching)
  • Efficient Sorting: Z-depth sorting for correct occlusion handling

Terrain Parameters

  • Grid size: 200x200 vertices (configurable)
  • Scale: 0.05 (controls feature size, 0.01-0.1 recommended)
  • Octaves: 5 (detail levels, 1-8 recommended)
  • Height multiplier: 50.0 (vertical exaggeration for dramatic terrain)
  • Render distance: 100 grid units
  • Movement speed: 1.2 units per frame
  • Mouse sensitivity: 0.15 degrees per pixel

Customization

You can modify terrain parameters in src/dev/aster/app/Main.java:

1new Terrain(2    200,       // width: Grid width (default: 200)3    200,       // height: Grid height (default: 200)4    noise,     // perlinNoise5    0.05,      // scale: Smaller = larger features6    5,         // octaves: Bigger = more detail7    50.0       // heightMultiplier: Vertical scale8);

Camera settings can be adjusted in Camera.java:

1private static final double MOVEMENT_SPEED = 1.2;   // Units per frame2private static final double VERTICAL_SPEED = 0.2;   // Units per frame (up/down)3private static final double MOUSE_SENSITIVITY = 0.1; // Degrees per pixel

Rendering parameters in Renderer3D.java:

1private static final double FOV = 70.0;2private static final int RENDER_DISTANCE = 120;   // Grid units

Performance Considerations

  • Grid Size: 200x200 is the default balanced size
    • Smaller grids (100x100) for older hardware
    • Larger grids (300x300) for powerful systems
  • Render Distance: Reduce for better performance on slower systems
  • Mouse Sensitivity: Adjust for comfortable control experience
  • FPS Counter: Shows actual rendering performance in real-time

Requirements

  • Java 22 or higher (for multi-file source-file launching; Java 25 recommended)

System Requirements

Minimum:

  • Processor: Dual-core 2.0 GHz
  • RAM: 512 MB
  • Graphics: Integrated (software rendering)

Recommended:

  • Processor: Quad-core 2.5 GHz
  • RAM: 2 GB
  • Graphics: Dedicated graphics card

License

This project is licensed under the MIT License - see the LICENSE file for details.

Want to see more? Visit my GitHub profile for all of my repositories and contributions.

View all repositories on GitHub