Draw prop models with a single atlas material
Each generated prop used one material per part (body, accent, metal...). The model pipeline now packs a prop's palette into one power-of-two colour atlas plus a matching metallic/roughness atlas and emits a single material: - atlas_for(): 8x8 cells per palette role, colours in sRGB, roughness in the G and metallic in the B channel of the second atlas; NEAREST sampling keeps cells flat. - build_glb(): every part merges into one primitive with constant per-vertex atlas UVs; the material uses baseColorTexture + metallicRoughnessTexture with factors 1.0. - audit_glb(): fails unless a prop has exactly one material, both atlas textures, two images, and TEXCOORD_0 on every primitive. - Removed the now-unused sRGB->linear factor helpers; colour travels in the texture. Verification: headless 181 -> 182 (new "one material per prop scene" test), Python tooling 53/53 (atlas determinism/size/UV/palette-override tests replace the old factor tests), model audit OK for all six props, screenshots regenerated and screen_designs.py compare still 6 good / 0 bad. Version 0.3.1.
This commit is contained in:
1 parent
7f92b8861d
commit
f2863abeac
32 files changed
+275
-97
No files matched your search
@@ -39,6 +39,35 @@ func test_prop_scenes_instantiate_with_meshes() -> bool:
|
||||
instance.free()
|
||||
return TestUtils.check(problems.is_empty(), "every prop scene has geometry (%s)" % str(problems))
|
||||
|
||||
func test_prop_scenes_share_one_atlas_material() -> bool:
|
||||
## All parts of a prop share one material backed by the colour atlas, so a
|
||||
## prop is a single draw material instead of one per part.
|
||||
var problems: Array[String] = []
|
||||
for prop in WorldBuilder.MODEL_PROPS:
|
||||
var packed := ResourceLoader.load(MODEL_DIR + str(prop) + ".glb") as PackedScene
|
||||
if packed == null:
|
||||
problems.append("%s: no scene" % prop)
|
||||
continue
|
||||
var instance := packed.instantiate()
|
||||
var meshes := instance.find_children("*", "MeshInstance3D", true, false)
|
||||
var materials := {}
|
||||
var surfaces := 0
|
||||
for node in meshes:
|
||||
var mesh: Mesh = (node as MeshInstance3D).mesh
|
||||
if mesh == null:
|
||||
continue
|
||||
for index in mesh.get_surface_count():
|
||||
surfaces += 1
|
||||
var material := mesh.surface_get_material(index)
|
||||
if material != null:
|
||||
materials[material.get_instance_id()] = true
|
||||
if surfaces == 0:
|
||||
problems.append("%s: no surfaces" % prop)
|
||||
elif materials.size() != 1:
|
||||
problems.append("%s: %d materials (expected 1)" % [prop, materials.size()])
|
||||
instance.free()
|
||||
return TestUtils.check(problems.is_empty(), "one atlas material per prop (%s)" % str(problems))
|
||||
|
||||
func test_world_places_generated_props() -> bool:
|
||||
var root := Node3D.new()
|
||||
var builder := WorldBuilder.new(root)
|
||||
|
||||
Reference in new issue
Block a user