Procedural Grass (GRAS + LTEX)¶
Fallout 4's grass is not hand-placed. It is procedurally scattered at runtime based on landscape texture coverage (splatmaps) combined with per-texture grass definitions.
Data Flow¶
LAND record (splatmap alpha layers)
-> each layer references an LTEX (Landscape Texture)
-> LTEX optionally has a GNAM subrecord pointing to a GRAS record
-> GRAS record defines mesh + placement parameters
Wherever a landscape texture with an associated GRAS record has non-zero alpha coverage in the splatmap, the engine scatters grass mesh instances using the GRAS parameters.
GRAS Record¶
Type code: GRAS
Subrecords¶
| Subrecord | Type | Description |
|---|---|---|
| EDID | zstring | Editor ID |
| OBND | 12 bytes | Object bounds |
| MODL | zstring | Mesh path (always under Meshes\Landscape\Grass\) |
DATA Subrecord (placement parameters)¶
| Offset | Type | Field | Description |
|---|---|---|---|
| 0x00 | uint8 | Density | Frequency of placement on the associated texture |
| 0x01 | uint8 | Min Slope | Minimum terrain angle (degrees, 0-90) |
| 0x02 | uint8 | Max Slope | Maximum terrain angle (degrees, 0-90) |
| 0x04 | uint16 | Units from Water | Distance threshold from water surface |
| 0x08 | uint32 | Water Relationship | See enum below |
| 0x0C | float32 | Position Range | Average area each instance occupies (units) |
| 0x10 | float32 | Height Range | Vertical scale variation (+/- percent) |
| 0x14 | float32 | Color Range | Random vertex color darkening degree |
| 0x18 | float32 | Wave Period | Wind sway animation speed (cycles per game-minute) |
| 0x1C | uint8 | Flags | See flags below |
Water Relationship Enum¶
| Value | Meaning |
|---|---|
| 0 | Above - At Least |
| 1 | Above - At Most |
| 2 | Below - At Least |
| 3 | Below - At Most |
| 4 | Either - At Least |
| 5 | Either - At Most |
| 6 | Either - At Most Above |
| 7 | Either - At Most Below |
Flags¶
| Bit | Name | Effect |
|---|---|---|
| 0 | Vertex Lighting | Use terrain normal directly below for lighting |
| 1 | Uniform Scaling | Scale all 3 axes equally; without this only Z is scaled |
| 2 | Fit To Slope | Align rotation to terrain surface angle |
LTEX -> GRAS Link¶
The LTEX (Landscape Texture) record has an optional GNAM subrecord containing the FormID of a
GRAS record. If present, any landscape cell using that texture will spawn grass.
Relevant LTEX subrecords:
| Subrecord | Type | Description |
|---|---|---|
| TNAM | formid | Texture set (TXST) reference |
| MNAM | formid | Material type (MATT) reference |
| HNAM | 2 bytes | Havok friction + restitution |
| SNAM | uint8 | Texture specular exponent |
| GNAM | formid | Grass (GRAS) reference — the critical link |
Placement Algorithm (Inferred)¶
- For each LAND cell, iterate splatmap layers (BTXT base + ATXT alpha layers)
- Resolve each layer's texture to its LTEX record, check for GNAM
- If GNAM exists, for each vertex/area with non-zero alpha coverage:
- Reject if terrain slope is outside [Min Slope, Max Slope]
- Reject if water distance violates the Water Relationship constraint
- Place instances at frequency controlled by Density x alpha opacity
- Randomize position within Position Range
- Randomize height within Height Range (+/- percent)
- Randomize vertex color darkening within Color Range
- If Fit To Slope, orient instance to terrain surface
- If Uniform Scaling, scale X/Y/Z equally; otherwise only Z
- Animate with wind sway at Wave Period speed
INI Settings¶
Global grass tuning lives in Fallout4Prefs.ini under [Grass]:
| Setting | Default | Effect |
|---|---|---|
| iMinGrassSize | 20 | Lower = denser grass (performance cost) |
| fGrassStartFadeDistance | 3500.0 | Distance where grass begins fading in |
| fGrassMaxStartFadeDistance | 4000.0 | Maximum fade distance cap |
| fGrassMinStartFadeDistance | 0.0 | Minimum fade distance floor |