feat(materials): generated facade texture maps, sampled world-aligned

New Tools/generate_facade_textures.py: deterministic, stdlib-only PNG generator for
four facade surface sets (ashlar stone, stucco, asphalt, concrete), each as base
colour (_BC) plus roughness (_R). Pure zlib encoder and hash-based value noise, so
re-running produces byte-identical files (verified by md5sum); ~14 s for eight 512²
maps.

ue_build_demo_map.py imports them into /Game/Hollywood/Textures and samples them
world-aligned: WorldPosition (cm) * 1/tile_cm -> ComponentMask(R,G) -> TextureSample
UVs, with per-material tile sizes (stone 440, stucco 260, asphalt 900, concrete
250 cm). A textured material skips the graph coursing deliberately - overlaying both
would double the course pattern.

Textures imported 8/8, hero 4/4 slots assigned, map saved; screenshots re-rendered.
This commit is contained in:
zwitschi committed 2026-11-08 19:04:03 +01:00
1 parent 0f928531df
commit 73e535a24b
39 files changed
+401 -48

No files matched your search

+1
View File
@@ -16,6 +16,7 @@ Geographic tools live in [`Geo/tools/`](../Geo/README.md) and the Blender-side b
| Tool | Purpose |
| --- | --- |
| `check-lfs.sh` | Fails if the `lfs` filter is missing or an LFS-tracked file was committed as a plain blob |
| `generate_facade_textures.py` | Deterministic stdlib PNG generator for the facade maps (`T_StoneAshlar`, `T_Stucco`, `T_Asphalt`, `T_Concrete`, each `_BC` base colour + `_R` roughness). Pure-zlib writer, hash-based value noise, identical bytes on every run; `--size` and `--out` (`/tmp/gigline/textures` by default). `ue_build_demo_map.py` imports them into `/Game/Hollywood/Textures` and samples them world-aligned. |
| `ue_common.py` | Shared helpers for the Unreal commandlet scripts: `make_writable()` clears the read-only bit an LFS `.umap` checks out with (otherwise `save_map()` returns False silently), and `require_saved()` makes that failure explicit. |
| `fbx_export_preset.py` | The **single** FBX export preset (`ue_metric_v1` / `ue_character_v1`): metres→centimetres via `FBX_SCALE_NONE`, axis mapping east +X / north −Y / up +Z, `mesh_smooth_type="FACE"` (smoothing groups survive the import). Every Blender exporter imports it instead of copying the argument block; `preset_kwargs()` is bpy-free and unit-tested. |
| `sibling_asset_audit.py` | Reads the sibling project's prop library from GLB headers into `Art/props/reuse-manifest.json`; copies nothing |