EsotericSoftware / spine-runtimes

2D skeletal animation runtimes for Spine.
http://esotericsoftware.com/
Other
4.42k stars 2.92k forks source link

[spine-pixi] I have set the texture's scale filter mode to NEAREST, but the effect remains LINEAR. I also tried `spineTexture.setFilters(spine.TextureFilter.Nearest, spine.TextureFilter.Nearest)`, but it still has no effect. Could you please advise? #2610

Closed yxdtg closed 3 months ago

yxdtg commented 3 months ago

I have set the texture's scale filter mode to NEAREST, but the effect remains LINEAR. I also tried spineTexture.setFilters(spine.TextureFilter.Nearest, spine.TextureFilter.Nearest), but it still has no effect. Could you please advise?

import * as PIXI from "pixi.js";
import * as spine from "@esotericsoftware/spine-pixi";

function parseSkeletonData(skeletonData: Uint8Array, atlasData: spine.TextureAtlas, textures: PIXI.Texture[], options?: spine.ISpineOptions): spine.SkeletonData {
    let skeleton: spine.SkeletonData = null!;

    atlasData.pages.forEach((page, index) => {
        const texture = textures[index];
        if (texture) {
            const spineTexture = spine.SpineTexture.from(texture.baseTexture);
            // spineTexture.setFilters(spine.TextureFilter.Nearest, spine.TextureFilter.Nearest);
            page.setTexture(spineTexture);
        } else {
            console.warn(`Texture for page ${page.name} not found in provided images.`);
        }
    });

    const attachmentLoader = new spine.AtlasAttachmentLoader(atlasData);
    let parser = skeletonData instanceof Uint8Array ? new spine.SkeletonBinary(attachmentLoader) : new spine.SkeletonJson(attachmentLoader);

    parser.scale = options?.scale ?? 1;
    skeleton = parser.readSkeletonData(skeletonData);

    return skeleton;
}

const urls = ["xxx.json", "xxx.atlas", "xxx.png"];

const spineData = await PIXI.Assets.load(urls[0]);
const atlasData = await PIXI.Assets.load(urls[1]);
const texture: PIXI.Texture = await PIXI.Assets.load(urls[2]);
texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;

const skeletonData = parseSkeletonData(spineData, atlasData, [texture]);
const spineObj = new spine.Spine(skeletonData);
// ...
davidetan commented 3 months ago

Hello, you were very unfortunate because in both of your attempts, the filter change were overwritten by page.setTexture.

page.setTexture invokes spineTexture.setFilters by using the filter set on the spineTexture (by default Nearest).

If you swapped these two lines:

spineTexture.setFilters(spine.TextureFilter.Nearest, spine.TextureFilter.Nearest);
page.setTexture(spineTexture);

Your code would have worked.

If you want to make Nearest the default one, just change the two lines above like this:

page.minFilter = spine.TextureFilter.Nearest;
page.setTexture(spineTexture);

One additional thing. By default the page filter is Nearest. However, this value is set durint the txt atlas parsing. If you open your atlas, I'm sure that your atlas pages has the following line:

filter:Linear,Linear

During the atlas parsing this set the minFilter and magFilter to Linear (magFilter is not used by pixi). So, you could just change that.