How do you use SKTextureFilteringNearest with SKTe

2020-08-22 06:47发布

问题:

I seem to be having a problem using SKTextureAtlas and nearest neighbor filtering for textures. When I used the nearest neighbor filtering without SKTextureAtlas it works fine, but everything is just changed to linear filtering when I use an SKTextureAtlas.

Code and Result Without SKTextureAtlas:

SKTexture* texture = [SKTexture textureWithImageNamed:@"grass"];
texture.filteringMode = SKTextureFilteringNearest;
SKSpriteNode* node = [SKSpriteNode spriteNodeWithTexture:texture size:CGSizeMake(512,512)];

Should Produce Nearest Neighbor Filtering & Does

Code and Result With SKTextureAtlas:

SKTextureAtlas* atlas = [SKTextureAtlas atlasNamed:@"myAtlas"];
SKTexture* texture = [atlas textureNamed:@"grass"];
texture.filteringMode = SKTextureFilteringNearest;
SKSpriteNode* node = [SKSpriteNode spriteNodeWithTexture:texture size:CGSizeMake(512,512)];

Should Produce Nearest Neighbor Filtering & DOES NOT

Any suggestions?

回答1:

I have been struggling with exactly the same problem.

It seems that when you set the filtering mode for a SKTexture coming from an SKTextureAtlas it sets the filtering mode for everything coming out of that atlas.

I ended up solving it by making two SKTextureAtlas's (AtlasLinear and AtlasNearest). One is for my normal artwork the other is for pixelart. This works as a charm.

However with very small atlasses I sometimes get weird small pixel errors. If this pops up for you, it actually helps to add some big white block png's to your pixel art atlas.

Good luck.



回答2:

This is indeed a bizarre problem. It seems to me that there is a missing API: [SKTextureAtlas atlasNamed:atlasName withFilteringMode:filteringMode]

In lieu of such an API for the time being, I use the following method:

-(SKTextureAtlas *) textureAtlasWithName:(NSString *)atlasName filteringMode:(SKTextureFilteringMode)filteringMode {

    SKTextureAtlas * result = [SKTextureAtlas atlasNamed:atlasName];

    NSArray * textureNames = [result textureNames];

    if ([textureNames count] > 0) {
        SKTexture * aTexture = [result textureNamed:[textureNames lastObject]];
        [aTexture setFilteringMode:filteringMode];

    } else {
        NSLog(@"WARNING: couldn't find any textures in the atlas %@; filtering mode set likely failed.", result);
    }

    return result;
}


回答3:

I managed to solve this problem in my program. What I have found out is that if a texture atlas is instantiated more than once, even if all texture loads from the atlases are set to SKTextureFilteringNearest, the textures are rendered with the linear filtering. What I ended up doing is provide my atlas through a singleton and made sure all textures load with filtering set to SKTextureFilteringNearest and it worked perfectly.