Blender Export Scripts
Python scripts for generating textures and heightmaps from Blender terrain meshes.
Prerequisites
- Blender 5.0+
- Terrain mesh object (default name: "TerrainPlane")
Scripts
generate_heightmap.py
Bakes EXR heightmap from terrain mesh using Blender's render system.
Output: textures/terrain_heightmap.exr (R32Float single-channel)
Usage:
# In Blender's Scripting workspace - just run the script!
# It will automatically find TerrainPlane and bake to textures/terrain_heightmap.exr
Or run from command line:
blender terrain.blend --background --python scripts/generate_heightmap.py
Custom parameters:
from generate_heightmap import bake_heightmap
bake_heightmap(
terrain_obj=bpy.data.objects["TerrainPlane"],
resolution=1000,
output_path="path/to/output.exr"
)
generate_normal_map.py
Generates normal map from terrain mesh for neighbor sampling in shaders.
Output: textures/terrain_normals.png (RGB encoded normals)
Usage:
from generate_normal_map import save_normal_map
save_normal_map(
output_path=project_root / "textures" / "terrain_normals.png",
resolution=1024,
blur_iterations=2,
terrain_name="TerrainPlane"
)
generate_flowmap.py
Generates flowmap for water/snow flow effects.
Output: textures/terrain_flowmap.png
Terrain Export Workflow
-
Model terrain in Blender 5.0
- Create/sculpt terrain mesh
- Add modifiers (Subdivision, Displacement, etc.)
- Ensure terrain has UV mapping
-
Bake heightmap
- Run
generate_heightmap.pyscript - Uses Blender's baking system (like baking a texture)
- Creates
textures/terrain_heightmap.exr - Automatically applies all modifiers
- Run
-
Export glTF with baked heights
- Select terrain mesh
- File → Export → glTF 2.0
- Save as
meshes/terrain.gltf - Heights are baked in vertex positions
-
Both files in sync
- glTF: rendering (vertices with baked heights)
- EXR: physics (rapier3d heightfield collider)
- Both from same source = guaranteed match
Resolution Guidelines
-
Heightmap (EXR): 512×512, 1000×1000, or 1024×1024
- Higher = more accurate collision
- Lower = faster loading
- Default: 1000×1000
- Uses Blender's render sampling (no gaps!)
-
Normal Map: 1024×1024 or 2048×2048
- For shader neighbor sampling
- Higher quality for detailed terrain
Customization
Change parameters by editing the script or calling directly:
from generate_heightmap import bake_heightmap
bake_heightmap(
terrain_obj=bpy.data.objects["MyTerrain"],
resolution=1024,
output_path="custom/path.exr"
)
Output Files
project_root/
├── meshes/
│ └── terrain.gltf # Mesh with baked heights (manual export)
└── textures/
├── terrain.exr # Heightmap for physics (generated)
├── terrain_normals.png # Normal map (generated)
└── terrain_flowmap.png # Flow map (generated)
Troubleshooting
"Object not found":
- Ensure terrain object exists
- Check object name matches parameter
- Script will auto-detect objects with "terrain" or "plane" in name
"Mesh has no vertices":
- Apply all modifiers before running script
- Check mesh is not empty
EXR export fails:
- Ensure Blender has EXR support enabled
- Check output directory exists and is writable