Adopt the realism pass and refresh screenshots/docs
- add the v2 runtime picks: per-phase skyline panoramas, brick, sidewalk pavers, dry/wet asphalt, awning canvas, and their normal maps - add the realism tooling and evidence: tools/scene_concepts.py, capture_realism.gd, concept frames, reports/sheets, and tests - retune phase lighting/fog/exposure, add sun yaw, brighten the night glow, add the flashlight beam mesh, and rebuild the planter/tree assets - regenerate all eleven staged screenshots from the current build; compare is 11 good / 0 bad - finish the visual-alignment closeout in DONE/TODO, update architecture, blender-assets, PLAN, and ignore rules (editable Blender sources untracked) - keep the judge retry and document the verified default judge model Verification: headless 227/227; Python tooling 86/86; check_screenshots 11/11.
This commit is contained in:
1 parent
26ecb93fd4
commit
d7e523f63c
70 files changed
+4042
-101
No files matched your search
+43
-11
@@ -9,13 +9,19 @@ extends RefCounted
|
||||
## UV scaling, and texture filtering in one place so the world builder, the NPC
|
||||
## avatars, and the props all look like one scene.
|
||||
|
||||
const T_BRICK := preload("res://assets/textures/ai/game_ready/brick_facade.png")
|
||||
const T_CONCRETE := preload("res://assets/textures/ai/game_ready/concrete.png")
|
||||
const T_ASPHALT := preload("res://assets/textures/ai/game_ready/asphalt.png")
|
||||
const T_AWNING := preload("res://assets/textures/ai/game_ready/awning.png")
|
||||
const T_BRICK_NORMAL := preload("res://assets/textures/ai/game_ready/brick_facade_normal.png")
|
||||
const T_CONCRETE_NORMAL := preload("res://assets/textures/ai/game_ready/concrete_normal.png")
|
||||
const T_ASPHALT_NORMAL := preload("res://assets/textures/ai/game_ready/asphalt_normal.png")
|
||||
## Realism-pass picks (tools/scene_concepts.py promote): brick, sidewalk pavers and
|
||||
## asphalt replaced the flat first-generation tiles. Normal maps carry the mortar,
|
||||
## paver joints and aggregate that Compatibility cannot get from screen space.
|
||||
const PICK_DIR := "res://assets/textures/ai/game_ready/v2/picks/"
|
||||
const T_BRICK := preload(PICK_DIR + "brick_facade.png")
|
||||
const T_CONCRETE := preload(PICK_DIR + "sidewalk_pavers.png")
|
||||
const T_ASPHALT := preload(PICK_DIR + "asphalt.png")
|
||||
const T_ASPHALT_WET := preload(PICK_DIR + "asphalt_wet.png")
|
||||
const T_AWNING := preload(PICK_DIR + "awning_canvas.png")
|
||||
const T_BRICK_NORMAL := preload(PICK_DIR + "brick_facade_normal.png")
|
||||
const T_CONCRETE_NORMAL := preload(PICK_DIR + "sidewalk_pavers_normal.png")
|
||||
const T_ASPHALT_NORMAL := preload(PICK_DIR + "asphalt_normal.png")
|
||||
const T_ASPHALT_WET_NORMAL := preload(PICK_DIR + "asphalt_wet_normal.png")
|
||||
|
||||
## Roughness / metallic pairs per surface role. Exposed so tests and tooling can
|
||||
## assert the profiles instead of hard-coding numbers twice.
|
||||
@@ -90,10 +96,15 @@ static func brick(tint: Color = Color(1, 1, 1), uv_scale: Vector2 = Vector2(10,
|
||||
static func concrete(tint: Color = Color(1, 1, 1), uv_scale: Vector2 = Vector2(9, 2.4)) -> StandardMaterial3D:
|
||||
return textured(T_CONCRETE, tint, uv_scale, "concrete", T_CONCRETE_NORMAL)
|
||||
|
||||
static func asphalt(tint: Color = Color(1, 1, 1), uv_scale: Vector2 = Vector2(30, 7)) -> StandardMaterial3D:
|
||||
var mat := textured(T_ASPHALT, tint, uv_scale, "asphalt", T_ASPHALT_NORMAL)
|
||||
# Damp asphalt at night picks up the street lamps and the marquee.
|
||||
mat.metallic_specular = 0.6
|
||||
static func asphalt(tint: Color = Color(1, 1, 1), uv_scale: Vector2 = Vector2(30, 7),
|
||||
wet: bool = false) -> StandardMaterial3D:
|
||||
var texture: Texture2D = T_ASPHALT_WET if wet else T_ASPHALT
|
||||
var normal: Texture2D = T_ASPHALT_WET_NORMAL if wet else T_ASPHALT_NORMAL
|
||||
var mat := textured(texture, tint, uv_scale, "asphalt", normal)
|
||||
# Damp asphalt at night picks up the street lamps and the marquee: glossier
|
||||
# and slightly metallic so the lamp pools read as reflections.
|
||||
mat.metallic_specular = 0.75 if wet else 0.6
|
||||
mat.roughness = 0.38 if wet else float(profile("asphalt").get("roughness", 0.72))
|
||||
return mat
|
||||
|
||||
static func awning(tint: Color = Color(1, 1, 1), uv_scale: Vector2 = Vector2(4, 1)) -> StandardMaterial3D:
|
||||
@@ -117,6 +128,27 @@ static func emissive(color: Color, energy: float = 1.4) -> StandardMaterial3D:
|
||||
mat.roughness = 0.4
|
||||
return mat
|
||||
|
||||
## Fake light shaft for the flashlight (Compatibility has no volumetrics).
|
||||
## Additive, unshaded, no depth write: it glows over the scene, is still occluded
|
||||
## by walls, and fades out along its length instead of ending in a hard disc.
|
||||
static func light_beam() -> StandardMaterial3D:
|
||||
var mat := StandardMaterial3D.new()
|
||||
mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
||||
mat.blend_mode = BaseMaterial3D.BLEND_MODE_ADD
|
||||
mat.cull_mode = BaseMaterial3D.CULL_DISABLED
|
||||
mat.depth_draw_mode = BaseMaterial3D.DEPTH_DRAW_DISABLED
|
||||
mat.albedo_color = Color(1.0, 0.95, 0.82, 1.0)
|
||||
var fade := Gradient.new()
|
||||
fade.set_color(0, Color(1.0, 0.95, 0.82, 0.0))
|
||||
fade.add_point(0.18, Color(1.0, 0.95, 0.82, 0.22))
|
||||
fade.set_color(fade.get_point_count() - 1, Color(1.0, 0.95, 0.82, 0.0))
|
||||
var ramp := GradientTexture1D.new()
|
||||
ramp.gradient = fade
|
||||
mat.albedo_texture = ramp
|
||||
mat.texture_filter = BaseMaterial3D.TEXTURE_FILTER_LINEAR
|
||||
return mat
|
||||
|
||||
## Dark glass for windows and the entrance door. The alpha keeps the interior
|
||||
## visible, and the low roughness gives the facade a highlight instead of a hole.
|
||||
static func glass(color: Color = Color(0.42, 0.56, 0.72, 0.75)) -> StandardMaterial3D:
|
||||
|
||||
Reference in new issue
Block a user