extends SceneTree const OUTPUT_PATH := "res://docs/baselines/jajce_lookdev_01.png" const SCENE_PATH := "res://world/jajce/JajceLookdev.tscn" const CAPTURE_SIZE := Vector2i(1280, 720) const WARMUP_FRAMES := 90 func _initialize() -> void: call_deferred("_run") func _run() -> void: root.size = CAPTURE_SIZE var scene := load(SCENE_PATH) as PackedScene if scene == null: push_error("Could not load %s" % SCENE_PATH) quit(1) return var lookdev := scene.instantiate() as Node3D root.add_child(lookdev) await process_frame for _frame in WARMUP_FRAMES: await process_frame var image := root.get_texture().get_image() if image == null or image.is_empty(): push_error("Lookdev capture produced no image") quit(1) return var analysis := _analyze_image(image) if analysis.get("range", 0.0) < 0.05: push_error("Lookdev capture is too uniform: %s" % analysis) quit(1) return var error := image.save_png(OUTPUT_PATH) if error != OK: push_error("Could not save %s: %s" % [OUTPUT_PATH, error_string(error)]) quit(1) return print("[TOOL] Saved %s | %s" % [OUTPUT_PATH, analysis]) quit(0) func _analyze_image(image: Image) -> Dictionary: var min_luma := INF var max_luma := -INF var total_luma := 0.0 var samples := 0 var step_x = maxi(1, image.get_width() / 64) var step_y = maxi(1, image.get_height() / 36) for y in range(0, image.get_height(), step_y): for x in range(0, image.get_width(), step_x): var color := image.get_pixel(x, y) var luma := color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722 min_luma = minf(min_luma, luma) max_luma = maxf(max_luma, luma) total_luma += luma samples += 1 return { "size": "%sx%s" % [image.get_width(), image.get_height()], "samples": samples, "average_luma": total_luma / samples, "range": max_luma - min_luma, }