donmccurdy / three-gltf-viewer

Drag-and-drop preview for glTF 2.0 models in WebGL using three.js.
https://gltf-viewer.donmccurdy.com/
MIT License
2.1k stars 533 forks source link

Validated GLB model fails to load without a proper error message #202

Open alexGuntha opened 4 years ago

alexGuntha commented 4 years ago

Hello,

I have attached a simple model (a 5-vertex pyramid with some colors) generated by a tool of my own, so there's still a possibility my exporter is buggy, though I believe I strictly followed the format specification. Though, it loads properly in Blender 2.81, https://sandbox.babylonjs.com/, and is validated by http://github.khronos.org/glTF-Validator/ The output of the validator: { "uri": "bloc1.glb", "mimeType": "model/gltf-binary", "validatorVersion": "2.0.0-dev.3.2", "validatedAt": "2020-06-23T21:27:09.612Z", "issues": { "numErrors": 0, "numWarnings": 0, "numInfos": 1, "numHints": 0, "messages": [ { "code": "UNUSED_OBJECT", "message": "This object may be unused.", "severity": 2, "pointer": "/meshes/0/primitives/0/attributes/TEXCOORD_0" } ], "truncated": false }, "info": { "version": "2.0", "generator": "Guntha's Engine MeshBuilder::saveToGLB", "resources": [ { "pointer": "/buffers/0", "mimeType": "application/gltf-buffer", "storage": "glb", "byteLength": 268 } ], "animationCount": 0, "materialCount": 0, "hasMorphTargets": false, "hasSkins": false, "hasTextures": false, "hasDefaultScene": true, "drawCallCount": 1, "totalVertexCount": 5, "totalTriangleCount": 4, "maxUVs": 1, "maxInfluences": 0, "maxAttributes": 4 } }

In Firefox (77.0.1), it fails with the error "attempting to construct out-of-bounds TypedArray on ArrayBuffer" image And on Edge with the error "Invalid offset/length when creating typed array" image

bloc1.zip

donmccurdy commented 4 years ago

This does appear to be a bug in the viewer — the model is technically valid. But it also fails to load in the glTF Sample Viewer with the same error, for the same reason: the vertex data is interleaved in way that you probably don't intend. Generally if you're interleaving the vertices, you want to use a single bufferView for an entire primitive (or even multiple primitives), and set accessor.byteOffset with the offsets for each vertex attribute. This model uses a new bufferView for each vertex attribute. In three.js, at least, that will lose the benefit of the interleaving. It's also the reason for the error here, although looking at the glTF specification I can see I got the math wrong for this situation (expecting the bufferview to have space for the remaining attributes) and I should fix that.

alexGuntha commented 4 years ago

Hello Don, thank you very much for your insight, I fixed the issue on my end, I'm leaving a "fixed" version of the model here as an example of "better practice" (accessors with a byte offset for each attribute, only 1 bufferView for the actual vertices data). bloc1.zip