Jon*_*mos 21 performance-testing ios sprite-kit texture-atlas xcasset
我正在制作一个游戏,我注意到在某些场景中,我的FPS不断下降到55-60FPS区域(使用纹理图集).这让我疯了,所以我决定把我所有的资产都放到Images.xcassets文件夹中,然后稳定60FPS.
我认为这是一个侥幸或我做错了什么,所以我决定开始一个新项目,并执行一些基准...
Apple的文档称使用纹理图集会提高应用程序性能.基本上,允许您的应用程序利用批量渲染.然而...
测试(https://github.com/JRam13/JSGlitch):
- (void)runTest
{
SKAction *spawn = [SKAction runBlock:^{
for (int i=0; i<10; i++) {
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
sprite.xScale = 0.5;
sprite.yScale = 0.5;
sprite.position = CGPointMake(0, [self randomNumberBetweenMin:0 andMax:768]);
SKAction *action = [SKAction rotateByAngle:M_PI duration:1];
[sprite runAction:[SKAction repeatActionForever:action]];
SKAction *move = [SKAction moveByX:1200 y:0 duration:2];
[sprite runAction:move];
//notice I don't remove from parent (see test2 below)
[self addChild:sprite];
}
}];
SKAction *wait = [SKAction waitForDuration:.1];
SKAction *sequence = [SKAction sequence:@[spawn,wait]];
SKAction *repeat = [SKAction repeatActionForever:sequence];
[self runAction:repeat];
}
Run Code Online (Sandbox Code Playgroud)
结果:

测试反复表明,使用xcassets的方式比FPS中的atlas对应方式更好.尽管如此,地图集确实比mcassets更好地管理内存.
有谁知道为什么这些结果表明images.xcassets的性能比地图集好?
我提出了一些假设:
更新
对于下一个测试,我继续前进,并在它离开屏幕后从父级中删除了精灵.我还使用了7种不同的图像.我们应该看到由于抽奖计数而使用地图集的巨大性能提升但......

pro*_*cal 16
首先,修改您的测试以匹配此:
for (int i=0; i<10; i++) {
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
sprite.xScale = 0.5;
sprite.yScale = 0.5;
float spawnY = arc4random() % 768;
sprite.position = CGPointMake(0, spawnY);
SKAction *action = [SKAction rotateByAngle:M_PI duration:1];
[sprite runAction:[SKAction repeatActionForever:action]];
SKAction *move = [SKAction moveByX:1200 y:0 duration:2];
// next three lines replace the runAction line for move
SKAction *remove = [SKAction removeFromParent];
SKAction *sequence = [SKAction sequence:@[move, remove]];
[sprite runAction:sequence];
[self addChild:sprite];
}
Run Code Online (Sandbox Code Playgroud)
重新运行您的测试,您应该注意到您的帧率永远不会像测试中那样恶化.您的测试基本上说明了当您从未删除节点时会发生什么,但不断创建新节点.
接下来,在设置skview时将以下行添加到ViewController:
skView.showsDrawCount = YES;
Run Code Online (Sandbox Code Playgroud)
这样您就可以通过SKTextureAtlas查看抽奖计数并正确理解您在哪里获得性能提升.
现在,不是只有一个图像,而是每次创建节点时通过选择随机的一个图像来收集3个图像并修改测试,您可以这样做:
NSArray *imageNames = @[@"image-0", @"image-1", @"image-2"];
NSString *imageName = imageNames[arc4random() % imageNames.count];
Run Code Online (Sandbox Code Playgroud)
在您的代码中,每次循环时都使用该imageName创建精灵.即:
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:imageName];
Run Code Online (Sandbox Code Playgroud)
在您的SKTextureAtlas测试中,显然使用相同的imageName来创建每个精灵.
现在......重新运行测试并记下每次测试中的抽奖计数.
这应该为您提供有关SKTextureAtlas批处理渲染的实际示例.
这不是关于渲染相同的精灵图像数千次.
它是关于在同一个绘图过程中绘制许多不同的精灵图像.
获得此渲染优化可能会有一些开销,但我认为绘制计数应该是自我解释为什么在考虑所有事情时这种开销没有实际意义.
现在,你可以假设更多:)
UPDATE
正如评论中所提到的,我的帖子是揭示为什么你的测试不是对SKTextureAtlas的好处的良好测试,并且如果想要以有意义的方式分析它是有缺陷的.你的测试就像用麻痹试验测试麻疹一样.
下面是一个github项目,我将它放在一起,以确定SKTextureAtlas的适用位置,并且确实优于xcassets.
只需在您的设备上运行该项目,然后点击即可在测试之间切换.您可以告诉它何时使用SKTextureAtlas进行测试,因为绘制计数为1,帧速率为60fps.
我分离了将使用SKTextureAtlas进行优化的内容.它是一个60帧动画和1600个节点播放该动画.我偏移了它们的起始帧,以便它们不会同时在同一帧上.我也为两个测试保持一致,所以这是一个直接的比较.
有人认为使用SKTextureAtlas只会优化所有渲染,这是不准确的.通过批量渲染减少抽取计数来实现优化.因此,如果您的帧速率减慢不能通过批量渲染得到改善,那么SKTexture地图册就是错误的工具.对 ?
类似于对象池,您可以通过不经常创建和终止游戏对象来获得优化,而是从对象池中重用它们.但是,如果你不是在游戏中不断创造和杀死对象,那么合并就不会优化你的游戏.
根据我在讨论日志中描述的游戏问题,池化可能是您工作中的正确工具.
| 归档时间: |
|
| 查看次数: |
4052 次 |
| 最近记录: |