如何在SKTextureAtlas中使用SKTextureFilteringNearest?

9

我似乎在使用SKTextureAtlas和最近邻过滤纹理时遇到了问题。当我在没有SKTextureAtlas的情况下使用最近邻过滤时,它可以正常工作,但是当我使用SKTextureAtlas时,所有东西都会变成线性过滤。

没有SKTextureAtlas的代码和结果:

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

应该生成最近邻过滤并确实执行了 enter image description here

使用SKTextureAtlas的代码和结果:

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

应该使用最近邻过滤,但没有 enter image description here

有什么建议吗?


1
尝试使用未指定大小的spriteNodeWithTexture:,这会有什么不同吗?对我来说,最近的图集纹理过滤器有效,但我还没有尝试在初始化时更改精灵矩形。您仍然可以通过xScale/yScale在创建后缩放精灵。 - CodeSmile
好的,我尝试了那个,但是结果还是一样的 :( - Nico Cvitak
我尝试了您的方式但是没有成功。不过,我在init方法之后设置了大小,使用了[node setSize:];这个方法,然后就可以正常工作了。 - John Riselvato
我正在使用一个64x64的纹理,并且我有一个名为GrassNode的对象,它继承自SKSpriteNode,最初我在其中包含了大小和比例代码,但失败了。现在当我在场景中声明GrassNode并使用[grass setSize:CGSizeMake(1,1)];时,它仍然失败。你能描述一下你的布局,也许我可以弄清楚问题所在。 - Nico Cvitak
如果最终发现我的问题没有实际解决方案,我可能会将纹理升级,以便在更高的分辨率下保持清晰。 - Nico Cvitak
3个回答

4

我一直在苦苦挣扎着同样的问题。

似乎当你为来自SKTextureAtlas的SKTexture设置过滤模式时,它会将该图集中的所有内容的过滤模式都设置为相同。

最终我通过创建两个SKTextureAtlas(AtlasLinear和AtlasNearest)来解决这个问题。一个用于我的普通艺术作品,另一个用于像素艺术。这个方法非常有效。

然而,对于非常小的图集,有时会出现奇怪的小像素错误。如果出现这种情况,向你的像素艺术图集添加一些大的白色块状png文件实际上是有帮助的。

祝你好运。


1
这不是同一个纹理集的两个不同实例。实际上,这是两个物理上不同的文件夹(pixelArt.atlas和normalTextures.atlas)。当我加载它们时,我会设置它们的过滤模式,并且它会影响所有使用其中纹理的精灵。 - Theis Egeberg

3
这确实是一个奇怪的问题。在我看来,似乎缺少一个API:[SKTextureAtlas atlasNamed:atlasName withFilteringMode:filteringMode] 目前暂时没有这样的API,因此我使用以下方法:
-(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;
}

1
我设法解决了程序中的这个问题。我发现,即使从所有纹理贴图中加载的所有纹理都设置为SKTextureFilteringNearest,如果纹理贴图被实例化多次,则纹理将使用线性滤波呈现。最终我做的是通过单例提供我的纹理贴图,并确保所有纹理加载时过滤器设置为SKTextureFilteringNearest,这样就可以完美解决问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接