Skip to content

Commit

Permalink
gltfpack: Switch to EXT_meshopt_compression extension
Browse files Browse the repository at this point in the history
We now produce files encoded with EXT_ extension variant, and
string-like enums for compression mode/filter instead of integer enums.
  • Loading branch information
zeux committed Jun 16, 2020
1 parent 320876d commit 137d574
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 12 deletions.
2 changes: 1 addition & 1 deletion gltf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ gltfpack substantially changes the glTF data by optimizing the meshes for vertex

By default gltfpack outputs regular `.glb`/`.gltf` files that have been optimized for GPU consumption using various cache optimizers and quantization. These files can be loaded by GLTF loaders that support `KHR_mesh_quantization` extension such as [three.js](https://threejs.org/) (r111+) and [Babylon.js](https://www.babylonjs.com/) (4.1+).

When using `-c` option, gltfpack outputs compressed `.glb`/`.gltf` files that use meshoptimizer codecs to reduce the download size further. Loading these files requires extending GLTF loaders with support for `MESHOPT_compression` extension; [demo/GLTFLoader.js](https://github.com/zeux/meshoptimizer/blob/master/demo/GLTFLoader.js) contains a custom version of three.js loader that can be used to load them.
When using `-c` option, gltfpack outputs compressed `.glb`/`.gltf` files that use meshoptimizer codecs to reduce the download size further. Loading these files requires extending GLTF loaders with support for `EXT_meshopt_compression` extension; [demo/GLTFLoader.js](https://github.com/zeux/meshoptimizer/blob/master/demo/GLTFLoader.js) contains a custom version of three.js loader that can be used to load them.

For better compression, you can use `-cc` option which applies additional compression; additionally make sure that your content delivery method is configured to use deflate (gzip) - meshoptimizer codecs are designed to produce output that can be compressed further with general purpose compressors.

Expand Down
4 changes: 2 additions & 2 deletions gltf/gltfpack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output

const ExtensionInfo extensions[] = {
{"KHR_mesh_quantization", settings.quantize, true},
{"MESHOPT_compression", settings.compress, !settings.fallback},
{"EXT_meshopt_compression", settings.compress, !settings.fallback},
{"KHR_texture_transform", settings.quantize && !json_textures.empty(), false},
{"KHR_materials_pbrSpecularGlossiness", ext_pbr_specular_glossiness, false},
{"KHR_materials_clearcoat", ext_clearcoat, false},
Expand Down Expand Up @@ -669,7 +669,7 @@ static std::string getBufferSpec(const char* bin_path, size_t bin_size, const ch
append(json, "\"byteLength\":");
append(json, fallback_size);
append(json, ",\"extensions\":{");
append(json, "\"MESHOPT_compression\":{");
append(json, "\"EXT_meshopt_compression\":{");
append(json, "\"fallback\":true");
append(json, "}}");
append(json, "}");
Expand Down
2 changes: 1 addition & 1 deletion gltf/parsegltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ cgltf_data* parseGltf(const char* path, std::vector<Mesh>& meshes, std::vector<A
*error = getError(result, data);
else if (requiresExtension(data, "KHR_draco_mesh_compression"))
*error = "file requires Draco mesh compression support";
else if (requiresExtension(data, "MESHOPT_compression"))
else if (requiresExtension(data, "EXT_meshopt_compression"))
*error = "file has already been compressed using gltfpack";
else if (needsDummyBuffers(data))
*error = "buffer has no data";
Expand Down
76 changes: 68 additions & 8 deletions gltf/write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,63 @@ static const char* lightType(cgltf_light_type type)
}
}

static const char* alphaMode(cgltf_alpha_mode mode)
{
switch (mode)
{
case cgltf_alpha_mode_opaque:
return "OPAQUE";

case cgltf_alpha_mode_mask:
return "MASK";

case cgltf_alpha_mode_blend:
return "BLEND";

default:
return "";
}
}

static const char* compressionMode(BufferView::Compression mode)
{
switch (mode)
{
case BufferView::Compression_Attribute:
return "ATTRIBUTES";

case BufferView::Compression_Index:
return "TRIANGLES";

case BufferView::Compression_IndexSequence:
return "INDICES";

default:
return "";
}
}

static const char* compressionFilter(StreamFormat::Filter filter)
{
switch (filter)
{
case StreamFormat::Filter_None:
return "NONE";

case StreamFormat::Filter_Oct:
return "OCTAHEDRAL";

case StreamFormat::Filter_Quat:
return "QUATERNION";

case StreamFormat::Filter_Exp:
return "EXPONENTIAL";

default:
return "";
}
}

static void writeTextureInfo(std::string& json, const cgltf_data* data, const cgltf_texture_view& view, const QuantizationTexture* qt)
{
assert(view.texture);
Expand Down Expand Up @@ -337,8 +394,9 @@ void writeMaterial(std::string& json, const cgltf_data* data, const cgltf_materi
if (material.alpha_mode != cgltf_alpha_mode_opaque)
{
comma(json);
append(json, "\"alphaMode\":");
append(json, (material.alpha_mode == cgltf_alpha_mode_blend) ? "\"BLEND\"" : "\"MASK\"");
append(json, "\"alphaMode\":\"");
append(json, alphaMode(material.alpha_mode));
append(json, "\"");
}

if (material.alpha_cutoff != 0.5f)
Expand Down Expand Up @@ -404,7 +462,7 @@ void writeBufferView(std::string& json, BufferView::Kind kind, StreamFormat::Fil

// when compression is enabled, we store uncompressed data in buffer 1 and compressed data in buffer 0
// when compression is disabled, we store uncompressed data in buffer 0
size_t buffer = compression >= 0 ? 1 : 0;
size_t buffer = compression != BufferView::Compression_None ? 1 : 0;

append(json, "{\"buffer\":");
append(json, buffer);
Expand All @@ -425,20 +483,22 @@ void writeBufferView(std::string& json, BufferView::Kind kind, StreamFormat::Fil
if (compression != BufferView::Compression_None)
{
append(json, ",\"extensions\":{");
append(json, "\"MESHOPT_compression\":{");
append(json, "\"EXT_meshopt_compression\":{");
append(json, "\"buffer\":0");
append(json, ",\"byteOffset\":");
append(json, size_t(compressed_offset));
append(json, ",\"byteLength\":");
append(json, size_t(compressed_size));
append(json, ",\"byteStride\":");
append(json, stride);
append(json, ",\"mode\":");
append(json, size_t(compression));
append(json, ",\"mode\":\"");
append(json, compressionMode(compression));
append(json, "\"");
if (filter != StreamFormat::Filter_None)
{
append(json, ",\"filter\":");
append(json, size_t(filter));
append(json, ",\"filter\":\"");
append(json, compressionFilter(filter));
append(json, "\"");
}
append(json, ",\"count\":");
append(json, count);
Expand Down

0 comments on commit 137d574

Please sign in to comment.