Подтвердить что ты не робот

Основные проблемы с производительностью iOS9 с помощью Sprite Kit

Я испытываю огромные проблемы с производительностью с iOS9, и я просто не могу понять, что делать. Я прочитал много сообщений - здесь и здесь, но их предлагаемые решения не помогают или не имеют большого значения.

Моя игра прошла от 60 кадров в секунду на старом iPad 2 (iOS 8.4) до < 15 кадров в секунду на новом iPad mini (iOS 9).

Я пытаюсь выработать главного виновника. Я почти уверен, что один из них - SKCropNodes. Обычно я делаю несколько SKCropNodes в моей сцене (6-18). Это никогда не было проблемой в iOS8, но, похоже, iOS9, в то время как он лучше справляется с обрезкой, также ест производительность.

Если я обрабатываю узлы обрезки как обычные SKSpriteNodes, я получаю, возможно, 5 кадров в секунду на старых устройствах и до 30 на более новом iPhone 6. У меня нет альтернативы использованию узлов обрезки, но это не может быть всей проблемой.

Я подумал, что, возможно, неправильный атлас текстуры используется, т.е. одно из гораздо большего разрешения. Однако заставить мое устройство использовать очень маленький атлас не имеет никакого значения.

Я использую Texture Packer для создания своих атласов с вариантами масштабирования для разных устройств. Я заметил, что XCAssets теперь имеет возможность добавить атлас Sprite (я не могу найти никакой документации об этом). Это не подходит для моей игры, так как я использую 100 спрайтов. Я попытался добавить свои атласы в XCAssets, но по какой-то причине он не будет использовать варианты масштабирования. Тем не менее, при низких результирующих текстурах он все еще работает ужасно.

Я попытался установить

skView.ignoresSiblingOrder = YES;

и заданы все мои значения zPosition, но все равно никакого эффекта. Я также добавил расширение .png к каждому имени изображения (первоначально проблема, которая означала, что они не будут отображаться.)

У меня есть некоторые SKEffectNodes в моих сценах, но удаление и добавление их не похоже на эффект.

Я не понимаю, как одно и то же оборудование и тот же код могут производить такие сильно разные результаты. Очевидно, Apple изменила что-то, связанное с рендерингом, оказавшим неблагоприятное воздействие. Они также, похоже, не намерены исправлять эти проблемы. Я знаю о проблемах, которые были там в течение нескольких месяцев - задолго до выхода iOS9.

Я работаю над этой игрой уже 2 года и только что выпустил ее перед iOS9. Теперь он страдает от ужасного выступления и регулярных сбоев.

Кто-нибудь понял, что именно сделал Apple, чтобы убить производительность? Если бы я знал это, я мог бы хотя бы попытаться обойти это... Спасибо.

UPDATE

Ниже приведены некоторые цифры для одной и той же сцены с абсолютным максимальным количеством узлов, которые игра будет генерироваться за один раз.

iOS 8, iPad 2, ~ 200 узлов, ~ 100 ничьих, 58,7 - 60 кадров в секунду

iOS 9, iPhone6, ~ 280 узлов, ~ 216 ничьих, около 20 кадров в секунду

Я предполагаю, что различие в количестве узлов связано с разными размерами экрана. Если я изменил сцену на iPhone 6, чтобы получить эквивалентные значения, FPS все равно около 24.

ОБНОВЛЕНИЕ 2

Используя проект Xcode-шаблона Sprite Kit и меняя космический корабль на SKCropNode, содержащий космический корабль, на iOS 8 я могу добавить 100 кораблей без проблемы с частотой кадров. На iOS 9, в том же проекте, я могу добавить около 25, прежде чем частота кадров упадет до < 30.

iOS 8 на iPad2:

введите описание изображения здесь

iOS 9 iPhone 5:

введите описание изображения здесь

С точки зрения использования текстурного атласа, как и в моем комментарии, я не могу гарантировать, что что-то будет нарисовано из того же атласа. Моя игра содержит персонализированные символы, с активами из ряда атласов (каждая из которых содержит ~ 100 текстур). Одновременно может отображаться до 9 символов. Я понимаю, что это не самая эффективная с точки зрения ничьей, но у меня никогда не было проблемы до iOS9...

Обновление 3

Я представил ошибку Apple, включая мою примерную программу. Я также воспользовался одним из моих запросов технической поддержки. Пока что ничего от Apple.

