のぐそんブログ

暗いおじさんがシコシコ書くブログです。

UVマッピングについて

UVとはポリゴンにテクスチャを貼るためのテクスチャの座標のことです。 UV座標はX、YのVector2(2次元)の情報となります。

主にテクスチャの特定の位置を表示したい場合などに使用します。

試してみる

まずは普通にテクスチャを貼ってみます。

テクスチャ

結果

UVマッピングしてみる

四角形の場合は6面あるので、ポリゴンがが6x2で12個あります。 それぞれのポリゴンに対して、テクスチャのどの位置を表示するか指定していきます。

UV座標を指定する場合のポイントは以下の2つです。

  • テクスチャ座標の原点は左下になる。
  • 座標は%指定する。

上記の範囲のテクスチャを貼る場合は、下記のように指定します。

let textuerLoader = new THREE.TextureLoader();
let mat = new THREE.MeshPhongMaterial();
let geom = new THREE.BoxGeometry(3, 3, 3);

for (let i = 0, j = geom.faceVertexUvs[0].length; i < j; i++) {
    let uv;
    if (i % 2 === 0) {
        uv = [
            new THREE.Vector2(0, 0.5),
            new THREE.Vector2(0, 0),
            new THREE.Vector2(0.5, 0.5)
        ];
    } else {
        uv = [
            new THREE.Vector2(0, 0),
            new THREE.Vector2(0.5, 0),
            new THREE.Vector2(0.5, 0.5)
        ];
    }


    geom.faceVertexUvs[0][i] = uv;
}

let textuer = textuerLoader.load('images/tx.png');
mat.map = textuer;

let mesh = new THREE.Mesh(geom, mat);

scene.add(mesh);

ここでよくわからなかったのが、偶数番号のポリゴンに対してUV座標を指定する際に、座標の指定を反時計回りに指定しないと上手く表示することができませんでした。 頂点のインデックスと関係があるのかな。。。

テクスチャをリピートする

テクスチャをどのようにリピートするかを設定します。 デフォルトはTHREE.ClampToEdgeWrappingが設定されており、テクスチャはリピートされません。

それではX、Y軸ともに2回テクスチャをリピートしてみようと思います。

let textuerLoader = new THREE.TextureLoader();

let mat = new THREE.MeshPhongMaterial();
let geom = new THREE.BoxGeometry(3, 3, 3);


let textuer = textuerLoader.load('images/tx.png');
mat.map = textuer;

mat.map.wrapS = THREE.RepeatWrapping;
mat.map.wrapT = THREE.RepeatWrapping;
mat.map.repeat.set(2, 2);

let mesh = new THREE.Mesh(geom, mat);

scene.add(mesh);

wrapSプロパティはX軸に沿ってテクスチャがどのように振る舞ってほしかを指定します。 wrapTプロパティはY軸に沿ってテクスチャがどのように振る舞ってほしかを指定します。

THREE.RepeatWrappingはテクスチャ全体が繰り返されます。

THREE.RepeatWrappingはテクスチャが繰り返される度に反転します。 テクスチャの境目を滑らかにする場合などに使用します。

まとめ

UV座標の指定が難しかったです。 テクスチャにはcanvasやvideoも使用できるのでそのあたりもまとめて見ようと思います。