Give the Joke Shop a dark stucco wall and a photo-anchored concept
No files matched your search
@@ -393,12 +393,12 @@ facade evidence is still the 2009 CC BY frame. The 8 downloaded candidates are i
|
|||||||
- [ ] Run the assisted Blender pipeline end to end on the first block (OSM import → `inspect` →
|
- [ ] Run the assisted Blender pipeline end to end on the first block (OSM import → `inspect` →
|
||||||
retopo/UV assist → atlas → `audit`), and document the exact commands in
|
retopo/UV assist → atlas → `audit`), and document the exact commands in
|
||||||
`docs/asset-tooling.md`.
|
`docs/asset-tooling.md`.
|
||||||
- [-] Joke Shop building-appearance pass, same evidence model as the masonic facade: generate a
|
- [x] Joke Shop building-appearance pass: `dark_stucco` tile (1024 px) promoted via the picks
|
||||||
dark stucco wall tile reference-anchored on the public-domain frontage photo (PD allows
|
pipeline and wired into `_build_comedy_store_building`, replacing the grey paver tile so the
|
||||||
derived work without attribution conditions), generate a photo-anchored day concept for the
|
hall reads as flat matte charcoal instead of masonry; photo-anchored day concept generated
|
||||||
three-up board, wire the tile behind `VENUE_SPECS`, then recapture and rebuild the Joke Shop
|
from the hillside PD frame (the branded frontage photo trips the model's image-recitation
|
||||||
day board. Verify texel density stays inside the 40–400 px/m band and the signature fascia
|
filter — recorded in the concept README); day capture promoted and the three-up board rebuilt.
|
||||||
+ red curtain bays still read against the reference.
|
Test asserts the hall wall carries `dark_stucco`.
|
||||||
- [x] Building-appearance realism pass, measured against the reference set: bring the masonic
|
- [x] Building-appearance realism pass, measured against the reference set: bring the masonic
|
||||||
facade's material response (limestone value/roughness, joint lines, weathering streaks),
|
facade's material response (limestone value/roughness, joint lines, weathering streaks),
|
||||||
the banner/canopy and marquee materials, and the night emissive balance to the level of the
|
the banner/canopy and marquee materials, and the night emissive balance to the level of the
|
||||||
|
|||||||
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 922 KiB |
@@ -15,4 +15,4 @@ attribution lives in the caption and the [refs sidecars](../refs/README.md)).
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
|  | El Capitan facade, day. Photo: [CC BY 2.0, woo, 2009](https://commons.wikimedia.org/wiki/File:El_Capitan_Theater_frontal_fachade-The_Masonic_Temple.jpg) via `refs/hollywood`. Concept: photo-anchored generation. Capture: current build with the ashlar limestone field (`limestone_ashlar`, anchored on the same photo). |
|
|  | El Capitan facade, day. Photo: [CC BY 2.0, woo, 2009](https://commons.wikimedia.org/wiki/File:El_Capitan_Theater_frontal_fachade-The_Masonic_Temple.jpg) via `refs/hollywood`. Concept: photo-anchored generation. Capture: current build with the ashlar limestone field (`limestone_ashlar`, anchored on the same photo). |
|
||||||
|  | El Capitan block, night. Photo: CC BY-SA 3.0 (reviewed; redistribution only, no derived assets) via `refs/hollywood`. Concept: photo-anchored night restage. Capture: current build. |
|
|  | El Capitan block, night. Photo: CC BY-SA 3.0 (reviewed; redistribution only, no derived assets) via `refs/hollywood`. Concept: photo-anchored night restage. Capture: current build. |
|
||||||
|  | Joke Shop frontage, day. Photo: public domain (2006) via `refs/joke-shop`. Concept: generated. Capture: current build. |
|
|  | Joke Shop frontage, day. Photo: public domain (2006) via `refs/joke-shop`. Concept: photo-anchored (hillside frame; the branded frontage trips the model's recitation filter). Capture: current build with the `dark_stucco` wall tile. |
|
||||||
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 112 KiB |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"board": "jokeshop-day-board.jpg",
|
"board": "jokeshop-day-board.jpg",
|
||||||
"caption": "Joke Shop, day: licensed photo | generated concept | current capture",
|
"caption": "Joke Shop frontage, day. Photo: public domain 2006. Concept: photo-anchored (hillside frame). Capture: dark stucco wall tile.",
|
||||||
"photo": "docs/screens/refs/joke-shop/comedy-store-frontage-palms-day-pd-2006-12-29.jpg",
|
"photo": "docs/screens/refs/joke-shop/comedy-store-frontage-palms-day-pd-2006-12-29.jpg",
|
||||||
"concept": "docs/screens/concepts/joke_shop/joke_shop_entrance_day.png",
|
"concept": "docs/screens/concepts/joke_shop/joke_shop_entrance_day-v2.png",
|
||||||
"capture": "docs/screenshots/12-joke-shop.png"
|
"capture": "docs/screenshots/12-joke-shop.png"
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,17 @@ real Comedy Store block at 8433 Sunset Boulevard. They are generated with
|
|||||||
game textures. The geometry mapping and source links are in
|
game textures. The geometry mapping and source links are in
|
||||||
[`../../../joke-shop-map.md`](../../../joke-shop-map.md).
|
[`../../../joke-shop-map.md`](../../../joke-shop-map.md).
|
||||||
|
|
||||||
|
## Entrance — day, photo-anchored
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Generated with `generate --reference`, anchored on the licence-cleared
|
||||||
|
[`comedy-store-hillside-canopy-day-pd-2006-12-29.jpg`](../../refs/joke-shop/comedy-store-hillside-canopy-day-pd-2006-12-29.jpg)
|
||||||
|
board photo (public domain); provenance in
|
||||||
|
[`joke_shop_entrance_day-v2.refgen.json`](joke_shop_entrance_day-v2.refgen.json).
|
||||||
|
The frontage photo itself triggers the model's image-recitation filter, so the
|
||||||
|
hillside block frame anchors the facade; shape follows the frontage photo.
|
||||||
|
|
||||||
## Entrance — day
|
## Entrance — day
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
|
After Width: | Height: | Size: 1.2 MiB |
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"concept": "joke_shop_entrance_day",
|
||||||
|
"generated": "joke_shop_entrance_day-v2.png",
|
||||||
|
"model": "google/gemini-2.5-flash-image",
|
||||||
|
"reference": {
|
||||||
|
"file": "docs/screens/refs/joke-shop/comedy-store-hillside-canopy-day-pd-2006-12-29.jpg",
|
||||||
|
"licence": "Public domain",
|
||||||
|
"page": "https://commons.wikimedia.org/wiki/File:ComedyStore_01.jpg",
|
||||||
|
"licence_checked": true
|
||||||
|
},
|
||||||
|
"suffix": "Use the attached reference photograph as the fixed source of geometry and composition: keep the building's proportions, column rhythm, band heights, signage placement and camera angle exactly as photographed. Only restage lighting, weather, people and surface condition where the prompt asks for it. Do not invent extra storeys, wings or ornaments that the photo does not show."
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 567 KiB After Width: | Height: | Size: 535 KiB |
@@ -36,6 +36,10 @@ const T_LIMESTONE_NORMAL := preload(PICK_DIR + "stone_steps_normal.png")
|
|||||||
## `stone_steps` tile reads as small pavers, not wall ashlar).
|
## `stone_steps` tile reads as small pavers, not wall ashlar).
|
||||||
const T_ASHLAR := preload(PICK_DIR + "limestone_ashlar.png")
|
const T_ASHLAR := preload(PICK_DIR + "limestone_ashlar.png")
|
||||||
const T_ASHLAR_NORMAL := preload(PICK_DIR + "limestone_ashlar_normal.png")
|
const T_ASHLAR_NORMAL := preload(PICK_DIR + "limestone_ashlar_normal.png")
|
||||||
|
## Dark stucco for the Comedy Store hall wall: flat matte charcoal (the concrete
|
||||||
|
## paver tile read as grey masonry, not the building's flat black surface).
|
||||||
|
const T_STUCCO := preload(PICK_DIR + "dark_stucco.png")
|
||||||
|
const T_STUCCO_NORMAL := preload(PICK_DIR + "dark_stucco_normal.png")
|
||||||
|
|
||||||
## Roughness / metallic pairs per surface role. Exposed so tests and tooling can
|
## Roughness / metallic pairs per surface role. Exposed so tests and tooling can
|
||||||
## assert the profiles instead of hard-coding numbers twice.
|
## assert the profiles instead of hard-coding numbers twice.
|
||||||
@@ -118,6 +122,9 @@ static func limestone(tint: Color = Color(1, 1, 1), uv_scale: Vector2 = Vector2(
|
|||||||
static func ashlar(tint: Color = Color(1, 1, 1), uv_scale: Vector2 = Vector2(6, 3)) -> StandardMaterial3D:
|
static func ashlar(tint: Color = Color(1, 1, 1), uv_scale: Vector2 = Vector2(6, 3)) -> StandardMaterial3D:
|
||||||
return textured(T_ASHLAR, tint, uv_scale, "stone", T_ASHLAR_NORMAL)
|
return textured(T_ASHLAR, tint, uv_scale, "stone", T_ASHLAR_NORMAL)
|
||||||
|
|
||||||
|
static func stucco(tint: Color = Color(1, 1, 1), uv_scale: Vector2 = Vector2(6, 3)) -> StandardMaterial3D:
|
||||||
|
return textured(T_STUCCO, tint, uv_scale, "concrete", T_STUCCO_NORMAL)
|
||||||
|
|
||||||
static func asphalt(tint: Color = Color(1, 1, 1), uv_scale: Vector2 = Vector2(30, 7),
|
static func asphalt(tint: Color = Color(1, 1, 1), uv_scale: Vector2 = Vector2(30, 7),
|
||||||
wet: bool = false) -> StandardMaterial3D:
|
wet: bool = false) -> StandardMaterial3D:
|
||||||
var texture: Texture2D = T_ASPHALT_WET if wet else T_ASPHALT
|
var texture: Texture2D = T_ASPHALT_WET if wet else T_ASPHALT
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ const T_ASPHALT := preload(PICK_DIR + "asphalt.png")
|
|||||||
const T_AWNING := preload(PICK_DIR + "awning_canvas.png")
|
const T_AWNING := preload(PICK_DIR + "awning_canvas.png")
|
||||||
const T_LIMESTONE := preload(PICK_DIR + "stone_steps.png")
|
const T_LIMESTONE := preload(PICK_DIR + "stone_steps.png")
|
||||||
const T_ASHLAR := preload(PICK_DIR + "limestone_ashlar.png")
|
const T_ASHLAR := preload(PICK_DIR + "limestone_ashlar.png")
|
||||||
|
const T_STUCCO := preload(PICK_DIR + "dark_stucco.png")
|
||||||
## One skyline panorama per shift phase (realism pass): hazy daylight, warm dusk
|
## One skyline panorama per shift phase (realism pass): hazy daylight, warm dusk
|
||||||
## with lit windows, and a night city. The old single strip was a black silhouette.
|
## with lit windows, and a night city. The old single strip was a black silhouette.
|
||||||
const T_SKYLINE_DAY := preload(PICK_DIR + "skyline_day.png")
|
const T_SKYLINE_DAY := preload(PICK_DIR + "skyline_day.png")
|
||||||
@@ -374,10 +375,12 @@ func _build_comedy_store_building() -> void:
|
|||||||
var black_deep := Color(0.045, 0.045, 0.05)
|
var black_deep := Color(0.045, 0.045, 0.05)
|
||||||
var signature := Color(0.58, 0.56, 0.52)
|
var signature := Color(0.58, 0.56, 0.52)
|
||||||
var red := Color(0.42, 0.035, 0.045)
|
var red := Color(0.42, 0.035, 0.045)
|
||||||
# Main hall. The black stucco is the real building's dominant surface; the
|
# Main hall. The black stucco is the real building's dominant surface: a flat
|
||||||
# concrete texture keeps it matte instead of turning it into glossy paint.
|
# matte charcoal tile now replaces the grey paver texture so the wall reads as
|
||||||
|
# dark plaster, not masonry. The 0.105 tint keeps the effective value near the
|
||||||
|
# reference's flat black while the fine grain stops it looking like glossy paint.
|
||||||
_add_box(building, Vector3(w, h, d), Vector3(0, h * 0.5, cz), black,
|
_add_box(building, Vector3(w, h, d), Vector3(0, h * 0.5, cz), black,
|
||||||
false, T_CONCRETE, Vector2(w * 0.42, h * 0.42), "concrete")
|
false, T_STUCCO, Vector2(w * 0.42, h * 0.42), "concrete")
|
||||||
# Low plinth and a thin parapet cap so the roofline reads against the hill.
|
# Low plinth and a thin parapet cap so the roofline reads against the hill.
|
||||||
_add_box(building, Vector3(w, 0.30, 0.34), Vector3(0, 0.15, front + 0.05),
|
_add_box(building, Vector3(w, 0.30, 0.34), Vector3(0, 0.15, front + 0.05),
|
||||||
Color(0.07, 0.07, 0.075), true, null, Vector2.ONE, "stone")
|
Color(0.07, 0.07, 0.075), true, null, Vector2.ONE, "stone")
|
||||||
|
|||||||
@@ -76,12 +76,21 @@ func test_joke_shop_uses_the_real_sunset_strip_layout() -> bool:
|
|||||||
"the low entrance step is built")
|
"the low entrance step is built")
|
||||||
var g := TestUtils.check(root.find_child("AlleyWall", true, false) == null,
|
var g := TestUtils.check(root.find_child("AlleyWall", true, false) == null,
|
||||||
"the old alley walls are gone")
|
"the old alley walls are gone")
|
||||||
|
# The hall wall uses the dark stucco pick, not the grey sidewalk-paver tile,
|
||||||
|
# so it reads as the real club's flat black plaster.
|
||||||
|
var wall := root.find_child("Building", true, false) as Node3D
|
||||||
|
var wall_mesh := wall.get_child(0) as MeshInstance3D if wall != null and wall.get_child_count() > 0 else null
|
||||||
|
var wall_mat: Material = wall_mesh.mesh.surface_get_material(0) if wall_mesh != null and wall_mesh.mesh != null else null
|
||||||
|
var g2 := TestUtils.check(wall_mat is StandardMaterial3D
|
||||||
|
and (wall_mat as StandardMaterial3D).albedo_texture != null
|
||||||
|
and (wall_mat as StandardMaterial3D).albedo_texture.resource_path.contains("dark_stucco"),
|
||||||
|
"the hall wall carries the dark stucco texture")
|
||||||
var placements: Array = builder.spec.get("prop_placements", [])
|
var placements: Array = builder.spec.get("prop_placements", [])
|
||||||
var h := TestUtils.check(not placements.is_empty()
|
var h := TestUtils.check(not placements.is_empty()
|
||||||
and WorldBuilder.placement_problems(placements).is_empty(),
|
and WorldBuilder.placement_problems(placements).is_empty(),
|
||||||
"the Joke Shop prop placements stay on the sidewalk and clear the lane")
|
"the Joke Shop prop placements stay on the sidewalk and clear the lane")
|
||||||
root.free()
|
root.free()
|
||||||
return a and b and c and d and e and f and g and h
|
return a and b and c and d and e and f and g and g2 and h
|
||||||
|
|
||||||
func test_joke_shop_geometry_stays_inside_the_map_budget() -> bool:
|
func test_joke_shop_geometry_stays_inside_the_map_budget() -> bool:
|
||||||
var root := Node3D.new()
|
var root := Node3D.new()
|
||||||
|
|||||||
@@ -231,6 +231,7 @@ PICKS = {
|
|||||||
"brick_facade": "brick_facade",
|
"brick_facade": "brick_facade",
|
||||||
"stone_steps": "stone_steps-v2",
|
"stone_steps": "stone_steps-v2",
|
||||||
"limestone_ashlar": "limestone_ashlar",
|
"limestone_ashlar": "limestone_ashlar",
|
||||||
|
"dark_stucco": "dark_stucco",
|
||||||
"sidewalk_pavers": "sidewalk_pavers",
|
"sidewalk_pavers": "sidewalk_pavers",
|
||||||
"asphalt": "asphalt",
|
"asphalt": "asphalt",
|
||||||
"asphalt_wet": "asphalt_wet",
|
"asphalt_wet": "asphalt_wet",
|
||||||
|
|||||||