Dusk and night: FLUX sky panoramas, working street lamps, headlights
A Time column in the menu picks day / dusk / night per run: - Dusk: low orange sun under a FLUX-generated equirectangular panorama (golden hour rakes the heritage facades -- best light in the game). - Night: dim blue moonlight, city-glow panorama, headlight spotlights on the player, and every street lamp gets a real OmniLight under its lantern. Because the light is parented to the lamp's physics body, toppling the lamp takes its pool of light with it. Panorama seams are wrap-blended in post (PanoramaSky tiles horizontally and FLUX edges never match on their own); flux_local.py learned non-square generation (1024x512) for exactly this. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
d886188475
commit
52f7705e13
BIN
assets/textures/sky_dusk.jpg
Normal file
BIN
assets/textures/sky_dusk.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
40
assets/textures/sky_dusk.jpg.import
Normal file
40
assets/textures/sky_dusk.jpg.import
Normal file
@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bijmj1x4hi11a"
|
||||
path="res://.godot/imported/sky_dusk.jpg-63e4d345e86325d5834f66bcdedd0851.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/textures/sky_dusk.jpg"
|
||||
dest_files=["res://.godot/imported/sky_dusk.jpg-63e4d345e86325d5834f66bcdedd0851.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
assets/textures/sky_night.jpg
Normal file
BIN
assets/textures/sky_night.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
40
assets/textures/sky_night.jpg.import
Normal file
40
assets/textures/sky_night.jpg.import
Normal file
@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://2rackpqbvwp2"
|
||||
path="res://.godot/imported/sky_night.jpg-79b8d08aa9423f4579159cfb2d221005.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/textures/sky_night.jpg"
|
||||
dest_files=["res://.godot/imported/sky_night.jpg-79b8d08aa9423f4579159cfb2d221005.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
40
shot_dusk.png.import
Normal file
40
shot_dusk.png.import
Normal file
@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ckgqxm67w4wjg"
|
||||
path="res://.godot/imported/shot_dusk.png-f6af1b6e4e64591ef1de1c661224bed5.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://shot_dusk.png"
|
||||
dest_files=["res://.godot/imported/shot_dusk.png-f6af1b6e4e64591ef1de1c661224bed5.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
40
shot_new_bubbla_600.png.import
Normal file
40
shot_new_bubbla_600.png.import
Normal file
@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ceecujmymhp7v"
|
||||
path="res://.godot/imported/shot_new_bubbla_600.png-05b2db194b7a014fc14c973c912e5583.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://shot_new_bubbla_600.png"
|
||||
dest_files=["res://.godot/imported/shot_new_bubbla_600.png-05b2db194b7a014fc14c973c912e5583.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
40
shot_new_falcodore_gtho.png.import
Normal file
40
shot_new_falcodore_gtho.png.import
Normal file
@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://mll58atwcrp6"
|
||||
path="res://.godot/imported/shot_new_falcodore_gtho.png-e66ed2ab5a9d8d094ec961c70879ba93.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://shot_new_falcodore_gtho.png"
|
||||
dest_files=["res://.godot/imported/shot_new_falcodore_gtho.png-e66ed2ab5a9d8d094ec961c70879ba93.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
40
shot_new_hardon_waggo.png.import
Normal file
40
shot_new_hardon_waggo.png.import
Normal file
@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c7vogu04epx1b"
|
||||
path="res://.godot/imported/shot_new_hardon_waggo.png-070bed85dde44ad7d2157c19c292a0a0.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://shot_new_hardon_waggo.png"
|
||||
dest_files=["res://.godot/imported/shot_new_hardon_waggo.png-070bed85dde44ad7d2157c19c292a0a0.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
40
shot_new_hardon_wb_ute.png.import
Normal file
40
shot_new_hardon_wb_ute.png.import
Normal file
@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bgjfj2d166iw"
|
||||
path="res://.godot/imported/shot_new_hardon_wb_ute.png-7ed5d240147f85803b553146a1f90363.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://shot_new_hardon_wb_ute.png"
|
||||
dest_files=["res://.godot/imported/shot_new_hardon_wb_ute.png-7ed5d240147f85803b553146a1f90363.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
40
shot_night.png.import
Normal file
40
shot_night.png.import
Normal file
@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://ssfx4eea0hio"
|
||||
path="res://.godot/imported/shot_night.png-18957e7f26c9433700879ac3d7e65fdb.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://shot_night.png"
|
||||
dest_files=["res://.godot/imported/shot_night.png-18957e7f26c9433700879ac3d7e65fdb.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
90
src/game.gd
90
src/game.gd
@ -10,6 +10,7 @@ extends Node3D
|
||||
static var car_path := ""
|
||||
static var level_path := ""
|
||||
static var mode := "cruise"
|
||||
static var time_of_day := "day" # day | dusk | night
|
||||
static var junction: Dictionary = {}
|
||||
|
||||
const LAPS := 3
|
||||
@ -493,11 +494,22 @@ func _spawn_smashables(level: Node) -> void:
|
||||
hmat.albedo_color = Color(0.86, 0.84, 0.72)
|
||||
hmat.emission_enabled = true
|
||||
hmat.emission = Color(0.9, 0.85, 0.6)
|
||||
hmat.emission_energy_multiplier = 0.35
|
||||
hmat.emission_energy_multiplier = 0.35 if time_of_day != "night" else 3.5
|
||||
hm.material = hmat
|
||||
head.mesh = hm
|
||||
head.position = Vector3(1.45, size.y * 0.5 - 0.36, 0)
|
||||
b.add_child(head)
|
||||
if time_of_day == "night":
|
||||
# a real light under the lantern -- and because it's parented
|
||||
# to the physics body, toppling the lamp takes its pool of
|
||||
# light with it, which is deeply satisfying
|
||||
var ol := OmniLight3D.new()
|
||||
ol.light_color = Color(1.0, 0.87, 0.55)
|
||||
ol.light_energy = 1.6
|
||||
ol.omni_range = 13.0
|
||||
ol.omni_attenuation = 1.4
|
||||
ol.position = head.position - Vector3(0, 0.5, 0)
|
||||
b.add_child(ol)
|
||||
add_child(b)
|
||||
var t: Transform3D = (m as Node3D).global_transform
|
||||
b.global_transform = Transform3D(
|
||||
@ -507,12 +519,22 @@ func _spawn_smashables(level: Node) -> void:
|
||||
n += 1
|
||||
|
||||
func _build_environment() -> void:
|
||||
## Brisbane midday: hard high sun, deep blue zenith, everything a bit blown out.
|
||||
## The bare default (no tonemap, grey ambient) rendered the city flat and dead.
|
||||
## Three Brisbanes: midday (hard high sun), dusk (low orange sun under a FLUX
|
||||
## panorama) and night (moonlight, working street lamps, headlights).
|
||||
var sun := DirectionalLight3D.new()
|
||||
sun.rotation_degrees = Vector3(-62, 38, 0)
|
||||
sun.light_color = Color(1.0, 0.96, 0.88)
|
||||
sun.light_energy = 1.25
|
||||
match time_of_day:
|
||||
"dusk":
|
||||
sun.rotation_degrees = Vector3(-11, 55, 0)
|
||||
sun.light_color = Color(1.0, 0.62, 0.32)
|
||||
sun.light_energy = 0.85
|
||||
"night":
|
||||
sun.rotation_degrees = Vector3(-48, -20, 0)
|
||||
sun.light_color = Color(0.55, 0.65, 0.90) # moon
|
||||
sun.light_energy = 0.14
|
||||
_:
|
||||
sun.rotation_degrees = Vector3(-62, 38, 0)
|
||||
sun.light_color = Color(1.0, 0.96, 0.88)
|
||||
sun.light_energy = 1.25
|
||||
sun.shadow_enabled = true
|
||||
sun.directional_shadow_mode = DirectionalLight3D.SHADOW_PARALLEL_4_SPLITS
|
||||
sun.directional_shadow_max_distance = 220.0
|
||||
@ -533,14 +555,24 @@ func _build_environment() -> void:
|
||||
fill.shadow_enabled = false
|
||||
add_child(fill)
|
||||
|
||||
var sky_mat := ProceduralSkyMaterial.new()
|
||||
sky_mat.sky_top_color = Color(0.27, 0.46, 0.74)
|
||||
sky_mat.sky_horizon_color = Color(0.80, 0.86, 0.92)
|
||||
sky_mat.sky_energy_multiplier = 1.0
|
||||
sky_mat.ground_bottom_color = Color(0.28, 0.28, 0.30)
|
||||
sky_mat.ground_horizon_color = Color(0.66, 0.72, 0.78)
|
||||
sky_mat.sun_angle_max = 4.0
|
||||
sky_mat.sun_curve = 0.08
|
||||
# dusk/night ride FLUX panoramas; day keeps the procedural gradient
|
||||
var sky_mat: Material
|
||||
var pano := "res://assets/textures/sky_%s.jpg" % time_of_day
|
||||
if time_of_day != "day" and ResourceLoader.exists(pano):
|
||||
var pm := PanoramaSkyMaterial.new()
|
||||
pm.panorama = load(pano)
|
||||
pm.energy_multiplier = 1.3 if time_of_day == "dusk" else 0.9
|
||||
sky_mat = pm
|
||||
else:
|
||||
var gm := ProceduralSkyMaterial.new()
|
||||
gm.sky_top_color = Color(0.27, 0.46, 0.74)
|
||||
gm.sky_horizon_color = Color(0.80, 0.86, 0.92)
|
||||
gm.sky_energy_multiplier = 1.0
|
||||
gm.ground_bottom_color = Color(0.28, 0.28, 0.30)
|
||||
gm.ground_horizon_color = Color(0.66, 0.72, 0.78)
|
||||
gm.sun_angle_max = 4.0
|
||||
gm.sun_curve = 0.08
|
||||
sky_mat = gm
|
||||
|
||||
var e := Environment.new()
|
||||
e.background_mode = Environment.BG_SKY
|
||||
@ -550,8 +582,16 @@ func _build_environment() -> void:
|
||||
# a street canyon is lit almost entirely by ambient, so pure sky ambient
|
||||
# painted the whole city blue -- blend it half-and-half with neutral
|
||||
e.ambient_light_sky_contribution = 0.5
|
||||
e.ambient_light_color = Color(0.88, 0.87, 0.84)
|
||||
e.ambient_light_energy = 0.55
|
||||
match time_of_day:
|
||||
"dusk":
|
||||
e.ambient_light_color = Color(0.80, 0.62, 0.55)
|
||||
e.ambient_light_energy = 0.38
|
||||
"night":
|
||||
e.ambient_light_color = Color(0.35, 0.40, 0.55)
|
||||
e.ambient_light_energy = 0.16
|
||||
_:
|
||||
e.ambient_light_color = Color(0.88, 0.87, 0.84)
|
||||
e.ambient_light_energy = 0.55
|
||||
e.reflected_light_source = Environment.REFLECTION_SOURCE_SKY
|
||||
e.tonemap_mode = Environment.TONE_MAPPER_ACES
|
||||
e.tonemap_exposure = 0.6
|
||||
@ -573,10 +613,28 @@ func _build_environment() -> void:
|
||||
e.fog_depth_end = 900.0
|
||||
e.fog_depth_curve = 0.7
|
||||
e.fog_sun_scatter = 0.15
|
||||
if time_of_day == "night":
|
||||
e.glow_intensity = 0.8 # lamp heads and tail lights bloom
|
||||
e.fog_light_color = Color(0.10, 0.11, 0.16)
|
||||
elif time_of_day == "dusk":
|
||||
e.fog_light_color = Color(0.55, 0.38, 0.30)
|
||||
var env := WorldEnvironment.new()
|
||||
env.environment = e
|
||||
add_child(env)
|
||||
|
||||
if time_of_day == "night":
|
||||
# headlights on the player: two warm spots raking the road ahead
|
||||
for sx in [-0.55, 0.55]:
|
||||
var hl := SpotLight3D.new()
|
||||
hl.light_color = Color(1.0, 0.94, 0.78)
|
||||
hl.light_energy = 4.0
|
||||
hl.spot_range = 42.0
|
||||
hl.spot_angle = 28.0
|
||||
hl.spot_angle_attenuation = 1.6
|
||||
hl.position = Vector3(sx, 0.15, -car.stats.length * 0.48)
|
||||
hl.rotation_degrees = Vector3(-4.0, 180.0, 0)
|
||||
car.add_child(hl)
|
||||
|
||||
func _exit_tree() -> void:
|
||||
Engine.time_scale = 1.0
|
||||
|
||||
|
||||
@ -3,10 +3,12 @@ extends Control
|
||||
|
||||
const MODES := [["cruise", "Cruise"], ["crash", "Crash Mode"], ["race", "Race"],
|
||||
["rage", "Road Rage"], ["drag", "Drag"], ["derby", "Derby"]]
|
||||
const TIMES := [["day", "Day"], ["dusk", "Dusk"], ["night", "Night"]]
|
||||
|
||||
@onready var car_list: ItemList = $VBox/HBox/Cars
|
||||
@onready var level_list: ItemList = $VBox/HBox/Levels
|
||||
@onready var mode_list: ItemList = $VBox/HBox/Modes
|
||||
@onready var time_list: ItemList = $VBox/HBox/Times
|
||||
|
||||
var car_paths: Array = []
|
||||
var level_paths: Array = []
|
||||
@ -29,6 +31,9 @@ func _ready() -> void:
|
||||
junction_data.append(j.data)
|
||||
for m in MODES:
|
||||
mode_list.add_item(m[1])
|
||||
for t in TIMES:
|
||||
time_list.add_item(t[1])
|
||||
time_list.select(0)
|
||||
if not car_paths.is_empty():
|
||||
car_list.select(0)
|
||||
if not level_paths.is_empty():
|
||||
@ -45,4 +50,6 @@ func _start() -> void:
|
||||
Game.junction = junction_data[li]
|
||||
# picking a CRASH JCT entry forces junction mode, whatever the mode column says
|
||||
Game.mode = "junction" if not Game.junction.is_empty() else MODES[mode_list.get_selected_items()[0]][0]
|
||||
var ti := time_list.get_selected_items()
|
||||
Game.time_of_day = TIMES[ti[0]][0] if not ti.is_empty() else "day"
|
||||
get_tree().change_scene_to_file("res://src/game.tscn")
|
||||
|
||||
@ -51,6 +51,10 @@ size_flags_horizontal = 3
|
||||
[node name="Modes" type="ItemList" parent="VBox/HBox"]
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="Times" type="ItemList" parent="VBox/HBox"]
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 0.5
|
||||
|
||||
[node name="Start" type="Button" parent="VBox"]
|
||||
text = "RACE"
|
||||
theme_override_font_sizes/font_size = 32
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate a texture on the local MODELBEAST farm (operator: flux_local).
|
||||
|
||||
Usage: flux_local.py "<prompt>" <out.jpg> [size_px] [target_luma]
|
||||
Usage: flux_local.py "<prompt>" <out.jpg> [size_px] [target_luma] [WxH]
|
||||
|
||||
size_px is the output's max dimension; WxH overrides the GENERATION aspect
|
||||
(e.g. 1024x512 for a 2:1 sky panorama). Output keeps the generation aspect.
|
||||
|
||||
The fallback for tools/flux_texture.sh when Cloudflare Workers AI returns 429 --
|
||||
its free tier is 10,000 neurons/day and a full texture-set regen burns through
|
||||
@ -48,9 +51,12 @@ def main():
|
||||
luma = float(sys.argv[4]) if len(sys.argv) > 4 else 0.0
|
||||
tok = token()
|
||||
|
||||
gen = max(size, 768) # generate at >=768 then downscale, same as the CF path
|
||||
if len(sys.argv) > 5 and "x" in sys.argv[5]:
|
||||
gw, gh = (int(v) for v in sys.argv[5].split("x"))
|
||||
else:
|
||||
gw = gh = max(size, 768) # generate at >=768 then downscale, like the CF path
|
||||
job = call("/api/jobs", tok, {"operator": "flux_local", "params": {
|
||||
"prompt": prompt, "width": gen, "height": gen, "steps": 6}})
|
||||
"prompt": prompt, "width": gw, "height": gh, "steps": 6}})
|
||||
jid = job["id"]
|
||||
for _ in range(120):
|
||||
time.sleep(3)
|
||||
@ -75,7 +81,9 @@ def main():
|
||||
open(tmp, "wb").write(blob)
|
||||
|
||||
from PIL import Image, ImageStat
|
||||
im = Image.open(tmp).convert("RGB").resize((size, size), Image.LANCZOS)
|
||||
im = Image.open(tmp).convert("RGB")
|
||||
scale = size / max(im.size)
|
||||
im = im.resize((max(1, int(im.width * scale)), max(1, int(im.height * scale))), Image.LANCZOS)
|
||||
if luma:
|
||||
mean = ImageStat.Stat(im.convert("L")).mean[0]
|
||||
if mean > luma:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user