Как применить полноэкранный SKEffectNode для постобработки в SpriteKit

Я пробую SpriteKit со следующей настройкой:

  1. SKScene с двумя дочерними узлами, используемыми просто для группировки других узлов: переднего плана и фона.
  2. На данный момент фон действительно пуст, но в конечном итоге будет содержать какой-то фоновый спрайт / слои.
  3. foreground — это SKEffectNode, и всякий раз, когда пользователь нажимает на экран, к нему добавляется новый экземпляр подкласса SKnode, который представляет игровой элемент.
  4. Этот подкласс SKNode в основном создает 3 SKShapeNodes и две метки: внешнюю окружность, внутреннюю окружность, 2 метки и окружность внутренней четверти. Окружность внутренней четверти имеет SKAction, который заставляет ее вечно вращаться вокруг своего начала/центра.

Теперь вот проблема, пока передний план не имеет никакого CIFilter или имеет shouldEnableEffects = NO, все в порядке. То есть я могу нажать на экран, и мои игровые элементы будут созданы и добавлены в основную сцену. Но в ту минуту, когда я пытаюсь добавить CGaussianBlur или CIBloom на передний план, я замечаю две вещи:

  1. Частота кадров падает примерно до 2 кадров в секунду. Имейте в виду, это происходит даже при наличии всего 6 узлов в сцене.
  2. Эффект, кажется, постоянно обрезает его содержимое или регулирует его рамку. То есть, если у меня есть один узел, эффект «полноэкранного режима», похоже, пытается постоянно обрезать или регулировать его границы до минимальной площади, необходимой для хранения всех узлов. Это для одного узла:

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

И это для 2 узлов:

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

В OpenGL ES 2 можно было бы выполнить пост-размытие/цветение, в основном визуализируя весь буфер кадра (все объекты) в текстуру, затем выполняя по крайней мере еще один проход для размытия и т. д. на этой текстуре, а затем либо представляя это в буфере кадра, прикрепленном к отобразите или скомпонуйте его с исходным рендерингом обратно в буфер кадра. Я ожидаю, что SKEffectNode будет работать аналогичным образом. Однако обрезка и низкая производительность заставляют меня думать, что я мог использовать узел эффекта неправильно. Есть предположения?


person SaldaVonSchwartz    schedule 21.09.2013    source источник


Ответы (1)


Насколько я могу судить, это ошибка, когда SKEffectNode пытается применить фильтр к дочерним узлам SKShapeNode. Я поиграл с этим и добился ваших результатов, но когда я заменил SKShapeNodes на SKSpriteNodes (используя простой круг png), обрезка больше не появляется. Это ошибка в том, что SKEffectNode не очень хорошо обрабатывает ход SKShapeNode. Если убрать обводку (lineWidth = 0) и придать ей цвет заливки, вы увидите, что обрезки нет.

Что касается частоты кадров, то SKShapeNodes работают плохо. Выполнение переключения на SKSpriteNodes, о котором я упоминал ранее, увеличило частоту кадров с 40 до 50, когда у меня было 35 узлов на экране (iPhone 5) с примененным фильтром.

person Austin Borden    schedule 22.09.2013
comment
Теперь, когда я думаю об этом, может быть обходной путь: SKView поддерживается CEAGLLayer и даже имеет свойство -textureFromNode, которое возвращает SKTexture. Если бы я настроил свой собственный шейдер GL для размытия/цветения, я мог бы захватывать каждый кадр (через свойство или, возможно, даже касаясь самого слоя с моим собственным контекстом OpenGL), постобрабатывать его и представлять обратно либо в слое SKView. или новый CAEAGLLayer. - person SaldaVonSchwartz; 22.09.2013
comment
Можете ли вы прокомментировать, сработал ли этот обходной путь? Я пытаюсь выяснить, можете ли вы делать свои собственные эффекты постобработки с помощью Sprite Kit? - person Oscar; 07.11.2013
comment
хотелось бы увидеть какой-нибудь код для этого... не могу найти, как кто-нибудь применяет SKEffectNode для этих пост-эффектов - person Robbie; 25.01.2020