Skip to content

Commit 34421c1

Browse files
committed
gltfpack: Warn when position quantization error is significant for any mesh
When float quantization is not used, we use the same quantization settings for all meshes. This simplifies the flow as skins and materials may need to change based on the quantization grid, and in some cases eliminates micro gaps between meshes, but may result in reduced precision compared to using per-mesh grids. For now we detect this case and suggest increasing the number of bits used for positions or switching to floating-point quantization.
1 parent 4a2bbe4 commit 34421c1

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

gltf/stream.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ struct Bounds
2525
return min.f[0] <= max.f[0] && min.f[1] <= max.f[1] && min.f[2] <= max.f[2] && min.f[3] <= max.f[3];
2626
}
2727

28+
float getExtent() const
29+
{
30+
return std::max(max.f[0] - min.f[0], std::max(max.f[1] - min.f[1], max.f[2] - min.f[2]));
31+
}
32+
2833
void merge(const Bounds& other)
2934
{
3035
for (int k = 0; k < 4; ++k)
@@ -108,7 +113,20 @@ QuantizationPosition prepareQuantizationPosition(const std::vector<Mesh>& meshes
108113
result.offset[0] = b.min.f[0];
109114
result.offset[1] = b.min.f[1];
110115
result.offset[2] = b.min.f[2];
111-
result.scale = std::max(b.max.f[0] - b.min.f[0], std::max(b.max.f[1] - b.min.f[1], b.max.f[2] - b.min.f[2]));
116+
result.scale = b.getExtent();
117+
}
118+
119+
if (b.isValid() && settings.quantize && !settings.pos_float)
120+
{
121+
float error = result.scale * 0.5f / (1 << (result.bits - 1));
122+
float max_rel_error = 0;
123+
124+
for (size_t i = 0; i < meshes.size(); ++i)
125+
if (bounds[i].isValid())
126+
max_rel_error = std::max(max_rel_error, error / bounds[i].getExtent());
127+
128+
if (max_rel_error > 5e-2f)
129+
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);
112130
}
113131

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

0 commit comments

Comments
 (0)