Three.js Использование 2D-текстуры\спрайт для анимации (planeGeometry)

Я новичок в html5 и three.js. Я немного экспериментировал с этим, и в основном то, что я хочу сделать, это иметь Mesh (я использую planeGeometry, так как учебник, который я использовал, использовал). В Mesh отображаются различные текстуры, которые могут впоследствии измениться.

Вот как выглядит мой код:

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);

Проблема в том, что всякий раз, когда я смещаюсь, Mesh кажется достаточно большим, чтобы показать все другие спрайты (я использую текстуру как 2D-спрайт, который я компенсировал, чтобы анимировать его). Результат довольно катастрофический, и я все еще выясняю, как контролировать, насколько велика Mesh, чтобы он показывал только один снимок Sprite. Все мои попытки, похоже, только изменяют размер сетки, а также лежащую в основе текстуры и все еще показывают все спрайты.

Может ли кто-нибудь указать мне в правильном направлении? Спасибо заранее.

...

Мой друг придумал решение... Я пропустил свойство повтора.

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);

Надеюсь, это поможет другим, имеющим ту же проблему.

Ответ 1

У меня был тот же вопрос некоторое время назад, и поэтому я написал полный пример анимации с использованием спрайта в качестве текстуры для PlaneGeometry, а затем для обновления текстуры через регулярные промежутки времени - посмотрите пример в

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

и просмотрите исходный код комментария для дополнительного объяснения.

Ответ 2

В своем комментарии к Ли Стемкоски я отметил, что спрайт-листы, содержащие более одной строки, не работают одинаково при использовании более новой THREE.TextureLoader().

Я использую следующее изображение спрайта 4x4 в своих тестах.

Image showing quadrant highlighted for each expected tile

Без изменения функции Ли Стемкоски TextureAnimator, при условии, что у вас есть полная таблица спрайтов из 16 плиток.

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

Анимированная текстура работает в обратном направлении. Codepen Demo

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 вашего spritesheet framesX, сколько кадров подходят вдоль оси х (левая и правая) framesY, сколько кадров подходят вдоль оси у (вверх и вниз) 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 Демо Здесь