-
-
Notifications
You must be signed in to change notification settings - Fork 36.1k
Description
Repro
Attached, a version of WaterBottle.glb quantized by my (WIP) quantization implementation in donmccurdy/glTF-Transform#59. The model has a number of validation issues that I'm still working on, but it should be able to render in three.js now, and doesn't.
If you load the model and then erase the default bounding box information, it works normally.
Screenshot:
Desktop (please complete the following information):
All.
Smartphone (please complete the following information):
All.
Additional context
Referring to the code here...
three.js/examples/js/loaders/GLTFLoader.js
Lines 2860 to 2875 in 51afad9
| if ( attributes.POSITION !== undefined ) { | |
| var accessor = parser.json.accessors[ attributes.POSITION ]; | |
| var min = accessor.min; | |
| var max = accessor.max; | |
| // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement. | |
| if ( min !== undefined && max !== undefined ) { | |
| box.set( | |
| new THREE.Vector3( min[ 0 ], min[ 1 ], min[ 2 ] ), | |
| new THREE.Vector3( max[ 0 ], max[ 1 ], max[ 2 ] ) ); | |
| } else { |
... it looks like three.js (as well as babylon.js, actually) is using the POSITION attribute's .min and .max property to infer bounds of a mesh primitive, without a more costly traversal of the vertex data. However, the glTF specification states:
Exporters and loaders must treat these values as having the same data type as accessor's componentType, i.e., use integers (JSON number without fractional part) for integer types and use floating-point decimals for 5126 (FLOAT).
In other words, a normalized accessor will contain normalized integer values in its min/max, and the implementation needs to convert that to floating-point decimals to use as mesh bounds. This becomes an issue for models using KHR_materials_quantization, which may choose to use normalized 8-bit or 16-bit integer storage.
