extends Node3D
## Test scene: Sky3DExtended atmosphere + SunshineClouds2 volumetric clouds.
## Sky3D Extended provides atmosphere/sun/moon/stars/cirrus.
## SunshineClouds2 provides volumetric cloud rendering via CompositorEffect.
##
## Controls:
## T / Shift+T — advance / rewind time by 1 hour
## F — fast forward (1min cycle)
## G — normal speed (15min cycle)
## P — pause / resume time
## F12 — screenshot
var _sky3d: Sky3DExtended
var _driver: SunshineCloudsDriverGD
func _ready() -> void:
_sky3d = $Sky3DExtended as Sky3DExtended
if not _sky3d:
push_error("[Sky3D+Sunshine] Sky3DExtended not found")
return
# Create SunshineClouds2 driver — it auto-creates the CompositorEffect
_driver = SunshineCloudsDriverGD.new()
_driver.name = "SunshineCloudsDriver"
add_child(_driver)
# Wait one frame for Sky3D to finish initialization (creates SunLight/MoonLight)
call_deferred("_setup_sunshine")
print("[Sky3D+Sunshine] T/Shift+T: ±1hr, F: fast, G: slow, P: pause, F12: screenshot")
func _setup_sunshine() -> void:
var sun_light := _sky3d.sun
var moon_light := _sky3d.moon
if not sun_light:
push_warning("[Sky3D+Sunshine] No SunLight found in Sky3DExtended")
return
# Create the cloud CompositorEffect and attach to Sky3D's WorldEnvironment
var cloud_res := SunshineCloudsGD.new()
cloud_res.clouds_coverage = 0.874
cloud_res.clouds_density = 0.14
cloud_res.atmospheric_density = 0.503
cloud_res.lighting_density = 0.982
cloud_res.clouds_anisotropy = 0.16
cloud_res.clouds_sharpness = 0.746
cloud_res.cloud_floor = 1500.0
cloud_res.cloud_ceiling = 25000.0
cloud_res.max_step_count = 300.0
cloud_res.max_lighting_steps = 32.0
cloud_res.curl_noise_strength = 4500.0
_driver.clouds_resource = cloud_res
# Add to Sky3D's compositor
var we := _sky3d as WorldEnvironment
if not we.compositor:
we.compositor = Compositor.new()
var effects := we.compositor.compositor_effects.duplicate()
effects.append(cloud_res)
we.compositor.compositor_effects = effects
# Track lights
var lights: Array[DirectionalLight3D] = []
lights.append(sun_light)
if moon_light:
lights.append(moon_light)
_driver.tracked_directional_lights = lights
_driver.tracked_directional_light_shadow_steps = [32, 12]
# Wind
_driver.wind_direction = Vector3(2, 0, 2)
_driver.update_continuously = true
print("[Sky3D+Sunshine] SunshineClouds2 active, tracking %d lights, coverage=%.2f" % [lights.size(), cloud_res.clouds_coverage])
func _unhandled_input(event: InputEvent) -> void:
if not event is InputEventKey or not event.pressed or not _sky3d:
return
match event.keycode:
KEY_T:
var delta := -1.0 if event.shift_pressed else 1.0
_sky3d.current_time = fmod(_sky3d.current_time + delta + 24.0, 24.0)
print("[Sky3D+Sunshine] Time: %.1f (%s)" % [
_sky3d.current_time, "day" if _sky3d.is_day() else "night"])
KEY_F:
_sky3d.minutes_per_day = 1.0
print("[Sky3D+Sunshine] Fast forward (1min cycle)")
KEY_G:
_sky3d.minutes_per_day = 15.0
print("[Sky3D+Sunshine] Normal speed (15min cycle)")
KEY_P:
if _sky3d.game_time_enabled:
_sky3d.pause()
print("[Sky3D+Sunshine] Paused at %.1f" % _sky3d.current_time)
else:
_sky3d.resume()
print("[Sky3D+Sunshine] Resumed")
KEY_F12:
var img := get_viewport().get_texture().get_image()
var ts := Time.get_datetime_string_from_system().replace(":", "-")
var dir := "/home/fleeky/Desktop/hyper-tps"
DirAccess.make_dir_recursive_absolute(dir)
var path := "%s/sky3d_sunshine_%s.png" % [dir, ts]
img.save_png(path)
print("[Sky3D+Sunshine] Screenshot: %s" % path)