A world generated by Terrain Diffusion (90m).
Terrain Diffusion [Website] [Paper]
A practical, learned successor to Perlin noise for infinite, deterministic, and randomly-accessible real-time terrain generation.
This repo provides:
- InfiniteDiffusion, a drop-in replacement for MultiDiffusion that makes diffusion sampling lazy and unbounded, with O(1) random access and seed-consistency (determinism). Built with the infinite-tensor framework.
- A hierarchical stack of models for generating planetary terrain
- Real time streaming of terrain and climate data
Related Repositories
Infinite Tensor
Python library for managing infinite-dimensional tensors.
https://github.com/xandergos/infinite-tensor
Minecraft Mod
Fabric mod that replaces Minecraft's world generator.
https://github.com/xandergos/terrain-diffusion-mc
InfiniteDiffusion Panorama
If you want to understand or reproduce the core InfiniteDiffusion algorithm, see annotated_infinite_panorama.py. It is a self-contained, heavily annotated demo that generates an infinite-width panorama using Stable Diffusion v1.5 and infinite-tensor, with no dependency on the rest of this repository.
Install:
pip install torch diffusers transformers accelerate infinite-tensor pillow numpy
Run:
python annotated_infinite_panorama.py
This saves output.png (a 2048-pixel-wide crop of an unbounded panorama) next to the script. Edit the constants at the top of the file (PROMPT, CROP_PIXEL_WIDTH, INTERMEDIATE_TIMESTEPS, etc.) to experiment.
Installation
git clone https://github.com/xandergos/terrain-diffusion cd terrain-diffusion pip install -r requirements.txt
GPU Acceleration with CUDA (NVIDIA GPU Required)
If you have an NVIDIA GPU, it is strongly recommended to ensure that PyTorch is installed with CUDA support for GPU acceleration. Terrain Diffusion can run on a CPU as well, but it will be much slower. Mac is CPU-only.
Steps on Windows or Linux
- Install latest NVIDIA driver
- Install PyTorch with CUDA:
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121
Quick Start
All models operate in two stages.
- A coarse map defines initial layouts for the world, generated procedurally or hand-drawn. These do not need to be exact. You control how much these sketches influence the final result.
- Then the model converts these sketches into high-resolution (e.g. 30m/pixel) heightmaps that can be used for whatever your heart desires.
Models
See all models on Hugging Face.
| Model | Resolution | Use case |
|---|---|---|
| xandergos/terrain-diffusion-30m | 30 m/px, 7.7 km coarse | Best for playable worlds. Finer controls allow more local variation and detail; recommended for games or interactive experiences. |
| xandergos/terrain-diffusion-90m | 90 m/px, 23 km coarse | Best for realistic world building. More coherent and expansive. Often too expansive. Use for large-scale worldbuilding where realism is the main priority. |
Explore a Procedural World
This opens a two-panel GUI. The left panel shows the coarse map. Click any pixel on the coarse map to generate a high resolution shaded relief map on the right.
You can also view the temperature of the high resolution map with Temperature (Adjusted for elevation).
python -m terrain_diffusion explore xandergos/terrain-diffusion-30m
General API
This runs a generalized API that can be used to query for elevation and climate data. See API_README.md for details. This is primarily designed for developers who want to experiment with the tool without commiting to full integration.
python -m terrain_diffusion api xandergos/terrain-diffusion-30m
Azgaar to TIFF
Convert an Azgaar Fantasy Map Generator full JSON export (Tools -> Export -> Export To JSON -> Full) into conditioning GeoTIFFs (elevation, temperature, precipitation, etc.).
--scale sets the output pixel size in km, 100 by default. Larger values result in more manageable outputs for large worlds, but the most realistic value is the
coarse pixel size (7.7 for 30m, 23 for 90m). The output directory can be used as the conditioning folder to TIFF export (tiff-export).
python -m terrain_diffusion azgaar-to-tiff "MyMap.json" azgaar-output/ --scale 100
TIFF export
Generate a high-resolution elevation GeoTIFF from a folder of conditioning TIFFs. Y. The input is a folder containing the TIFF files below, which are first refined by the model, and then resolution is increased 256x on both axes. Use --snr to set refinement strength: 5 comma-separated values, one for each input. I found 0.2,0.2,1.0,0.2,1.0 to work well for Azgaar.
Expected files in the folder (missing files fall back to Perlin noise; at least one is required):
heightmap.tif— elevation (m)temperature.tif— mean temperature (°C)temperature_std.tif— temperature variability (°C)precipitation.tif— annual precipitation (mm)precipitation_cv.tif— precipitation variability (%)
ou may use the directory produced by Azgaar to TIFF as tiff_dir.
python -m terrain_diffusion xandergos/terrain-diffusion-90m tiff-export azgaar-output/ output.tif --snr 0.2,0.2,1.0,0.2,1.0
Training from scratch
See TRAINING.md for a step-by-step guide. This is, of course, pretty lengthy.
Modifying world generation (Advanced)
There are two ways to modify world generation without training from scratch.
Modifying the synthetic map
The code for generating the base map used for everything is at terrain_diffusion\inference\synthetic_map.py. It is basically just a bunch of perlin noise with some transformations to have the same statistics as real world data, and make sure the climate is at least kind of reasonable. You can modify the file directly to change how the world is generated.
Retraining the coarse model
The coarse model is tiny, so you can feasibly play around with the model parameters or the dataset to make new kinds of worlds. For example, you may over-sample crops that have harsher gradients. The dataset is in terrain_diffusion\training\datasets\coarse_dataset.py. You can also modify the config to create more or less powerful coarse models.
- Download ETOPO
Download the "30 Arc-Second Resolution GeoTIFF" here and place it in data/global.
- Download WorldClim data
Download bio 30s here. Extract all into data/global.
- Train with:
accelerate launch -m terrain_diffusion train --config ./configs/diffusion_coarse/diffusion_coarse.cfg
- Save the model:
python -m terrain_diffusion.training.save_model -c checkpoints/diffusion_coarse/latest_checkpoint -s 0.05
Move the output folder (Probably checkpoints/diffusion_coarse/latest_checkpoint/saved_model) to checkpoints/models/diffusion_coarse
Modifying the coarse model output
You can also do some shenanigans with the coarse model's output directly. For example, I incorporated a coarse_pooling argument to apply pooling to the outputs, essentially compressing horizontal space. I found this worked really well for making terrain more intense without breaking realism (too much). It can be made even more extreme with max pooling on the elevation map and min pooling on p5, this becomes more unrealistic though. This is an interesting direction to explore with limited compute. See WorldPipeline._build_coarse_stage.
Citation
@inproceedings{goslin2026infinitediffusion, author = {Goslin, Alexander}, title = {InfiniteDiffusion: Bridging Learned Fidelity and Procedural Utility for Open-World Terrain Generation}, booktitle = {Special Interest Group on Computer Graphics and Interactive Techniques Conference Conference Papers}, year = {2026}, pages = {10 pages}, publisher = {ACM}, address = {New York, NY, USA}, doi = {10.1145/3799902.3811080}, url = {https://doi.org/10.1145/3799902.3811080}, series = {SIGGRAPH Conference Papers '26} }