feat(scene): phone LOD car and clearcoat coachwork on desktop
Phones and the low tier load a decimated grand tourer built by a headless Blender script (31k to 11k faces, same nodes and materials). Desktop gets clearcoat paint and a soft halo parented to the tail bar.
This commit is contained in:
63
scripts/blender/make-lite-car.py
Normal file
63
scripts/blender/make-lite-car.py
Normal file
@@ -0,0 +1,63 @@
|
||||
"""Builds the phone LOD of the grand tourer. Headless only:
|
||||
|
||||
blender -b --python scripts/blender/make-lite-car.py -- \
|
||||
src/assets/nightdrive-grand-tourer-chromatic.glb \
|
||||
src/assets/nightdrive-grand-tourer-lite.glb
|
||||
|
||||
On a phone the car is about 200 px wide and seen from behind, so the wheel
|
||||
machining, the tyre treads and the dense trim carry detail nobody can see.
|
||||
They are collapsed; the silhouette parts (body, haunches, glass) are kept
|
||||
as authored so the car reads the same. Node names and the hierarchy are
|
||||
preserved: car.ts finds the wheels, the light bar and the underglow by name.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
import bpy
|
||||
|
||||
source, target = sys.argv[sys.argv.index("--") + 1 :][:2]
|
||||
|
||||
# Fraction of faces kept, by node name prefix (after the "evolution-" prefix).
|
||||
RATIOS = {
|
||||
"wheel-machining": 0.22,
|
||||
"tires": 0.25,
|
||||
"body-trim": 0.35,
|
||||
"rear-light-bar": 0.4,
|
||||
"car-underglow-source": 0.35,
|
||||
}
|
||||
|
||||
bpy.ops.wm.read_factory_settings(use_empty=True)
|
||||
bpy.ops.import_scene.gltf(filepath=source)
|
||||
|
||||
before = after = 0
|
||||
for obj in bpy.data.objects:
|
||||
if obj.type != "MESH":
|
||||
continue
|
||||
name = obj.name.removeprefix("evolution-")
|
||||
faces = len(obj.data.polygons)
|
||||
before += faces
|
||||
ratio = next((r for prefix, r in RATIOS.items() if name.startswith(prefix)), None)
|
||||
if ratio is not None and faces > 200:
|
||||
# Meshes can be shared between wheels; give each object its own data.
|
||||
obj.data = obj.data.copy()
|
||||
modifier = obj.modifiers.new("lod", "DECIMATE")
|
||||
modifier.decimate_type = "COLLAPSE"
|
||||
modifier.ratio = ratio
|
||||
modifier.use_collapse_triangulate = True
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
for other in bpy.context.view_layer.objects:
|
||||
other.select_set(other is obj)
|
||||
bpy.ops.object.modifier_apply(modifier=modifier.name)
|
||||
after += len(obj.data.polygons)
|
||||
|
||||
bpy.ops.export_scene.gltf(
|
||||
filepath=target,
|
||||
export_format="GLB",
|
||||
export_apply=True,
|
||||
export_yup=True,
|
||||
export_texcoords=False,
|
||||
export_normals=True,
|
||||
export_materials="EXPORT",
|
||||
export_animations=False,
|
||||
)
|
||||
print(f"LITE faces {before} -> {after}")
|
||||
Reference in New Issue
Block a user