Inspiration

We were inspired by voxel rendering dev logs to build a renderer… but from scratch. This led us down the rabbit hole of procedural generation, GPU programming, and heightmap ray marching.

What it does

Geoscape is a real-time procedural terrain renderer built with Three.js and GLSL. We start with a 2D grid and generate heightmaps using fractional Brownian motion (fBm) and Perlin noise. Instead of naively ray marching from the camera, we implemented several optimizations:

  • Bounding boxes per chunk: Each chunk is drawn via an instanced bounding box, and then raymarching is done starting from the surface of the box, saving expensive ray marching steps
  • DDA ray traversal: Instead of taking fixed-size steps or approximations, we use Digital Differential Analyzer (DDA) traversal to jump precisely from cell to cell in the heightmap grid. This makes ray traversal more accurate for the fixed grid heightmap that we use.

How we built it

  • We used Three.js to handle rendering setup and camera movement, while all the terrain rendering happens in custom GLSL shaders.
  • The heightmaps are stored in GPU textures, and the ray marching logic runs entirely on the fragment shader for real-time performance.

Challenges we ran into

  • One of the biggest challenges was that we had to develop different components independently — heightmap generation, converting the heightmap into a texture, and the shader-based ray marching. Each part depended on the others, which made testing and debugging difficult until everything was integrated.
  • On top of that, working with custom shaders in Three.js came with its own set of challenges. Managing uniforms, coordinate spaces, and texture sampling all required a lot of trial and error. Small math mistakes in the DDA logic often led to unexpected artifacts which made debugging especially tricky.

Accomplishments that we're proud of

  • Getting something to render after staring at cubes for 20 hours.

What we learned

  • It's hard to reinvent the wheel.

What's next for Geoscape

  • Circular buffer streaming for infinite terrain generation using fixed GPU memory.
  • Hierarchical heightmaps and associated traversal algorithms to reduce ray step counts and improve performance.
  • Memory optimisations like bit packing to reduce memory usage and increase possible render distance.
  • Interactive terrain simulation, such as erosion, water flow, and customizable noise settings.
  • Lighting and shading improvements for more realistic rendering.
Share this project:

Updates