Repository navigation
perf(web): device models download at a third of their size - #12
Merged
Kaloyanes merged 1 commit intoOct 30, 2026
Conversation
The 18 device GLBs were 39.9 MB (22.3 MB gzipped), almost all uncompressed geometry, and the iPhone 16 and 16 Plus camera glass z-fought with the layer beneath it. - Compress geometry with EXT_meshopt_compression on one scene-wide 16-bit grid. Per-mesh grids round Apple's coincident layers apart and z-fight. The loader registers three's MeshoptDecoder and bakes display meshes back into float model-space geometry, which the screen checks, UVs and touch projection need. - Drop 478 parts that never change a pixel (sources.json hiddenNodes). - Push the iPhone 16 and 16 Plus glass shells 0.0003 units outward (sources.json surfaceOffsets) so they stop crossing the base layer. The converter applies both new fields; docs/internals/devices.md records the pipeline constraints. Models now total 12.0 MB (8.3 MB gzipped). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Kaloyanes
merged commit Oct 30, 2026
1d97c2a
into
Kaloyanes:feat/device-models-by-type
5 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR targets pingdotgg#26884's branch. Its description lists "the models folder grows to 38 MB" as a tradeoff, and this takes that off the table before it reaches
main. The 18 device models go from 39.9 MB to 12.0 MB (22.3 to 8.3 MB gzipped). It also fixes the iPhone 16 and 16 Plus camera glass flickering.Compression. Geometry was almost all of the size, so the GLBs now use
EXT_meshopt_compression, andmodelScene.tsregisters three'sMeshoptDecoder. Quantization runs on one scene-wide 16-bit grid. Apple's assets stack coincident layers (glass over a base finish), and per-mesh grids round those layers apart until they z-fight. Screen meshes get quantized too, so the loader bakes their node transform back into float geometry, because the screen checks, UVs and touch projection work in model space. It's all the stock CLI:gltf-transform weld, thenmeshopt --quantization-volume scene --quantize-position 16.Hidden parts. 478 parts never change a pixel. I rendered every model from 26 directions with a logarithmic depth buffer and hid each node in turn; only nodes that changed nothing are removed. They're listed per model as
hiddenNodesinsources.json. Parts that are only nearly hidden stay. The Duo keeps everything, because its hinge pose changes what's visible.Glass fix. Most models' glass is an exact copy of the layer beneath it, which draws cleanly. On the iPhone 16 and 16 Plus the blue glass shell crosses the white base, partly in front and partly behind, so WebGL draws a flickering patchwork even without compression.
surfaceOffsetspushes that shell 0.0003 units outward (about 0.1 px at normal size).Both new
sources.jsonfields are applied byconvert-device-model.py, anddocs/internals/devices.mdrecords the constraints. Simplification is ruled out there: even a 1e-5 error changed rim highlights and put a seam in the Duo's inner displays.Evidence
Rendered with the 3D viewer's renderer settings, lights and near/far.
Original vs shipped, front and back:
Checks:
loadDeviceModeland build their phone or Duo scene with its screen checks (temporary browser test, hardware WebGL).vp test run packages/client-runtime/src/device: 74 passed. The new case feeds a quantized screen through the load step, which the screen checks reject without it.Not checked: a live simulator in the app. This was done on Linux without an iOS simulator, so the device models were only exercised through the runtime code paths above.
Created with Claude Opus 5.5 in Claude Code (T3 Code).