threejs TextureLoader和KTX2Loader加载纹理 上下翻转问题

发布于:2025-02-27 ⋅ 阅读:(28) ⋅ 点赞:(0)

参考文章:canvas坐标系统 webgl坐标系统 uv纹理坐标系统 原点_webgl uv坐标-CSDN博客

threejs中使用TextureLoader和KTX2Loader加载相同纹理,出现了上下翻转的情况

  •  TextureLoader默认加载
let textureLoader = new THREE.TextureLoader();
textureLoader.load('./image/img.png', function (texture) {
    let material = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide })
    let plane = new THREE.PlaneGeometry(0.5, 0.5);
    let mesh = new THREE.Mesh(plane, material);
    scene.add(mesh)
});

KTX2Loader默认加载

let kTX2Loader = new KTX2Loader()
    .setTranscoderPath("./lib/three/examples/jsm/libs/basis/") // Basis解码路径
    .detectSupport(renderer);


kTX2Loader.load('./image/img.ktx2', function (texture) {
    let material = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide })

    let plane = new THREE.PlaneGeometry(0.5, 0.5);
    let mesh = new THREE.Mesh(plane, material);
    scene.add(mesh)
});

原因:主要原因是 WebGL 纹理的默认 Y 轴方向 与图片的像素存储方向不同

TextureLoader: TextureLoader默认翻转 Y 轴,按正常的方式加载纹理图像,原点位于左下角,Y 轴朝上。

KTX2Loader: KTX2Loader 默认不会翻转 Y 轴,采用的是图像原点在左上角的坐标系,因此它加载的图像会上下翻转。为了与传统的纹理坐标系统保持一致,KTX2 文件的解析通常会需要额外的转换。

解决方案:手动翻转y轴。

let kTX2Loader = new KTX2Loader()
    .setTranscoderPath("./lib/three/examples/jsm/libs/basis/") // Basis解码路径
    .detectSupport(renderer);


kTX2Loader.load('./image/img.ktx2', function (texture) {
    texture.mapping = THREE.UVMapping;  // 保证是 UV 映射
    texture.repeat.y = -1;  // 反转 Y 轴
    texture.offset.y = 1;   // 调整纹理偏移

    let material = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide })

    let plane = new THREE.PlaneGeometry(0.5, 0.5);
    let mesh = new THREE.Mesh(plane, material);
    scene.add(mesh)
});

疑问:按道理来说,设置 texture.flipY = true; 就能翻转过来,达到和TextureLoader一样的效果,但设置了并没有生效,如果有大佬知道原因,请指教