fix: Align planar UV projection with GLTF spec to fix upside-down textures
Build and Deploy / build-and-push (push) Successful in 1m14s

This commit is contained in:
AI Bot
2026-09-22 10:11:54 +05:30
parent 585e6a2032
commit aa5de9f197
+7 -7
View File
@@ -33,7 +33,7 @@ export function reprojectUVs(geometry: THREE.BufferGeometry, mappingType: 'plana
if (mappingType === 'planar') { if (mappingType === 'planar') {
// Front planar projection // Front planar projection
u = nx; u = nx;
v = ny; v = 1.0 - ny;
} else if (mappingType === 'cylinder') { } else if (mappingType === 'cylinder') {
// Cylindrical projection // Cylindrical projection
const centeredX = x - center.x; const centeredX = x - center.x;
@@ -41,7 +41,7 @@ export function reprojectUVs(geometry: THREE.BufferGeometry, mappingType: 'plana
// atan2 returns -PI to PI. We want 0 to 1 around the cylinder. // atan2 returns -PI to PI. We want 0 to 1 around the cylinder.
let angle = Math.atan2(centeredZ, centeredX); let angle = Math.atan2(centeredZ, centeredX);
u = (angle + Math.PI) / (2 * Math.PI); u = (angle + Math.PI) / (2 * Math.PI);
v = ny; v = 1.0 - ny;
} else if (mappingType === 'sphere') { } else if (mappingType === 'sphere') {
// Spherical projection // Spherical projection
const centeredX = x - center.x; const centeredX = x - center.x;
@@ -53,7 +53,7 @@ export function reprojectUVs(geometry: THREE.BufferGeometry, mappingType: 'plana
let theta = Math.atan2(centeredZ, centeredX); // -PI to PI let theta = Math.atan2(centeredZ, centeredX); // -PI to PI
u = (theta + Math.PI) / (2 * Math.PI); u = (theta + Math.PI) / (2 * Math.PI);
v = 1.0 - (phi / Math.PI); v = phi / Math.PI; // 0 at top, 1 at bottom
} else if (mappingType === 'box') { } else if (mappingType === 'box') {
// Simple box projection (pick dominant axis based on normal) // Simple box projection (pick dominant axis based on normal)
// This requires normals // This requires normals
@@ -65,11 +65,11 @@ export function reprojectUVs(geometry: THREE.BufferGeometry, mappingType: 'plana
} }
const ax = Math.abs(normX), ay = Math.abs(normY), az = Math.abs(normZ); const ax = Math.abs(normX), ay = Math.abs(normY), az = Math.abs(normZ);
if (ax > ay && ax > az) { if (ax > ay && ax > az) {
u = nz; v = ny; u = nz; v = 1.0 - ny;
} else if (ay > ax && ay > az) { } else if (ay > ax && ay > az) {
u = nx; v = nz; u = nx; v = 1.0 - nz;
} else { } else {
u = nx; v = ny; u = nx; v = 1.0 - ny;
} }
} }
@@ -128,7 +128,7 @@ export function bakeTextureToNewUVs(
vOldUV = uv2; vOldUV = uv2;
float finalX = mix(uv.x * 2.0 - 1.0, 1.0 - uv.x * 2.0, uFlipX); float finalX = mix(uv.x * 2.0 - 1.0, 1.0 - uv.x * 2.0, uFlipX);
float finalY = mix(uv.y * 2.0 - 1.0, 1.0 - uv.y * 2.0, uFlipY); float finalY = mix(1.0 - uv.y * 2.0, uv.y * 2.0 - 1.0, uFlipY);
gl_Position = vec4(finalX, finalY, 0.0, 1.0); gl_Position = vec4(finalX, finalY, 0.0, 1.0);
} }