From 78d311c75f011f612faa8487326eb4101725307f Mon Sep 17 00:00:00 2001 From: "Hermes (scopedvr-dev)" Date: Tue, 20 Oct 2026 22:11:30 +0000 Subject: [PATCH] Atmosphaere & Skybox (t_f72913d4): Render-Probe Editor-Vorschau (Panorama vs. Prozedural, xvfb/opengl3) --- tests/probe_skybox_render.gd | 98 ++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 tests/probe_skybox_render.gd diff --git a/tests/probe_skybox_render.gd b/tests/probe_skybox_render.gd new file mode 100644 index 0000000..4b28829 --- /dev/null +++ b/tests/probe_skybox_render.gd @@ -0,0 +1,98 @@ +extends SceneTree +## Beweisbild-Probe (Karte t_f72913d4 — Atmosphäre & Skybox): Editor-Vorschau +## MIT Pack-Panorama-Skybox vs. ProceduralSky — Sichtprüfung, dass die +## „Himmel: Pack-Skybox“-Option im Viewport tatsächlich die Wüsten-Panorama- +## Skybox zeigt (und ohne Feld das alte ProceduralSky bleibt). +## +## xvfb-run -a /opt/data/home/bin/godot4 --path . --rendering-driver opengl3 \ +## -s res://tests/probe_skybox_render.gd +## +## Ausgabe: PROBE_SKYBOX_OK/_FAIL + PNGs im Beweis-Ordner. + +const OUT_DIR := "/opt/data/scopedvr/work/atmos_skybox_bilder" + +var fehler: Array = [] + + +func _initialize() -> void: + _run() + + +func _run() -> void: + DirAccess.make_dir_recursive_absolute(OUT_DIR) + await process_frame + await process_frame + var manifest: Dictionary = JSON.parse_string( + FileAccess.get_file_as_string(SvmapIO.MANIFEST_PATH)) + + var builder := Node3D.new() + builder.set_script(load("res://src/viewport/map_view_builder.gd")) + root.add_child(builder) + var bscript: Script = builder.get_script() + var sky_pfad: String = bscript.panorama_sky_pfad() + print("Panorama-Pfad: %s (existiert: %s)" % [sky_pfad, str(FileAccess.file_exists(sky_pfad))]) + if sky_pfad.is_empty() or not FileAccess.file_exists(sky_pfad): + fehler.append("Pack-Skybox im Nachbar-Klon nicht erreichbar") + + var doc: Dictionary = SvmapDocument.create_new("Skybox-Beweis", 64.0, "mittag") + + # Kamera AM ROOT (rebuild() freed alle Builder-Kinder — eine Kamera am + # Builder würde bei jedem Rebuild mit sterben). WorldEnvironment wirkt + # viewport-global, die Kamera sieht den Himmel trotzdem. + var cam := Camera3D.new() + root.add_child(cam) + cam.position = Vector3(0.0, 6.0, 20.0) + cam.look_at(Vector3(0.0, 8.0, -100.0)) + cam.current = true + + # --- 1) Mit Pack-Skybox --- + doc["weather_sky"] = "sky_panorama" + builder.call("rebuild", doc, manifest) + await process_frame + await process_frame + var we := _welt_env(builder) + if we == null or we.environment == null or we.environment.sky == null: + fehler.append("kein WorldEnvironment/Sky im Baum") + else: + var mat = we.environment.sky.sky_material + print("Panorama-Fall: Material = %s" % str(mat)) + if not (mat is PanoramaSkyMaterial): + fehler.append("Panorama-Fall zeigt kein PanoramaSkyMaterial") + if we.environment.tonemap_mode != Environment.TONE_MAPPER_ACES: + fehler.append("Tonemap ist nicht ACES") + await RenderingServer.frame_post_draw + var img := root.get_texture().get_image() + var pfad1 := OUT_DIR.path_join("editor_panorama_skybox.png") + img.save_png(pfad1) + print("PROBE_SAVED %s (%dx%d)" % [pfad1, img.get_width(), img.get_height()]) + if img.get_width() < 100: + fehler.append("Panorama-Bild verdächtig klein") + + # --- 2) Ohne Feld (alte Map) → Procedural --- + doc.erase("weather_sky") + builder.call("rebuild", doc, manifest) + await process_frame + await process_frame + var we2 := _welt_env(builder) + if we2 != null and we2.environment != null and we2.environment.sky != null: + var mat2 = we2.environment.sky.sky_material + print("Prozedural-Fall: Material = %s" % str(mat2)) + if not (mat2 is ProceduralSkyMaterial): + fehler.append("Ohne Feld zeigt nicht das ProceduralSky") + await RenderingServer.frame_post_draw + var img2 := root.get_texture().get_image() + var pfad2 := OUT_DIR.path_join("editor_prozedural_sky.png") + img2.save_png(pfad2) + print("PROBE_SAVED %s (%dx%d)" % [pfad2, img2.get_width(), img2.get_height()]) + + for f in fehler: + print(" FEHLER: %s" % f) + print("PROBE_SKYBOX_%s" % ("FAIL" if not fehler.is_empty() else "OK")) + quit(0 if fehler.is_empty() else 1) + + +func _welt_env(builder: Node) -> WorldEnvironment: + for child in builder.get_children(): + if child is WorldEnvironment: + return child + return null