贴图上下颠倒,字全是反的
同一张地面标牌贴图,用 TextureLoader 加载是正的,换成 canvas 或二进制数据生成之后就倒过来了。
现象
贴图内容整体上下翻转,文字倒置,图像底部跑到顶部。
只有部分材质出问题:从 glTF 加载的模型正常,自己用
DataTexture 生成的那张贴图是反的。
原因
WebGL 的纹理坐标原点在左下角,而图片像素原点在左上角,所以需要一次 Y 轴翻转。 three.js 对不同来源的默认值不一样:
| 纹理来源 | flipY 默认值 | 结果 |
|---|---|---|
TextureLoader 加载的图片 | true | 正常 |
CanvasTexture | true | 正常 |
DataTexture | false | 上下颠倒 |
| glTF 内嵌纹理 | false | 按规范正常 |
把 DataTexture 当成普通图片纹理使用,就会拿到反图;
反过来给 glTF 的纹理手动设 flipY = true,会把本来正确的贴图弄反。
排查过程
逐张打印纹理来源与 flipY,对照材质:
mesh.material.map && console.log({
name: mesh.material.map.name,
flipY: mesh.material.map.flipY,
colorSpace: mesh.material.map.colorSpace,
imageHeight: mesh.material.map.image.height
});
解决方案
数据纹理按图片方式使用时,把 flipY 改成 true,
并记得置 needsUpdate:
var tex = new THREE.DataTexture(bytes, width, height, THREE.RGBAFormat);
tex.flipY = true;
tex.colorSpace = THREE.SRGBColorSpace;
tex.needsUpdate = true;
不想改纹理,也可以改几何的 UV。把 V 坐标取反,效果与翻转纹理一样, 适合只对某一块网格做修正:
var uv = geometry.attributes.uv;
for (var i = 0; i < uv.count; i++) {
uv.setY(i, 1 - uv.getY(i));
}
uv.needsUpdate = true;
如果是 glTF 模型贴图反了,先怀疑导出环节把 UV 写反了,
不要在 three.js 里硬改 flipY,否则其他模型又会对不上:
// 仅针对单个材质,确认导出坐标系数 flip 之后再改
material.map.flipY = false;
material.map.needsUpdate = true;
验证
在地面放一个有文字的标牌,从正上方俯视,文字应为正读方向;
把 flipY 改回原值,画面应立刻倒置,说明该参数就是控制点。
同一张贴图在 TextureLoader 与 DataTexture 两种路径下显示一致。
判断方向的小技巧:贴一张左上角带明显色块的测试图。 色块出现在左下角,就是少了一次 Y 翻转;在同一位置重复出现,则是 UV 本身有问题。
经纬志(2026)。《贴图上下颠倒,字全是反的》。https://www.jingweizhi.com/cookbook/three-texture-flipY.html(访问日期 2026-11-03)。