-
Notifications
You must be signed in to change notification settings - Fork 514
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gltfpack: Rework compression extension to allow for uncompressed fallback #68
Conversation
When -cf setting is specified, we will save uncompressed binary data to the fallback buffer so that loaders that don't support the compression extension can load the data. This requires adjusting the JSON format for the buffer views; this change simply implements scaffolding necessary to support this - we now save an additional .fallback.bin file when requested and reference it from the JSON blob as a buffer #1.
Also add code to fill fallback buffer; now we need to fix JSON schema.
We now emit buffer view JSON to support fallback data properly: - Uncompressed buffer views are specified as before, with data sequentially laid out in buffer 0 - Compressed buffer views are specified with data laid out in buffer 0 and the compressed extension object explicitly targeting buffer 0 with the appropriate offsets - When fallback is used, compressed buffer views carry the uncompressed data in buffer 1 (that doesn't need to be loaded if the loader supports compression)
We now emit both buffers when compression is used; the fallback buffer should only be actually used when settings.fallback is set, but it needs to be specified for compressed buffer views to be able to reference it.
When compression is not used, the buffer offset needs to be taken from the bin, not fallback.
Both Three.JS and Babylon.JS loaders now read buffer view parameters from the extension JSON instead of reusing the buffer view.
Even though the fallback buffer is not always used, it is easier to always fill it with data because that way we can write sensible offsets and byte length into the JSON blob and just omit the actual file. This requires more memory but simplifies the code flow.
There are some questions regarding the exact approach taken here with fallback buffers in absence of the said fallback - it's not clear if dummy buffer references are optimal. There's a tracking issue for this in the spec repository, KhronosGroup/glTF#1684 - depending on the way it is resolved, this PR may or may not need changes. Since this is a large change to the JSON schema, I would rather do it once so I'm going to wait to merge this for a bit. |
Add -cf option to the brief gltfpack overview.
This looks cleaner and might compress a tiny bit better.
@donmccurdy had a great suggestion to mark the dummy buffer in a special way. This change marks the fallback buffer with fallback:true attribute. This can be useful for two reasons: - Fallback buffer without a URI is somewhat odd. The attribute helps note that this is not a regular buffer and it relates to the compression extension. - Fallback attribute is actually helpful for loaders that recognize MESHOPT_compression - they can skip loading the buffer from the URI. This is not necessary for Babylon.JS / Three.JS but could help in the future. The specification could be something like "if fallback:true is specified, all buffer views that refer to this buffer must have a MESHOPT_compression extension override that targets a different buffer". So specifying this attribute is optional if you want to mix & match fallback data with actual data in a real buffer. Then it naturally follows that if the extension support is required, fallback buffers can be ignored for the purpose of validation etc.
This change reworks the extension definition so that instead of using bufferOffset/bufferLength/buffer from the bufferView, the extension JSON specifies these directly.
This is important for two reasons:
This allows us to produce conformant compressed files - previously, bufferLength in the buffer view violated the spec (since the accessor needed to read more bytes from the buffer view), and it wasn't clear how to resolve this
This allows us to produce compressed files with uncompressed fallbacks (
-cf
option). In this mode, the.bin
/.glb
data is still using optimally packed compressed data, but we generate an extra.fallback.bin
file with uncompressed data. Loaders that support compression don't need to load this buffer, but the files are compatible with loaders that don't support compression extension.When generating compressed files without fallback (
-c
), we generate a "dummy" buffer with no URI. This is necessary because, since bufferView.buffer is a required schema element, this seems to be the only reasonable option of generating files that conform to glTF specification.This is a breaking change in the compression extension specification so this change updates loaders and has to update the demo
.glb
file.