feat(hero): sandstone, banners and recessed portals - the material was the missing link

Iterated the loop five times against Art/reference/hero-masonic/. What took the iterations was the material,
not the geometry:

- M_FacadeStone in /Game/Hollywood/Site is the KIT stone; the hero does not use it, so warming it changed
  nothing.
- The hero's materials come from the FBX and live at /Game/Hollywood/ElCapitan/M_Facade_*. Unreal keeps an
  existing material asset when an FBX referencing it is re-imported, so a Blender colour change never
  arrived.
- Deleting those materials before the import broke the mesh's slots: one colour, no banners, no windows.

The working step is tint_imported_materials(): import normally, then author one plain Constant3Vector
material per facade slot with the colour sampled from the reference, and assign it to the matching slot. The
elevation is now warm sandstone with ashlar coursing, three red banners, two window bands and three recessed
portals with steps.

Also: the portal's solid stone reveal z-fought with the door leaf and read as stripes, so the recess is
carried by jambs, lintel and shadow; banners are 1.35 x 6.2 m hung from 7.2 m instead of 1.55 x 5.4.

Loop iteration 5 verdict is still 'no': it wants the carved inscription, medallion relief, a crimson banner
tone and visible window grilles - all recorded as the next iteration. Rows 4-6 are pending review with the
new captures and two comparison plates.
This commit is contained in:
zwitschi committed 2026-11-10 09:05:48 +01:00
1 parent 19ed4fefd4
commit bf7dfe1052
120 files changed
+276 -158

No files matched your search

+27 -4
View File
@@ -131,8 +131,8 @@ def build():
# Warm limestone, sampled from 02-masonictemple01.jpg: the reference is a yellow-grey sandstone,
# nowhere near the near-white the blockout used.
stone = make_material("M_Facade_Stone", (0.66, 0.60, 0.48, 1.0), 0.82)
stone_dark = make_material("M_Facade_StoneShadow", (0.52, 0.47, 0.38, 1.0), 0.85)
stone = make_material("M_Facade_Stone", (0.34, 0.29, 0.21, 1.0), 0.82)
stone_dark = make_material("M_Facade_StoneShadow", (0.22, 0.185, 0.135, 1.0), 0.85)
glass = make_material("M_Facade_GlassDark", (0.05, 0.06, 0.07, 1.0), 0.25)
banner = make_material("M_Facade_Banner", (0.66, 0.06, 0.05, 1.0), 0.9)
@@ -306,8 +306,11 @@ def build():
# Recessed doorway: a dark reveal set back inside the plinth, 1.2 m deep so
# it reads as an opening from any angle.
depth = 1.2
cube(f"Hero_Portal_{i}", x, plinth_front + depth / 2.0 + 0.05, PORTAL_H / 2.0,
PORTAL_W, depth, PORTAL_H, glass)
# Door leaf set back inside the opening. A solid stone reveal box at the same volume z-fought
# with the leaf and read as stripes, so the recess is carried by the jambs, the lintel and the
# shadow instead.
cube(f"Hero_PortalLeaf_{i}", x, plinth_front + depth - 0.10, PORTAL_H / 2.0,
PORTAL_W - 0.10, 0.08, PORTAL_H - 0.10, glass)
# Stone surround, standing 0.1 m proud of the plinth face.
for side, sx in (("L", -1.0), ("R", 1.0)):
# Jambs stop at the pavement: a 0.15 m overhang below Z 0 would sink the
@@ -362,6 +365,26 @@ def build():
cube(f"Hero_Window_{rank}_{i}", wx, WINDOW_Y, z, 2.0, 0.08, 1.9, glass)
note("Hero_Window_x10", (2.0, 0.08, 1.9), "photographs: window bands behind the colonnade")
# --- window grilles ------------------------------------------------------
# The reference bays are closed with a dark metal trellis, not plain glass. Seven vertical and five
# horizontal bars per opening, 4 cm square, read as a grille at street distance and cost 60 cubes.
grille = make_material("M_Facade_Grille", (0.10, 0.10, 0.11, 1.0), 0.5)
barred = 0
for obj in list(bpy.data.objects):
if not obj.name.startswith("Hero_Window_"):
continue
wx, wy, wz, wdx, wdy, wdz = (obj.location.x, obj.location.y, obj.location.z,
obj.dimensions.x, obj.dimensions.y, obj.dimensions.z)
for v in range(7):
x = wx - wdx / 2.0 + (v + 0.5) * wdx / 7.0
cube(f"Hero_GrilleV_{barred:02d}", x, wy - 0.02, wz, 0.04, 0.03, wdz * 0.96, grille)
barred += 1
for hcount in range(5):
z = wz - wdz / 2.0 + (hcount + 0.5) * wdz / 5.0
cube(f"Hero_GrilleH_{barred:02d}", wx, wy - 0.02, z, wdx * 0.96, 0.03, 0.04, grille)
barred += 1
print(f"[hero] window grilles: {barred} bars")
# --- rustication and roof cresting --------------------------------------
# The photographs show the ground storey in banded ashlar and a cresting with balusters along
# the roof edge; without them the elevation reads as a flat card.