140 lines
3.4 KiB
Markdown
140 lines
3.4 KiB
Markdown
# 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:**
|
||
```python
|
||
# 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:**
|
||
```bash
|
||
blender terrain.blend --background --python scripts/generate_heightmap.py
|
||
```
|
||
|
||
**Custom parameters:**
|
||
```python
|
||
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:**
|
||
```python
|
||
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
|
||
|
||
1. **Model terrain in Blender 5.0**
|
||
- Create/sculpt terrain mesh
|
||
- Add modifiers (Subdivision, Displacement, etc.)
|
||
- Ensure terrain has UV mapping
|
||
|
||
2. **Bake heightmap**
|
||
- Run `generate_heightmap.py` script
|
||
- Uses Blender's baking system (like baking a texture)
|
||
- Creates `textures/terrain_heightmap.exr`
|
||
- Automatically applies all modifiers
|
||
|
||
3. **Export glTF with baked heights**
|
||
- Select terrain mesh
|
||
- File → Export → glTF 2.0
|
||
- Save as `meshes/terrain.gltf`
|
||
- Heights are baked in vertex positions
|
||
|
||
4. **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:
|
||
|
||
```python
|
||
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
|