Skip to content
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

Merged
merged 12 commits into from
Oct 12, 2019

Conversation

zeux
Copy link
Owner

@zeux zeux commented Oct 9, 2019

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:

  1. 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

  2. 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.

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.
@zeux
Copy link
Owner Author

zeux commented Oct 10, 2019

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.
@zeux zeux merged commit 9432b7a into master Oct 12, 2019
@zeux zeux deleted the gltf-fallback branch October 12, 2019 04:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant