Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion extern/cgltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ typedef enum cgltf_component_type
cgltf_component_type_r_16u, /* UNSIGNED_SHORT */
cgltf_component_type_r_32u, /* UNSIGNED_INT */
cgltf_component_type_r_32f, /* FLOAT */
cgltf_component_type_r_16f, /* HALF_FLOAT */
cgltf_component_type_max_enum
} cgltf_component_type;

Expand Down Expand Up @@ -4382,7 +4383,7 @@ static int cgltf_parse_json_diffuse_transmission(cgltf_options* options, jsmntok
// Defaults
cgltf_fill_float_array(out_diff_transmission->diffuse_transmission_color_factor, 3, 1.0f);
out_diff_transmission->diffuse_transmission_factor = 0.f;

for (int j = 0; j < size; ++j)
{
CGLTF_CHECK_KEY(tokens[i]);
Expand Down
2 changes: 2 additions & 0 deletions gltf/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ gltfpack supports most Khronos extensions and some multi-vendor extensions in th
- KHR_materials_variants
- KHR_materials_volume
- KHR_mesh_quantization
- KHR_accessor_float16
- KHR_meshopt_compression
- KHR_texture_basisu
- KHR_texture_transform
Expand All @@ -93,6 +94,7 @@ gltfpack supports most Khronos extensions and some multi-vendor extensions in th
Even if the source file does not use extensions, gltfpack may use some extensions in the output file either by default or when certain options are used:

- KHR_mesh_quantization (used by default unless disabled via `-noq`)
- KHR_accessor_float16 (used when requested via `-vph` or `-vth`)
- KHR_meshopt_compression (used when requested via `-ce khr` or `-cz`)
- KHR_texture_transform (used by default when textures are present, unless disabled via `-noq` or `-vtf`)
- KHR_texture_basisu (used when requested via `-tc` or `-tu`)
Expand Down
13 changes: 13 additions & 0 deletions gltf/gltfpack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,7 @@ static size_t process(cgltf_data* data, const char* input_path, const char* outp

const ExtensionInfo extensions[] = {
{"KHR_mesh_quantization", settings.quantize, true},
{"KHR_accessor_float16", settings.quantize && (settings.pos_half || settings.tex_half), true},
{meshopt_ext, settings.compress, !settings.fallback},
{"KHR_texture_transform", (settings.quantize && !settings.tex_float && !json_textures.empty()) || ext_texture_transform, false},
{"KHR_materials_pbrSpecularGlossiness", ext_pbr_specular_glossiness, false},
Expand Down Expand Up @@ -1338,10 +1339,20 @@ int main(int argc, char** argv)
{
settings.pos_float = true;
}
else if (strcmp(arg, "-vph") == 0)
{
settings.pos_float = true;
settings.pos_half = true;
}
else if (strcmp(arg, "-vtf") == 0)
{
settings.tex_float = true;
}
else if (strcmp(arg, "-vth") == 0)
{
settings.tex_float = true;
settings.tex_half = true;
}
else if (strcmp(arg, "-vnf") == 0)
{
settings.nrm_float = true;
Expand Down Expand Up @@ -1667,8 +1678,10 @@ int main(int argc, char** argv)
fprintf(stderr, "\t-vpi: use integer attributes for positions (default)\n");
fprintf(stderr, "\t-vpn: use normalized attributes for positions\n");
fprintf(stderr, "\t-vpf: use floating point attributes for positions\n");
fprintf(stderr, "\t-vph: use half precision attributes for positions\n");
fprintf(stderr, "\nVertex attributes:\n");
fprintf(stderr, "\t-vtf: use floating point attributes for texture coordinates\n");
fprintf(stderr, "\t-vth: use half precision attributes for texture coordinates\n");
fprintf(stderr, "\t-vnf: use floating point attributes for normals\n");
fprintf(stderr, "\t-vi: use interleaved vertex attributes (reduces compression efficiency)\n");
fprintf(stderr, "\t-kv: keep source vertex attributes even if they aren't used\n");
Expand Down
2 changes: 2 additions & 0 deletions gltf/gltfpack.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ struct Settings

bool pos_normalized;
bool pos_float;
bool pos_half;
bool tex_float;
bool tex_half;
bool nrm_float;

int trn_bits;
Expand Down
49 changes: 48 additions & 1 deletion gltf/stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,19 @@ QuantizationPosition prepareQuantizationPosition(const std::vector<Mesh>& meshes
fprintf(stderr, "Warning: position data has significant error (%.0f%%); consider using floating-point quantization (-vpf) or more bits (-vp N)\n", max_rel_error * 100);
}

if (b.isValid() && settings.quantize && settings.pos_half)
{
float amax = 0;
for (int k = 0; k < 3; ++k)
{
amax = std::max(amax, fabsf(b.min.f[0]));
amax = std::max(amax, fabsf(b.max.f[0]));
}

if (amax > 65500)
fprintf(stderr, "Warning: position data can't be represented by half-precision floating point; consider using floating-point quantization (-vpf)\n");
}

result.node_scale = result.scale / float((1 << result.bits) - 1) * (result.normalized ? 65535.f : 1.f);

return result;
Expand Down Expand Up @@ -299,7 +312,15 @@ void getPositionBounds(float min[3], float max[3], const Stream& stream, const Q

if (settings.quantize)
{
if (settings.pos_float)
if (settings.pos_half)
{
for (int k = 0; k < 3; ++k)
{
min[k] = meshopt_dequantizeHalf(meshopt_quantizeHalf(min[k]));
max[k] = meshopt_dequantizeHalf(meshopt_quantizeHalf(max[k]));
}
}
else if (settings.pos_float)
{
for (int k = 0; k < 3; ++k)
{
Expand Down Expand Up @@ -466,13 +487,36 @@ static StreamFormat writeVertexStreamFloat(std::string& bin, const Stream& strea
return format;
}

static StreamFormat writeVertexStreamHalf(std::string& bin, const Stream& stream, cgltf_type type, int components, size_t stride)
{
assert(components >= 1 && components <= 4);
assert(stride >= sizeof(uint16_t) * components);

for (size_t i = 0; i < stream.data.size(); ++i)
{
const Attr& a = stream.data[i];

uint16_t v[4] = {};
for (int k = 0; k < components; ++k)
v[k] = meshopt_quantizeHalf(a.f[k]);

bin.append(reinterpret_cast<const char*>(v), stride);
}

StreamFormat format = {type, cgltf_component_type_r_16f, false, stride};
return format;
}

StreamFormat writeVertexStream(std::string& bin, const Stream& stream, const QuantizationPosition& qp, const QuantizationTexture& qt, const Settings& settings, bool filters)
{
if (stream.type == cgltf_attribute_type_position)
{
if (!settings.quantize)
return writeVertexStreamRaw(bin, stream, cgltf_type_vec3, 3);

if (settings.pos_half)
return writeVertexStreamHalf(bin, stream, cgltf_type_vec3, 3, sizeof(uint16_t) * 4);

if (settings.pos_float)
return writeVertexStreamFloat(bin, stream, cgltf_type_vec3, 3, settings.compress && filters, qp.bits,
settings.compressmore ? meshopt_EncodeExpSharedComponent : meshopt_EncodeExpSeparate);
Expand Down Expand Up @@ -552,6 +596,9 @@ StreamFormat writeVertexStream(std::string& bin, const Stream& stream, const Qua
if (!settings.quantize)
return writeVertexStreamRaw(bin, stream, cgltf_type_vec2, 2);

if (settings.tex_half)
return writeVertexStreamHalf(bin, stream, cgltf_type_vec2, 2, sizeof(uint16_t) * 2);

// expand the encoded range to ensure it covers [0..1) interval
// this can slightly reduce precision but we should not need more precision inside 0..1, and this significantly improves compressed size when using encodeExpOne
if (settings.tex_float)
Expand Down
2 changes: 2 additions & 0 deletions gltf/write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ static const char* componentType(cgltf_component_type type)
return "5125";
case cgltf_component_type_r_32f:
return "5126";
case cgltf_component_type_r_16f:
return "5131";
default:
return "0";
}
Expand Down