saumwacht-godot/tools/ringborke_benchmark.gd
Martin Stickelbroeck c2b447610c Baseline: Saumwacht 0.15.0 (Phase 20A) vor dem Umbau zu Champions of Luneraria
Unveränderter Ausgangsstand inklusive Masterprompt und Konzeptbildern
unter assets/. .godot/ und docs/screenshots/ bleiben laut .gitignore
unversioniert; letztere sind unter ../backups gesichert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 20:00:36 +02:00

69 lines
3.3 KiB
GDScript

extends Node3D
var stage: Node3D
var viewport: SubViewport
var camera: Camera3D
var figures: Array[Node3D] = []
var results: Array = []
func _ready() -> void:
call_deferred("run")
func run() -> void:
Soundscape.enabled = false
DisplayServer.window_set_vsync_mode(DisplayServer.VSYNC_DISABLED)
get_window().size = Vector2i(960,540)
viewport = SubViewport.new()
viewport.own_world_3d = true
viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
viewport.msaa_3d = Viewport.MSAA_4X
add_child(viewport)
stage = Node3D.new()
viewport.add_child(stage)
var display := TextureRect.new()
display.texture = viewport.get_texture()
display.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
display.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
add_child(display)
var env := WorldEnvironment.new()
env.environment=Environment.new()
preload("res://scripts/presentation/lighting.gd").configure(env.environment,true)
stage.add_child(env)
var light := DirectionalLight3D.new()
light.rotation_degrees=Vector3(-45,-30,0)
light.light_energy=1.3
light.shadow_enabled=true
stage.add_child(light)
camera=Camera3D.new()
camera.projection=Camera3D.PROJECTION_ORTHOGONAL
stage.add_child(camera)
for resolution: Vector2i in [Vector2i(1920,1080),Vector2i(2560,1440)]:
viewport.size=resolution
for count: int in [1,30,90]:
for figure: Node3D in figures:figure.free()
figures.clear()
var columns: int = ceili(sqrt(count))
for i: int in range(count):
var figure: Node3D = AssetLibrary.instantiate_fighter("w04")
figure.position=Vector3((i%columns-columns*.5)*2.2,0,(i/columns-columns*.5)*2.2)
stage.add_child(figure)
figures.append(figure)
camera.size=maxf(4,columns*2.5)
camera.position=Vector3(8,18,23)
camera.look_at(Vector3(0,.8,0))
var times: Array[float]=[]
var started: int=Time.get_ticks_usec()
var previous: int=started
while Time.get_ticks_usec()-started < 8000000:
var elapsed: float = (Time.get_ticks_usec()-started)/1000000.0
for i: int in range(figures.size()):figures[i].preview("walk",fmod(elapsed+i*.05,1.4))
await get_tree().process_frame
var now: int=Time.get_ticks_usec()
if elapsed>2:times.append((now-previous)/1000.0)
previous=now
var total: float=0
for t: float in times:total+=t
times.sort()
var record := {"resolution":str(resolution),"window_size":str(get_window().size),"render_size":str(viewport.get_texture().get_size()),"instances":count,"mean_frame_ms":total/times.size(),"p95_frame_ms":times[int(times.size()*.95)],"draw_calls":Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME),"video_memory_bytes":Performance.get_monitor(Performance.RENDER_VIDEO_MEM_USED),"fps":1000.0/(total/times.size())}
results.append(record)
print("RIG_BENCH: ",record)
var f:=FileAccess.open("res://docs/phase11-benchmark.json",FileAccess.WRITE)
f.store_string(JSON.stringify({"device":RenderingServer.get_video_adapter_name(),"renderer":RenderingServer.get_current_rendering_method(),"vsync":false,"msaa":"4x","render_target":"Fixed-size SubViewport independent of desktop DPI and window stretch","warmup_seconds":2,"sample_seconds":6,"scope":"Isolated animated characters; not a complete game benchmark; includes CPU and GPU frame pacing, not separately timed stages","results":results},"\t"));f.close()
await Soundscape.quit_game()