41

THREE.js OBJ ローダーを使用してモデルをシーンにインポートする作業を行っています。

MeshNormalMaterial をそれに割り当てると、うまく表示されるので、ジオメトリをうまくインポートできることはわかっています。ただし、UV 座標を必要とするものを使用すると、次のエラーが表示されます。

[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1 

これは、読み込まれた OBJ に UV 座標がないためだとわかっていますが、必要なテクスチャ座標を生成する方法があるかどうか疑問に思っていました。私が試してみました

material.needsUpdate = true;
geometry.uvsNeedUpdate = true;
geometry.buffersNeedUpdate = true;

...しかし、役に立たない。

three.js を使用して UV テクスチャを自動的に生成する方法はありますか? または座標を自分で割り当てる必要がありますか?

4

5 に答える 5

19

ここでの他の回答は非常に役立ちましたが、ほとんどが平らな表面を持つ形状のすべての側面に繰り返しパターン テクスチャを適用するという私の要件には完全には適合しませんでした。問題は、x および y コンポーネントのみを u および v として使用すると、垂直面で奇妙に引き伸ばされたテクスチャになることです。

以下の私のソリューションでは、表面法線を使用して、どの 2 つのコンポーネント (x、y、z) を u と v にマッピングするかを選択しています。

function assignUVs(geometry) {

    geometry.faceVertexUvs[0] = [];

    geometry.faces.forEach(function(face) {

        var components = ['x', 'y', 'z'].sort(function(a, b) {
            return Math.abs(face.normal[a]) > Math.abs(face.normal[b]);
        });

        var v1 = geometry.vertices[face.a];
        var v2 = geometry.vertices[face.b];
        var v3 = geometry.vertices[face.c];

        geometry.faceVertexUvs[0].push([
            new THREE.Vector2(v1[components[0]], v1[components[1]]),
            new THREE.Vector2(v2[components[0]], v2[components[1]]),
            new THREE.Vector2(v3[components[0]], v3[components[1]])
        ]);

    });

    geometry.uvsNeedUpdate = true;
}

この関数は、UV をオブジェクトのサイズに正規化しません。これは、同じシーン内の異なるサイズのオブジェクトに同じテクスチャを適用する場合に効果的です。ただし、ワールド座標系のサイズによっては、おそらくテクスチャもスケーリングして繰り返す必要があります。

texture.repeat.set(0.1, 0.1);
texture.wrapS = texture.wrapT = THREE.MirroredRepeatWrapping;
于 2014-12-05T14:20:29.277 に答える