Skip to content

Commit

Permalink
gltfpack: Implement initial support for KHR_materials_variants
Browse files Browse the repository at this point in the history
This change implements basic support for material variants. Each mesh
now keeps track of a set of material mappings; mesh merging is limited
to cases when the variant set is the same, and all material variants are
preserved.

Since we don't correctly compute the UV bounds for variant materials,
this only works without quantization so far.
  • Loading branch information
zeux committed Feb 2, 2021
1 parent d8bbb36 commit 4469d8f
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 0 deletions.
39 changes: 39 additions & 0 deletions gltf/gltfpack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,26 @@ static void process(cgltf_data* data, const char* input_path, const char* output
append(json_meshes, size_t(mi.remap));
}

if (mesh.variants.size())
{
append(json_meshes, ",\"extensions\":{\"KHR_materials_variants\":{\"mappings\":[");

for (size_t j = 0; j < mesh.variants.size(); ++j)
{
MaterialInfo& mi = materials[mesh.variants[j].material - data->materials];

assert(mi.keep);
comma(json_meshes);
append(json_meshes, "{\"material\":");
append(json_meshes, size_t(mi.remap));
append(json_meshes, ",\"variants\":[");
append(json_meshes, size_t(mesh.variants[j].variant));
append(json_meshes, "]}");
}

append(json_meshes, "]}}");
}

append(json_meshes, "}");
}

Expand Down Expand Up @@ -661,6 +681,24 @@ static void process(cgltf_data* data, const char* input_path, const char* output
append(json_extensions, "]}");
}

if (data->variants_count > 0)
{
comma(json_extensions);
append(json_extensions, "\"KHR_materials_variants\":{\"variants\":[");

for (size_t i = 0; i < data->variants_count; ++i)
{
const cgltf_material_variant& variant = data->variants[i];

comma(json_extensions);
append(json_extensions, "{\"name\":\"");
append(json_extensions, variant.name);
append(json_extensions, "\"}");
}

append(json_extensions, "]}");
}

append(json, "\"asset\":{");
append(json, "\"version\":\"2.0\",\"generator\":\"gltfpack ");
append(json, getVersion());
Expand All @@ -680,6 +718,7 @@ static void process(cgltf_data* data, const char* input_path, const char* output
{"KHR_materials_sheen", ext_sheen, false},
{"KHR_materials_volume", ext_volume, false},
{"KHR_materials_unlit", ext_unlit, false},
{"KHR_materials_variants", data->variants_count > 0, false},
{"KHR_lights_punctual", data->lights_count > 0, false},
{"KHR_texture_basisu", !json_textures.empty() && settings.texture_ktx2, true},
{"EXT_mesh_gpu_instancing", ext_instancing, true},
Expand Down
4 changes: 4 additions & 0 deletions gltf/gltfpack.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ struct Mesh
size_t targets;
std::vector<float> target_weights;
std::vector<const char*> target_names;

std::vector<cgltf_material_mapping> variants;
};

struct Track
Expand Down Expand Up @@ -255,7 +257,9 @@ void debugSimplify(const Mesh& mesh, const MaterialInfo& mi, Mesh& kinds, Mesh&
void debugMeshlets(const Mesh& mesh, Mesh& meshlets, Mesh& bounds, int max_vertices, bool scan);

bool compareMeshTargets(const Mesh& lhs, const Mesh& rhs);
bool compareMeshVariants(const Mesh& lhs, const Mesh& rhs);
bool compareMeshNodes(const Mesh& lhs, const Mesh& rhs);

void mergeMeshInstances(Mesh& mesh);
void mergeMeshes(std::vector<Mesh>& meshes, const Settings& settings);
void filterEmptyMeshes(std::vector<Mesh>& meshes);
Expand Down
10 changes: 10 additions & 0 deletions gltf/material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@ void mergeMeshMaterials(cgltf_data* data, std::vector<Mesh>& meshes, const Setti
break;
}
}

// TODO: merge variants
// TODO: clip useless variants
}
}

Expand All @@ -298,6 +301,13 @@ void markNeededMaterials(cgltf_data* data, std::vector<MaterialInfo>& materials,

mi.keep = true;
}

for (size_t j = 0; j < mesh.variants.size(); ++j)
{
MaterialInfo& mi = materials[mesh.variants[j].material - data->materials];

mi.keep = true;
}
}

// mark all named materials as kept if requested
Expand Down
20 changes: 20 additions & 0 deletions gltf/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,23 @@ bool compareMeshTargets(const Mesh& lhs, const Mesh& rhs)
return true;
}

bool compareMeshVariants(const Mesh& lhs, const Mesh& rhs)
{
if (lhs.variants.size() != rhs.variants.size())
return false;

for (size_t i = 0; i < lhs.variants.size(); ++i)
{
if (lhs.variants[i].variant != rhs.variants[i].variant)
return false;

if (lhs.variants[i].material != rhs.variants[i].material)
return false;
}

return true;
}

bool compareMeshNodes(const Mesh& lhs, const Mesh& rhs)
{
if (lhs.nodes.size() != rhs.nodes.size())
Expand Down Expand Up @@ -198,6 +215,9 @@ static bool canMergeMeshes(const Mesh& lhs, const Mesh& rhs, const Settings& set
if (!compareMeshTargets(lhs, rhs))
return false;

if (!compareMeshVariants(lhs, rhs))
return false;

if (lhs.indices.empty() != rhs.indices.empty())
return false;

Expand Down
2 changes: 2 additions & 0 deletions gltf/parsegltf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,8 @@ static void parseMeshesGltf(cgltf_data* data, std::vector<Mesh>& meshes, std::ve
result.targets = primitive.targets_count;
result.target_weights.assign(mesh.weights, mesh.weights + mesh.weights_count);
result.target_names.assign(mesh.target_names, mesh.target_names + mesh.target_names_count);

result.variants.assign(primitive.mappings, primitive.mappings + primitive.mappings_count);
}

mesh_remap[mi] = std::make_pair(remap_offset, meshes.size());
Expand Down
1 change: 1 addition & 0 deletions gltf/stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ void prepareQuantizationTexture(cgltf_data* data, std::vector<QuantizationTextur
assert(mi < bounds.size());

updateAttributeBounds(mesh, cgltf_attribute_type_texcoord, bounds[mi]);
// TODO: variants
}

for (size_t i = 0; i < result.size(); ++i)
Expand Down

0 comments on commit 4469d8f

Please sign in to comment.