web-dev-qa-db-ja.com

Three.jsアニメーションに2Dtexture \ Spriteを使用(planeGeometry)

私はhtml5とthree.jsでまったく新しいです。私はそれを少し実験してきました、そして基本的に私がしたいのはメッシュを持つことです(私が従ったチュートリアルがそれを使用したので、私はplaneGeometryを使用しています)。メッシュにはさまざまなテクスチャが表示されますが、後で変更される可能性があります。

私のコードは次のようになります。

angelTexture = THREE.ImageUtils.loadTexture("images/textures/chars/angel/angel.png");
angelTexture.offset.x = -0.75;
angelTexture.offset.y = -0.75;

angelMesh = new THREE.Mesh( new THREE.PlaneGeometry(79, 53, 79, 53), new THREE.MeshBasicMaterial( { map: angelTexture, wireframe: false } ));

angelMesh.position.x = 0;
angelMesh.position.y = 0;
scene.add(angelMesh);

問題は、オフセットするたびに、メッシュが他のすべてのスプライトを表示するのに十分な大きさに見えることです(テクスチャを、アニメーション化するためにオフセットした2Dスプライトとして使用しています)。結果は非常に悲惨であり、スプライトのスナップショットが1つだけ表示されるように、メッシュの大きさを制御する方法をまだ考えています。私の試みはすべて、メッシュとその下にあるテクスチャのサイズを変更するだけのようで、それでもすべてのスプライトが表示されます。

誰かが私を正しい方向に向けることができますか?前もって感謝します。

.。

私の友人は解決策を思いついた...私はリピートプロパティを逃した。

angelTexture = THREE.ImageUtils.loadTexture("images/textures/chars/angel/angel.png");
angelTexture.offset.x = -0.75; 
angelTexture.offset.y = -0.75;

angelTexture.repeat.x = 0.25;
angelTexture.repeat.y = 0.25;   
scene.add(angelMesh);

これが同じ問題を抱えている他の人に役立つことを願っています。

12
Spolarium7

しばらく前に同じ質問があったので、PlaneGeometryのテクスチャとしてスプライトシートを使用してアニメーション化し、定期的にテクスチャを更新する完全な例を作成しました。例を確認してください。

http://stemkoski.github.io/Three.js/Texture-Animation.html

コメント付きのソースコードで追加の説明をご覧ください。

18
Lee Stemkoski

Lee Stemkoskiへのコメントで、新しいTHREE.TextureLoader()を使用すると、複数の行を持つスプライトシートが同じように機能しないことに気づきました。

テストでは、次の4x4スプライト画像を使用しています。

Image showing quadrant highlighted for each expected tile

完全な16タイルのスプライトシートがあると仮定すると、LeeStemkoskiのTextureAnimator関数に変更はありません。

var texture = new THREE.TextureLoader().load('grid-Sprite.jpg');
var annie = new TextureAnimator(texture, 4, 4, 16, 150);

アニメーション化されたテクスチャは逆方向に実行されます。 Codepenデモ

enter image description here

だから私は私が呼ぶ自分のものを作りました???????????? THREE.SpriteSheetTexture ????????????

THREE.SpriteSheetTexture = function(imageURL, framesX, framesY, frameDelay, _endFrame) {

    var timer, frameWidth, frameHeight,
            x = 0, y = 0, count = 0, startFrame = 0, 
            endFrame = _endFrame || framesX * framesY,
            CORSProxy = 'https://cors-anywhere.herokuapp.com/',
            canvas = document.createElement('canvas'),
            ctx = canvas.getContext('2d'),
            canvasTexture = new THREE.CanvasTexture(canvas),
            img = new Image();

    img.crossOrigin = "Anonymous"
    img.onload = function(){
        canvas.width = frameWidth = img.width / framesX;
        canvas.height = frameHeight = img.height / framesY;
        timer = setInterval(nextFrame, frameDelay);
    }
    img.src = CORSProxy + imageURL;

    function nextFrame() {
        count++;

        if(count >= endFrame ) {
            count = 0;
        };

        x = (count % framesX) * frameWidth;
        y = ((count / framesX)|0) * frameHeight;

        ctx.clearRect(0, 0, frameWidth, frameHeight);
        ctx.drawImage(img, x, y, frameWidth, frameHeight, 0, 0, frameWidth, frameHeight);

        canvasTexture.needsUpdate = true;
    }

    return canvasTexture;
}

そして、それについて知っておく必要があるのはimageURLはスプライトシートのURLですframesXはx軸(左右)に沿って収まるフレームの数ですframesYはフレームの数ですy軸に沿ってフィット(上下)delayは、テクスチャが次のフレームに変更されるのを待機する時間です_endFrameはオプションです-フレームはいくつありますか(行全体を使用しない場合)

それはすべてこのように見えます

texture = new THREE.SpriteSheetTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/68819/grid-Sprite.jpg', 4, 4, 100, 16);
var material = new THREE.MeshBasicMaterial({ 
    map: texture
});
geometry = new THREE.BoxGeometry( 200, 200, 200 );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );

そして、たくさんの喜びがありました!!! Codepen Demo Here

1
Cmndo