4b9b3361

Ответ 1

Похоже, что большинство проблем iOS9 рассматриваются в последней бета-версии iOS9.2 и бета-версии Xcode 7.2.

Спасибо Apple, наконец, решив проблему. Жаль, что я потратил 2 месяца на работу.

Я публиковал на форумах Apple, отправлял ошибки и общался с техником поддержки. Стыдно, что Apple ни в коем случае не давала ясности в отношении того, о чем они знали, и о том, что касается команды Sprite Kit.

Тем не менее, по крайней мере, похоже, что большинство проблем с Sprite Kit теперь разрешены, и изменение карьеры больше не требуется:]

Ответ 2

Существуют две основные проблемы.

Один из них - это радикальное снижение производительности набора Sprite от iOS 8 до iOS 9 по всем причинам, некоторые из которых вы связали, но есть и другие. Кажется, что многие аспекты рендеринга, сортировки и хранения/работы с узлами либо сломаны, либо удваиваются или утроятся их предыдущие нагрузки на CPU/GPU.

Однако есть еще одна проблема, которая еще больше усиливает усилия для решения любой из возможных проблем с производительностью. Это широко распространенный и, по-видимому, произвольный механизм ограничения частоты кадров, который наиболее часто заметен, когда он работает со скоростью 40 кадров в секунду. Но он также работает на других частотах.

На протяжении многих лет эта ограниченность была отмечена (редко), когда люди вручную используют CADisplayLink для создания игровых циклов или других механизмов, основанных на хронологии, на кадре за фрейм.

С iOS 9 это, казалось бы, автоматическое укупорение стало ужасно нежелательной "особенностью" приложений Sprite Kit, SceneKit, Metal и OpenGL ES.

В случае с SceneKit это наиболее показательно, потому что ограничение происходит независимо от выбора рендеринга - Metal или OpenGL - и, казалось бы, на всех устройствах, включая такие вещи, как новые телефоны 6S и iPad Air 2, даже с очень простым, по умолчанию шаблонные проекты.

"Renderer" - это позиция в подробной статистике SceneKit на экране, на устройстве. Это наиболее показательная характеристика процесса укупорки. Это не так, когда игра работает стабильно со скоростью 60 кадров в секунду.

При ограничении на 40 кадров в секунду, независимо от того, сколько времени требуется для выполнения других действий на экране и в логике, этот компонент поглотит все оставшееся время в игровом цикле, необходимое для поддержания сплошного покрытия в 40 кадров в секунду. Он варьируется в зависимости от времени, необходимого для других активов, всегда заставляя очевидную цель базовой ОС удерживать частоту кадров со скоростью 40 кадров в секунду.

Эта проблема в сочетании с проблемами, касающимися производительности iOS 9 Sprite Kit, означает, что в настоящее время невозможно решить все ваши проблемы. Будет очень сложно установить, когда вы нажимаете одну из этих (по-видимому) произвольных кеппов fps по сравнению с тем, что вызвало настоящую проблему.

Так же, как и в стороне, эти шапки не ограничены 40 кадрами в секунду. Я заметил их со скоростью 30 кадров в секунду, 24 кадра в секунду, 20 кадров в секунду, 15 кадров в секунду, 12 кадров в секунду и 8 кадров в секунду.

Конечно, Apple никогда не уступала и не допускала этот механизм ограничения в ОС, и не комментировала, когда/как/почему это так сильно влияет на процессы игры и рендеринга.

Моя теория, выраженная в этом сообщении (Непоследовательная частота кадров SceneKit), заключается в том, что она является частью iOS, предназначенной для ускорения использования технологии с переменной частотой кадров в ближайшее время в iPad Pro и, возможно, на других устройствах.

Было бы разумно, что 120Гц станет базовой скоростью для будущих устройств, особенно учитывая акцент на преимуществах производительности iOS, нового Apple TV и выборки на 240 Гц на экране прикосновения/пера в iPad Pro... и значительных число 120 Гц телевизоров на рынке.

Даже без технологии с переменной частотой кадров (скажем... на вашем телевизоре) скорость отображения 120 Гц означает, что фильмы с 24 кадрами в секунду могут воспроизводиться при стабильном режиме отображения кадра 5: 5: 5 - это значительно увеличивает радость/погружение, когда просматривая фильмы, почти все из которых сняты и действительно используют преимущества истинных 24 кадров в секунду для эффектов размытия и движения.

