Refine environment surfaces and skyline haze
This commit is contained in:
1 parent
d7220c1a0a
commit
fb3da52438
8 files changed
+91
-22
No files matched your search
@@ -13,6 +13,9 @@ Semantic Versioning.
|
|||||||
- NPC fabric maps now repeat four times across the body and skip the baked
|
- NPC fabric maps now repeat four times across the body and skip the baked
|
||||||
per-character AO, removing the large blotchy patches from shirts, jackets and
|
per-character AO, removing the large blotchy patches from shirts, jackets and
|
||||||
trousers at portrait distance.
|
trousers at portrait distance.
|
||||||
|
- The Walk of Fame band now uses the paver/terrazzo texture instead of a flat
|
||||||
|
dark strip, the neighbour awning keeps its cream stripe at close range, and the
|
||||||
|
distant skyline fades into horizon haze instead of reading as a crisp cut-out.
|
||||||
|
|
||||||
## [0.9.4] — 2026-11-02
|
## [0.9.4] — 2026-11-02
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,13 @@ Session memory for durable decisions, state, and gotchas. Keep concise, remove o
|
|||||||
albedo/normal/ORM maps instead of 128² (AI shirt/trousers are resized to 256). The base and all
|
albedo/normal/ORM maps instead of 128² (AI shirt/trousers are resized to 256). The base and all
|
||||||
eight library GLBs plus AO maps were rebuilt; texture files total ~0.5 MB, eight GLBs ~5.75 MB,
|
eight library GLBs plus AO maps were rebuilt; texture files total ~0.5 MB, eight GLBs ~5.75 MB,
|
||||||
and the 24-NPC smoke remains 6.90 ms.
|
and the 24-NPC smoke remains 6.90 ms.
|
||||||
|
- **Environment surface audit (0.9.5, 2026-11-02):** `capture_realism.gd` gained
|
||||||
|
`surfaces` (Hollywood pavers/asphalt/limestone/facade) and `surfaces_joke`
|
||||||
|
(neighbour awning, canopy, pavers) stages with the HUD hidden. The Walk of Fame
|
||||||
|
band now uses `T_CONCRETE` as dark terrazzo; the neighbour awning uses a neutral
|
||||||
|
tint (`0.62`) and 4× UV so the red/cream stripes survive; the skyline shader
|
||||||
|
fades its lower 42 m toward a per-phase haze colour. Brick/asphalt picks needed
|
||||||
|
no replacement. No seams or broken UV scales found.
|
||||||
- **NPC fabric UV/AO (0.9.5, 2026-11-02):** cloth/pants use
|
- **NPC fabric UV/AO (0.9.5, 2026-11-02):** cloth/pants use
|
||||||
`Materials.NPC_FABRIC_UV_SCALE = Vector3(4,4,1)`, and `NpcAvatar` skips the baked per-character
|
`Materials.NPC_FABRIC_UV_SCALE = Vector3(4,4,1)`, and `NpcAvatar` skips the baked per-character
|
||||||
AO on those two slots. The 256² AO was magnifying into large blotches; the fabric now reads as a
|
AO on those two slots. The 256² AO was magnifying into large blotches; the fabric now reads as a
|
||||||
|
|||||||
@@ -57,16 +57,22 @@ Compatibility/Web parity, deterministic assets and offline CI.
|
|||||||
|
|
||||||
### Environment textures and materials
|
### Environment textures and materials
|
||||||
|
|
||||||
- [ ] Audit the v2 picks (brick, sidewalk pavers, dry/wet asphalt, awning canvas,
|
- [x] Audit the v2 picks (brick, sidewalk pavers, dry/wet asphalt, awning canvas,
|
||||||
day/dusk/night skylines) at close range and in the entrance/street shots for
|
day/dusk/night skylines) at close range and in the entrance/street shots for
|
||||||
seams, tiling, scale, contrast and normal-map strength.
|
seams, tiling, scale, contrast and normal-map strength. (New `surfaces` and
|
||||||
- [ ] Refine brick mortar/wear, paver joints/stains, asphalt aggregate/wet response
|
`surfaces_joke` capture stages; no seam or UV-scale failures found.)
|
||||||
|
- [x] Refine brick mortar/wear, paver joints/stains, asphalt aggregate/wet response
|
||||||
and awning weave using the existing image/asset tooling; never overwrite a
|
and awning weave using the existing image/asset tooling; never overwrite a
|
||||||
pick, use `-vN` candidates and promote validated results.
|
pick, use `-vN` candidates and promote validated results. (The Walk of Fame
|
||||||
- [ ] Check UV scales and material roughness/metallic profiles; keep day/night
|
band now uses the paver/terrazzo texture; the neighbour awning keeps its
|
||||||
phase behavior and the wet-street transition intact.
|
cream stripe via a neutral tint and 4× UV. Brick/asphalt picks held up.)
|
||||||
- [ ] Review distant skyline haze and foliage/planter surfaces against the concept
|
- [x] Check UV scales and material roughness/metallic profiles; keep day/night
|
||||||
references; fix obvious flatness without regressing readability.
|
phase behavior and the wet-street transition intact. (Profiles and UV
|
||||||
|
scales passed; dry/wet asphalt and phase switching unchanged.)
|
||||||
|
- [x] Review distant skyline haze and foliage/planter surfaces against the concept
|
||||||
|
references; fix obvious flatness without regressing readability. (Added
|
||||||
|
world-height haze fade to the skyline shader; foliage/planters stayed
|
||||||
|
stylized and readable, so no mesh change.)
|
||||||
|
|
||||||
### Character and prop textures
|
### Character and prop textures
|
||||||
|
|
||||||
@@ -74,7 +80,8 @@ Compatibility/Web parity, deterministic assets and offline CI.
|
|||||||
refine fabric weave, skin variation and fixed detail materials. (256² maps rebuilt; fabric
|
refine fabric weave, skin variation and fixed detail materials. (256² maps rebuilt; fabric
|
||||||
now uses a 4× UV weave and skips baked per-character AO, removing the portrait blotches;
|
now uses a 4× UV weave and skips baked per-character AO, removing the portrait blotches;
|
||||||
skin/hair/gear keep AO. Comparison `sheet_npc_baseline_compare-texuv.jpg`.)
|
skin/hair/gear keep AO. Comparison `sheet_npc_baseline_compare-texuv.jpg`.)
|
||||||
- [ ] Re-bake AO where geometry changes; verify the 256² maps and material wiring.
|
- [x] Re-bake AO where geometry changes; verify the 256² maps and material wiring.
|
||||||
|
(No character geometry changed in the texture pass; asset/base audits pass.)
|
||||||
- [ ] Audit library props and UI/card/icon textures at their actual screen sizes;
|
- [ ] Audit library props and UI/card/icon textures at their actual screen sizes;
|
||||||
remove blurry/oversized or unused textures where safe.
|
remove blurry/oversized or unused textures where safe.
|
||||||
- [ ] Run texture audits, import, and the full asset test suite; record texture memory
|
- [ ] Run texture audits, import, and the full asset test suite; record texture memory
|
||||||
|
|||||||
+10
-2
@@ -235,11 +235,19 @@ godot --path . --script res://src/test/capture_npc_baseline.gd -- \
|
|||||||
python3 tools/npc_baseline.py sheet --dir tmp/npc-baseline
|
python3 tools/npc_baseline.py sheet --dir tmp/npc-baseline
|
||||||
```
|
```
|
||||||
|
|
||||||
`capture_realism.gd` runs seven stages (day, portrait, evening, late, Joke Shop day, Joke Shop night, studio);
|
`capture_realism.gd` runs nine stages (day, Hollywood surface close-ups, Joke Shop surface close-ups, portrait, evening, late, Joke Shop day, Joke Shop night, studio);
|
||||||
`--stages=day,late` limits it while tuning; `--flashlight` turns on the guard lamp for
|
`--stages=day,late` limits it while tuning; `--flashlight` turns on the guard lamp for
|
||||||
night stages (used by the Desktop HQ A/B). The `portrait` shot freezes one NPC on open sidewalk
|
night stages (used by the Desktop HQ A/B). The `portrait` shot freezes one NPC on open sidewalk
|
||||||
and frames the face, which is the only capture that can judge avatar detail
|
and frames the face, which is the only capture that can judge avatar detail
|
||||||
(`--portrait-type=N` picks a role). The generated realism runs under
|
(`--portrait-type=N` picks a role). For the 0.9.5 texture audit, run the surface
|
||||||
|
stages directly; the HUD is hidden for them:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
godot --path . --script res://src/test/capture_realism.gd \
|
||||||
|
-- --out=res://tmp/surfaces --stages=surfaces,surfaces_joke
|
||||||
|
```
|
||||||
|
|
||||||
|
The generated realism runs under
|
||||||
`docs/screens/realism/` are **local, gitignored QA artifacts**; commit only the
|
`docs/screens/realism/` are **local, gitignored QA artifacts**; commit only the
|
||||||
resulting decisions/docs, not the run folders. The texture-adoption run compared
|
resulting decisions/docs, not the run folders. The texture-adoption run compared
|
||||||
the pre-adoption captures with the current build: on the shots both sets captured,
|
the pre-adoption captures with the current build: on the shots both sets captured,
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ Implemented so far:
|
|||||||
- NPC face-depth pass (0.9.4 work): sclera are recessed and capped by a thin upper lid, and the separate jaw/cheek spheres are replaced by a chin plate and cheekbones sculpted into the head mesh. The full library was rebuilt; the comparison is `sheet_npc_baseline_compare-face.jpg`.
|
- NPC face-depth pass (0.9.4 work): sclera are recessed and capped by a thin upper lid, and the separate jaw/cheek spheres are replaced by a chin plate and cheekbones sculpted into the head mesh. The full library was rebuilt; the comparison is `sheet_npc_baseline_compare-face.jpg`.
|
||||||
- NPC torso/hip transition (0.9.4 work): the pelvis and chest are slightly wider than the waist, giving shirts and jackets a readable taper into the hips without changing the build multipliers or the skeleton. The comparison is `sheet_npc_baseline_compare-torso.jpg`.
|
- NPC torso/hip transition (0.9.4 work): the pelvis and chest are slightly wider than the waist, giving shirts and jackets a readable taper into the hips without changing the build multipliers or the skeleton. The comparison is `sheet_npc_baseline_compare-torso.jpg`.
|
||||||
- Release v0.9.4 (2026-11-02): the tagged commit `a57b86c` passed the Gitea checks and full build and published seven artifacts (Linux, Windows, macOS, NSIS setup, AppImage, Web and Desktop HQ). Release page: <https://git.allucanget.biz/zwitschi/security-game/releases/tag/v0.9.4>.
|
- Release v0.9.4 (2026-11-02): the tagged commit `a57b86c` passed the Gitea checks and full build and published seven artifacts (Linux, Windows, macOS, NSIS setup, AppImage, Web and Desktop HQ). Release page: <https://git.allucanget.biz/zwitschi/security-game/releases/tag/v0.9.4>.
|
||||||
|
- Environment texture pass (0.9.5 work): `capture_realism.gd` now has hidden-HUD `surfaces`/`surfaces_joke` close-up stages. The Walk of Fame band uses the paver texture as dark terrazzo, the neighbour awning keeps its cream stripe, and the skyline shader blends its lower 42 m toward a per-phase haze colour. Brick, asphalt, limestone and paver UV scales/profiles passed without replacement.
|
||||||
- NPC texture pass (0.9.5 work): the NPC base and all eight library characters now use 256² albedo/normal/ORM maps instead of 128². Cloth and pants use `NPC_FABRIC_UV_SCALE` (4× weave) and skip the baked per-character AO, removing the large blotchy patches in portraits; skin, hair and gear keep baked AO. The base and eight GLBs plus AO maps were rebuilt; the 24-NPC smoke remains green.
|
- NPC texture pass (0.9.5 work): the NPC base and all eight library characters now use 256² albedo/normal/ORM maps instead of 128². Cloth and pants use `NPC_FABRIC_UV_SCALE` (4× weave) and skip the baked per-character AO, removing the large blotchy patches in portraits; skin, hair and gear keep baked AO. The base and eight GLBs plus AO maps were rebuilt; the 24-NPC smoke remains green.
|
||||||
- NPC visual optimization (0.9.4, complete 2026-11-02): all eight variants passed the portrait/readability, proportion, gear, foot/shoe, headgear and final-context gates. The library uses an 8,000-triangle / 8,000-glTF-vertex cap (up from 6,000/5,000; `npc_base` fallback remains 6,000/4,000); current characters measure 4,482–5,474 triangles and 4,260–5,494 vertices. The 48-frame baseline and 96-frame final-context review pass, the hand/gear offset and shoes are in, and the accepted stylized limits are documented in `npc-visual-review.md`.
|
- NPC visual optimization (0.9.4, complete 2026-11-02): all eight variants passed the portrait/readability, proportion, gear, foot/shoe, headgear and final-context gates. The library uses an 8,000-triangle / 8,000-glTF-vertex cap (up from 6,000/5,000; `npc_base` fallback remains 6,000/4,000); current characters measure 4,482–5,474 triangles and 4,260–5,494 vertices. The 48-frame baseline and 96-frame final-context review pass, the hand/gear offset and shoes are in, and the accepted stylized limits are documented in `npc-visual-review.md`.
|
||||||
- NPC face-detail pass (0.9.4 work): ala wings and a smaller nose bridge/tip, one rounded mouth slot, and a darker ear concha; all eight rebuilt. The comparison is `sheet_npc_baseline_compare-face-detail.jpg`.
|
- NPC face-detail pass (0.9.4 work): ala wings and a smaller nose bridge/tip, one rounded mouth slot, and a darker ear concha; all eight rebuilt. The comparison is `sheet_npc_baseline_compare-face-detail.jpg`.
|
||||||
|
|||||||
@@ -17,10 +17,14 @@ const T_SKYLINE_NIGHT := preload(PICK_DIR + "skyline_night.png")
|
|||||||
## Height of each backdrop plane (metres); the bases sit on the ground plane.
|
## Height of each backdrop plane (metres); the bases sit on the ground plane.
|
||||||
const SKYLINE_HEIGHT := 90.0
|
const SKYLINE_HEIGHT := 90.0
|
||||||
const SKYLINE_BY_PHASE := {
|
const SKYLINE_BY_PHASE := {
|
||||||
Rules.Phase.EARLY: {"texture": T_SKYLINE_DAY, "tint": Color(0.98, 1.0, 1.04)},
|
Rules.Phase.EARLY: {"texture": T_SKYLINE_DAY, "tint": Color(0.98, 1.0, 1.04),
|
||||||
Rules.Phase.MIDDAY: {"texture": T_SKYLINE_DAY, "tint": Color(1.02, 1.04, 1.08)},
|
"haze": Color(0.62, 0.71, 0.82), "haze_strength": 0.36},
|
||||||
Rules.Phase.EVENING: {"texture": T_SKYLINE_DUSK, "tint": Color(0.9, 0.92, 1.0)},
|
Rules.Phase.MIDDAY: {"texture": T_SKYLINE_DAY, "tint": Color(1.02, 1.04, 1.08),
|
||||||
Rules.Phase.LATE: {"texture": T_SKYLINE_NIGHT, "tint": Color(1.5, 1.55, 1.65)},
|
"haze": Color(0.66, 0.75, 0.85), "haze_strength": 0.34},
|
||||||
|
Rules.Phase.EVENING: {"texture": T_SKYLINE_DUSK, "tint": Color(0.9, 0.92, 1.0),
|
||||||
|
"haze": Color(0.55, 0.43, 0.40), "haze_strength": 0.30},
|
||||||
|
Rules.Phase.LATE: {"texture": T_SKYLINE_NIGHT, "tint": Color(1.5, 1.55, 1.65),
|
||||||
|
"haze": Color(0.07, 0.09, 0.14), "haze_strength": 0.22},
|
||||||
}
|
}
|
||||||
## steps, building facade, restricted door, sidewalk, pavement, and street edge.
|
## steps, building facade, restricted door, sidewalk, pavement, and street edge.
|
||||||
## Surfaces use the shared PBR profiles in `src/game/materials.gd`; street
|
## Surfaces use the shared PBR profiles in `src/game/materials.gd`; street
|
||||||
@@ -648,8 +652,10 @@ func _build_sunset_neighbours() -> void:
|
|||||||
# Ground-floor shopfront and a red canvas awning.
|
# Ground-floor shopfront and a red canvas awning.
|
||||||
_add_box(west, Vector3(8.6, 2.4, 0.12), Vector3(-22.6, 1.5, west_front + 0.08),
|
_add_box(west, Vector3(8.6, 2.4, 0.12), Vector3(-22.6, 1.5, west_front + 0.08),
|
||||||
Color(0.08, 0.10, 0.12), false, null, Vector2.ONE, "glass")
|
Color(0.08, 0.10, 0.12), false, null, Vector2.ONE, "glass")
|
||||||
|
# Keep the cream stripe: tinting the whole atlas dark red collapsed the
|
||||||
|
# canvas into a flat band at portrait distance.
|
||||||
_add_box(west, Vector3(9.2, 0.22, 1.3), Vector3(-22.6, 3.0, west_front + 0.65),
|
_add_box(west, Vector3(9.2, 0.22, 1.3), Vector3(-22.6, 3.0, west_front + 0.65),
|
||||||
Color(0.48, 0.10, 0.08), true, T_AWNING, Vector2(3, 0.5), "awning")
|
Color(0.62, 0.62, 0.62), true, T_AWNING, Vector2(4, 1), "awning")
|
||||||
# Balcony rails on the upper floor.
|
# Balcony rails on the upper floor.
|
||||||
for x in [-24.8, -21.2, -17.6]:
|
for x in [-24.8, -21.2, -17.6]:
|
||||||
_add_box(west, Vector3(2.4, 0.08, 0.85), Vector3(x, 5.6, west_front + 0.55),
|
_add_box(west, Vector3(2.4, 0.08, 0.85), Vector3(x, 5.6, west_front + 0.55),
|
||||||
@@ -1379,8 +1385,10 @@ func _build_walk_of_fame() -> void:
|
|||||||
var walk := Node3D.new()
|
var walk := Node3D.new()
|
||||||
walk.name = "WalkOfFame"
|
walk.name = "WalkOfFame"
|
||||||
root.add_child(walk)
|
root.add_child(walk)
|
||||||
|
# Reuse the paver map as a dark terrazzo: a flat colour read as a black
|
||||||
|
# strip at close range, while the texture supplies the small aggregate.
|
||||||
_add_box(walk, Vector3(30.0, 0.035, 1.75), Vector3(0, 0.198, 9.15),
|
_add_box(walk, Vector3(30.0, 0.035, 1.75), Vector3(0, 0.198, 9.15),
|
||||||
Color(0.20, 0.18, 0.17), false, null, Vector2.ONE, "stone")
|
Color(0.34, 0.30, 0.27), false, T_CONCRETE, Vector2(18, 1.05), "concrete")
|
||||||
var star_mesh := _star_mesh(0.40, 0.17)
|
var star_mesh := _star_mesh(0.40, 0.17)
|
||||||
var brass := Materials.flat(Color(0.70, 0.55, 0.24), "metal")
|
var brass := Materials.flat(Color(0.70, 0.55, 0.24), "metal")
|
||||||
var coral := Materials.flat(Color(0.72, 0.30, 0.28), "stone")
|
var coral := Materials.flat(Color(0.72, 0.30, 0.28), "stone")
|
||||||
@@ -1595,6 +1603,8 @@ func _build_skyline_backdrop() -> void:
|
|||||||
mat.shader = shader
|
mat.shader = shader
|
||||||
mat.set_shader_parameter("sky_texture", SKYLINE_BY_PHASE[_phase]["texture"])
|
mat.set_shader_parameter("sky_texture", SKYLINE_BY_PHASE[_phase]["texture"])
|
||||||
mat.set_shader_parameter("tint", SKYLINE_BY_PHASE[_phase]["tint"])
|
mat.set_shader_parameter("tint", SKYLINE_BY_PHASE[_phase]["tint"])
|
||||||
|
mat.set_shader_parameter("haze_color", SKYLINE_BY_PHASE[_phase]["haze"])
|
||||||
|
mat.set_shader_parameter("haze_strength", SKYLINE_BY_PHASE[_phase]["haze_strength"])
|
||||||
mat.set_shader_parameter("repeats", 2.0)
|
mat.set_shader_parameter("repeats", 2.0)
|
||||||
_skyline_mat = mat
|
_skyline_mat = mat
|
||||||
var mesh := PlaneMesh.new()
|
var mesh := PlaneMesh.new()
|
||||||
@@ -1633,11 +1643,18 @@ render_mode unshaded, cull_disabled, fog_disabled;
|
|||||||
|
|
||||||
uniform sampler2D sky_texture : source_color, repeat_enable, filter_linear_mipmap;
|
uniform sampler2D sky_texture : source_color, repeat_enable, filter_linear_mipmap;
|
||||||
uniform vec4 tint : source_color = vec4(1.0);
|
uniform vec4 tint : source_color = vec4(1.0);
|
||||||
|
uniform vec4 haze_color : source_color = vec4(0.62, 0.71, 0.82, 1.0);
|
||||||
|
uniform float haze_strength = 0.36;
|
||||||
uniform float repeats = 2.0;
|
uniform float repeats = 2.0;
|
||||||
|
|
||||||
void fragment() {
|
void fragment() {
|
||||||
vec4 panorama = texture(sky_texture, vec2(UV.x * repeats, UV.y));
|
vec4 panorama = texture(sky_texture, vec2(UV.x * repeats, UV.y));
|
||||||
ALBEDO = panorama.rgb * tint.rgb;
|
// Atmospheric perspective: blend the lower part of the panorama toward
|
||||||
|
// the horizon colour so the towers sit in the distance instead of reading
|
||||||
|
// as a crisp cardboard cut-out.
|
||||||
|
float world_y = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).y;
|
||||||
|
float horizon = clamp(1.0 - world_y / 42.0, 0.0, 1.0);
|
||||||
|
ALBEDO = mix(panorama.rgb * tint.rgb, haze_color.rgb, horizon * haze_strength);
|
||||||
ALPHA = panorama.a * tint.a;
|
ALPHA = panorama.a * tint.a;
|
||||||
ALPHA_SCISSOR_THRESHOLD = 0.5;
|
ALPHA_SCISSOR_THRESHOLD = 0.5;
|
||||||
}
|
}
|
||||||
@@ -2241,6 +2258,8 @@ func set_phase(phase: int) -> void:
|
|||||||
if _skyline_mat != null:
|
if _skyline_mat != null:
|
||||||
_skyline_mat.set_shader_parameter("sky_texture", entry["texture"])
|
_skyline_mat.set_shader_parameter("sky_texture", entry["texture"])
|
||||||
_skyline_mat.set_shader_parameter("tint", entry["tint"])
|
_skyline_mat.set_shader_parameter("tint", entry["tint"])
|
||||||
|
_skyline_mat.set_shader_parameter("haze_color", entry["haze"])
|
||||||
|
_skyline_mat.set_shader_parameter("haze_strength", entry["haze_strength"])
|
||||||
var night: bool = phase == Rules.Phase.EVENING or phase == Rules.Phase.LATE
|
var night: bool = phase == Rules.Phase.EVENING or phase == Rules.Phase.LATE
|
||||||
set_night_mode(night)
|
set_night_mode(night)
|
||||||
if _street_mat != null:
|
if _street_mat != null:
|
||||||
|
|||||||
@@ -62,6 +62,18 @@ const SHOTS_JOKE_DAY := [
|
|||||||
const SHOTS_STUDIO := [
|
const SHOTS_STUDIO := [
|
||||||
{"name": "studio_door", "pos": Vector3(0, 0.1, 6.2), "yaw": 0.0, "pitch": 2.0},
|
{"name": "studio_door", "pos": Vector3(0, 0.1, 6.2), "yaw": 0.0, "pitch": 2.0},
|
||||||
]
|
]
|
||||||
|
## Surface close-ups for the 0.9.5 texture audit; HUD is hidden for this stage.
|
||||||
|
const SHOTS_SURFACES := [
|
||||||
|
{"name": "surface_pavers", "pos": Vector3(0, 0.1, 10.5), "yaw": 0.0, "pitch": -55.0},
|
||||||
|
{"name": "surface_asphalt", "pos": Vector3(0, 0.1, 14.0), "yaw": 180.0, "pitch": -42.0},
|
||||||
|
{"name": "surface_limestone", "pos": Vector3(0, 0.1, 2.0), "yaw": 0.0, "pitch": 8.0},
|
||||||
|
{"name": "surface_facade_wide", "pos": Vector3(-2.0, 0.1, 13.2), "yaw": 12.0, "pitch": 20.0},
|
||||||
|
]
|
||||||
|
const SHOTS_SURFACES_JOKE := [
|
||||||
|
{"name": "surface_awning", "pos": Vector3(-22.6, 0.1, 2.6), "yaw": 0.0, "pitch": 14.0},
|
||||||
|
{"name": "surface_canopy", "pos": Vector3(0, 0.1, 7.5), "yaw": 0.0, "pitch": 24.0},
|
||||||
|
{"name": "surface_pavers_joke", "pos": Vector3(0, 0.1, 10.0), "yaw": 0.0, "pitch": -55.0},
|
||||||
|
]
|
||||||
## A face-on portrait: staged relative to a live NPC by `_stage_portrait()`.
|
## A face-on portrait: staged relative to a live NPC by `_stage_portrait()`.
|
||||||
const SHOTS_PORTRAIT := [
|
const SHOTS_PORTRAIT := [
|
||||||
{"name": "npc_portrait", "pos": Vector3.ZERO, "yaw": 0.0, "pitch": 0.0,
|
{"name": "npc_portrait", "pos": Vector3.ZERO, "yaw": 0.0, "pitch": 0.0,
|
||||||
@@ -70,6 +82,8 @@ const SHOTS_PORTRAIT := [
|
|||||||
## Stage list: shift time selects the phase, `venue` switches the scenario first.
|
## Stage list: shift time selects the phase, `venue` switches the scenario first.
|
||||||
const STAGES := [
|
const STAGES := [
|
||||||
{"name": "day", "elapsed": 0.0, "venue": "", "shots": SHOTS_DAY, "night": false},
|
{"name": "day", "elapsed": 0.0, "venue": "", "shots": SHOTS_DAY, "night": false},
|
||||||
|
{"name": "surfaces", "elapsed": 0.0, "venue": "", "shots": SHOTS_SURFACES, "night": false},
|
||||||
|
{"name": "surfaces_joke", "elapsed": 0.0, "venue": "joke_shop", "shots": SHOTS_SURFACES_JOKE, "night": false},
|
||||||
# Portrait next, while the day crowd is still on the street.
|
# Portrait next, while the day crowd is still on the street.
|
||||||
{"name": "portrait", "elapsed": 0.0, "venue": "", "shots": SHOTS_PORTRAIT,
|
{"name": "portrait", "elapsed": 0.0, "venue": "", "shots": SHOTS_PORTRAIT,
|
||||||
"night": false},
|
"night": false},
|
||||||
@@ -182,6 +196,7 @@ func _begin_stage() -> void:
|
|||||||
gm.hud.clear_log()
|
gm.hud.clear_log()
|
||||||
gm.hud.set_target_label("")
|
gm.hud.set_target_label("")
|
||||||
gm.hud.set_action_hint("")
|
gm.hud.set_action_hint("")
|
||||||
|
gm.hud.visible = not str(stage["name"]).begins_with("surfaces")
|
||||||
if _flashlight:
|
if _flashlight:
|
||||||
var want := bool(stage["night"])
|
var want := bool(stage["night"])
|
||||||
if want != bool(gm.flashlight_on):
|
if want != bool(gm.flashlight_on):
|
||||||
|
|||||||
@@ -113,8 +113,13 @@ func test_hollywood_uses_the_real_landmark_layout() -> bool:
|
|||||||
var banners := root.find_child("EventBanners", true, false)
|
var banners := root.find_child("EventBanners", true, false)
|
||||||
var d := TestUtils.check(banners != null and banners.get_child_count() >= 9,
|
var d := TestUtils.check(banners != null and banners.get_child_count() >= 9,
|
||||||
"three red event banners with their trim are present")
|
"three red event banners with their trim are present")
|
||||||
var e := TestUtils.check(root.find_child("WalkOfFame", true, false) != null,
|
var walk := root.find_child("WalkOfFame", true, false)
|
||||||
"the Hollywood Walk of Fame strip is built")
|
var walk_band := walk.get_child(0) as MeshInstance3D if walk != null else null
|
||||||
|
var walk_material: Material = walk_band.mesh.surface_get_material(0) if walk_band != null else null
|
||||||
|
var e := TestUtils.check(walk != null and walk_material != null
|
||||||
|
and walk_material is StandardMaterial3D
|
||||||
|
and (walk_material as StandardMaterial3D).albedo_texture != null,
|
||||||
|
"the Hollywood Walk of Fame strip is built with the terrazzo texture")
|
||||||
var f := TestUtils.check(root.get_node_or_null("NeighbourBlocks/ElCapitanTheatre") != null
|
var f := TestUtils.check(root.get_node_or_null("NeighbourBlocks/ElCapitanTheatre") != null
|
||||||
and root.get_node_or_null("NeighbourBlocks/EastRetailBlock") != null,
|
and root.get_node_or_null("NeighbourBlocks/EastRetailBlock") != null,
|
||||||
"the El Capitan Theatre and east retail neighbours are built")
|
"the El Capitan Theatre and east retail neighbours are built")
|
||||||
@@ -260,8 +265,12 @@ func test_skyline_backdrop_uses_alpha() -> bool:
|
|||||||
var mat: ShaderMaterial = builder._skyline_mat
|
var mat: ShaderMaterial = builder._skyline_mat
|
||||||
var b := TestUtils.check(mat != null and mat.shader != null, "skyline shader material captured")
|
var b := TestUtils.check(mat != null and mat.shader != null, "skyline shader material captured")
|
||||||
var code := mat.shader.code if mat != null and mat.shader != null else ""
|
var code := mat.shader.code if mat != null and mat.shader != null else ""
|
||||||
var c := TestUtils.check(code.contains("ALPHA") and code.contains("fog_disabled"),
|
var c := TestUtils.check(code.contains("ALPHA") and code.contains("fog_disabled")
|
||||||
"backdrop shader is alpha-scissored and fog-free")
|
and code.contains("haze_strength"),
|
||||||
|
"backdrop shader is alpha-scissored, fog-free and haze-blended")
|
||||||
|
var haze := float(mat.get_shader_parameter("haze_strength")) if mat != null else 0.0
|
||||||
|
var c2 := TestUtils.check(haze > 0.0, "skyline haze is enabled")
|
||||||
|
c = c and c2
|
||||||
var day: Texture2D = mat.get_shader_parameter("sky_texture")
|
var day: Texture2D = mat.get_shader_parameter("sky_texture")
|
||||||
builder.set_phase(Rules.Phase.LATE)
|
builder.set_phase(Rules.Phase.LATE)
|
||||||
var night: Texture2D = mat.get_shader_parameter("sky_texture")
|
var night: Texture2D = mat.get_shader_parameter("sky_texture")
|
||||||
|
|||||||
Reference in new issue
Block a user