Skip to content

Commit f5c3dc2

Browse files
committed
gltfpack: Fix UV quantization when material uses texture transforms
Because UVs are stored in a quantized form by default, we need to first apply the dequantization transform and only then apply the original texture transform. Our logic was the opposite, and only worked if quantization offset was 0 or if texture transform was offset-only. Note that this relies on the original transform being TRS; if the original transform was TSR, then applying a second non-uniform scale like so: TSR * TS would introduce skew and the resulting matrix will not be decomposable. Currently, three.js is using incorrect order (TSR), but Babylon.js and PlayCanvas correctly implement glTF specification using TRS.
1 parent 31687ce commit f5c3dc2

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

‎gltf/write.cpp‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "gltfpack.h"
33

44
#include <float.h>
5+
#include <math.h>
56
#include <stdio.h>
67
#include <stdlib.h>
78
#include <string.h>
@@ -195,8 +196,11 @@ static void writeTextureInfo(std::string& json, const cgltf_data* data, const cg
195196

196197
if (qt)
197198
{
198-
transform.offset[0] += qt->offset[0];
199-
transform.offset[1] += qt->offset[1];
199+
float rcos = cosf(transform.rotation), rsin = sinf(transform.rotation);
200+
float ox = transform.scale[0] * qt->offset[0], oy = transform.scale[1] * qt->offset[1];
201+
202+
transform.offset[0] += rcos * ox + rsin * oy;
203+
transform.offset[1] += -rsin * ox + rcos * oy;
200204
transform.scale[0] *= qt->scale[0] / float((1 << qt->bits) - 1) * (qt->normalized ? 65535.f : 1.f);
201205
transform.scale[1] *= qt->scale[1] / float((1 << qt->bits) - 1) * (qt->normalized ? 65535.f : 1.f);
202206
needs_transform = true;

0 commit comments

Comments
 (0)