Files
mtgodot-poc/project/gpu_lod_attachment_test.gd

64 lines
2.8 KiB
GDScript

extends SceneTree
const PlayerView = preload("res://ui/player_view.gd")
var failures: Array[String] = []
var ghosts_checked := 0
func _initialize() -> void:
call_deferred("run")
func check(ok: bool, message: String) -> void:
if not ok:
failures.append(message)
printerr("FAIL: ", message)
func run() -> void:
OS.set_environment("MTGODOT_GPUSKIN", "1")
var cam := Camera3D.new()
root.add_child(cam)
cam.make_current()
for race in 8:
cam.position = Vector3(0, 1, 3)
var pv := PlayerView.new()
root.add_child(pv)
if not pv.build(AssetRoot.path(), race):
check(false, "race %d build failed" % race)
pv.queue_free()
continue
pv.anim.set_process(false)
pv.anim.set("blend_time", 0.0)
pv.anim.set("time", 0.5)
var mesh_node: MeshInstance3D = pv.model.get_node("MeshInstance3D")
var reference_hair: PackedVector3Array = mesh_node.mesh.surface_get_arrays(mesh_node.mesh.get_surface_count() - 1)[Mesh.ARRAY_VERTEX]
for level in [0, 1, 2, 3, 2, 1, 0]:
cam.position = Vector3(0, 1, [3.0, 25.0, 60.0, 110.0][level])
for frame in 3:
await process_frame
check(int(pv.model.call("get_lod_level")) == level, "race %d did not reach LOD %d" % [race, level])
var mesh := mesh_node.mesh
var last := mesh.get_surface_count() - 1
check(String(mesh.surface_get_name(last)).begins_with("hair_"), "race %d LOD %d lost hair" % [race, level])
var vertices: PackedVector3Array = mesh.surface_get_arrays(last)[Mesh.ARRAY_VERTEX]
check(vertices == reference_hair, "race %d LOD %d changed hair geometry" % [race, level])
var mat: ShaderMaterial = mesh_node.get_active_material(last)
check(int(mat.get_shader_parameter("mode")) == 2, "race %d LOD %d lost hair cutout" % [race, level])
check(mat.get_shader_parameter("bones_tex") != null, "race %d LOD %d lost skin matrices" % [race, level])
var ghost: MeshInstance3D = pv.model.get_node_or_null("LodGhost")
if ghost != null:
ghosts_checked += 1
var old_mat: ShaderMaterial = ghost.get_active_material(0)
var frozen: Texture2D = old_mat.get_shader_parameter("bones_tex")
check(frozen != mat.get_shader_parameter("bones_tex"), "LOD ghost shares live bone texture")
var before := frozen.get_image().get_data()
pv.anim.set("time", 1.0)
check(before == frozen.get_image().get_data(), "LOD ghost pose changed after animation sample")
check(ghost.custom_aabb.size.length_squared() > 0, "LOD ghost lost posed culling bounds")
for surface in ghost.mesh.get_surface_count():
check(ghost.get_active_material(surface) != null, "LOD ghost lost surface material")
pv.anim.set("time", 0.5)
pv.queue_free()
await process_frame
check(ghosts_checked > 0, "No LOD fade snapshots were exercised")
print("gpu_lod_attachment_test: failures=", failures.size(), " ghosts=", ghosts_checked)
quit(0 if failures.is_empty() else 1)