120 Гц с технологией с переменной частотой кадров или с отображением кадров 5: 5: 5 также сэкономит Apple огромные усилия с точки зрения сжатия и декомпрессии пленок по сравнению с методами раскрытия, которые в настоящее время используются на всех устройствах с максимальной частотой кадров 60 кадров в секунду.

Все предположения, но я бы предположил, что использование этих фреймов в технологиях игровых движков поможет сделать игры более энергоемкими, а также дать (в будущем) разработчикам возможность фальсифицировать блокировку своих игр в мир устройств с переменной частотой кадров. Очень жаль, что (если это так) они сделали такую ​​плохую работу или разобрали проблемы с выпуском в ОС и природу набора Sprite Kit, что привело к сценарию, в котором вы боретесь вслепую, чтобы получить хорошую, согласованные частоты кадров.

Явное молчание и кажущееся беззаботное отношение к проблемам, которые возникают в этих двух наборах проблем, - это (весьма возможно) очень сильное указание на то, как они относятся к "сообществу разработчиков игр".

И это самая большая проблема в решении самых острых и критических проблем разработки, присущих игре в рамках закрытого исходного кода, из ненужной скрытной и некоммуникативной (почти воюющей) организации.

Ответ 3

В приведенном примере я вижу один способ улучшить счетчик обращений и проверить, что обрезка node не является проблемой. Я не знаю, насколько это практично в вашей реальной игре, но это резко ограничивает ваши призывы к розыгрышу.

#import "GameScene.h"

@interface GameScene ()

@property(nonatomic, strong)SKTexture *spaceshipTexture;
@end

@implementation GameScene

-(void)didMoveToView:(SKView *)view {
    /* Setup your scene here */
    SKLabelNode *myLabel = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];

    myLabel.text = @"Hello, World!";
    myLabel.fontSize = 45;
    myLabel.position = CGPointMake(CGRectGetMidX(self.frame),
                                   CGRectGetMidY(self.frame));

    [self addChild:myLabel];

    //Create one texture to be used over an over
    SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
    sprite.xScale = 0.5;
    sprite.yScale = 0.5;

    SKCropNode *cropNode = [[SKCropNode alloc] init];
    SKSpriteNode *mask = [SKSpriteNode spriteNodeWithColor:[UIColor blackColor] size:CGSizeMake(100, 100)];
    mask.position = sprite.position;
    [cropNode setMaskNode:mask];
    [cropNode addChild:sprite];
    [self addChild:cropNode];

    //temp add to scene to create the texture than remove
    //keep pointer to texture so it can be reused
    self.spaceshipTexture = [self.view textureFromNode:cropNode];
    [cropNode removeFromParent];

}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    /* Called when a touch begins */

    for (UITouch *touch in touches) {
        CGPoint location = [touch locationInNode:self];

        //re use texture
        SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithTexture:self.spaceshipTexture];
        sprite.position = location;
        [self addChild:sprite];
    }
}

@end

Недостатком является то, что проблема остается, когда вы получаете до 120 + ish узлов на экране.

Также обратите внимание, что я создал новое приложение SpriteKit с использованием шаблона по умолчанию и удалил SKAction. К сожалению, даже шаблон Apple по умолчанию страдает огромными капли fps, когда вы получаете до 120 + узлов. Поэтому я не знаю, будет ли ответ, и ваш лучший способ действий - подать отчет об ошибке, поскольку я считаю, что он должен (и использовать, чтобы иметь возможность) обрабатывать многие на экране без снижения кадров в секунду.

Также стоит отметить, что эта ошибка возникает в проекте по умолчанию, который может быть связан...

2015-10-20 10:46:50.640 Test[2218:658384] <CAMetalLayer: 0x15fe987c0>: calling -display has no effect.

Обновление Сделав немного больше исследований, я столкнулся с этим...

https://forums.developer.apple.com/thread/14487

Похоже, что другие регистрируют ошибки для этого...

Ответ 4

Много рисунков... Вы пробовали это?

skView.ignoresSiblingOrder = YES;

Ответ 5

Используете ли вы SKLightNode? Если это так, попробуйте удалить весь свет node из вашего кода. Я сделал это, и моя игра вернулась со скоростью 60 кадров в секунду, как в iOS8.

Источник: Проблемы с производительностью SKLightNode