Очень быстрый пиксель на экране

Моему другу пришлось рисовать мандельброта с opengl в c. Я решил сделать это в Swift.

Первый метод, который я попробовал, заключался в создании массива с данными ARGB, преобразовании его в CGImage и просмотре этого в UIImageView. Однако это было недостаточно быстро.

Теперь мне интересно, как быстрее всего нарисовать отдельные пиксели на экране. Я смотрел на Metal, но, похоже, это были в основном треугольники и 3D-вещи. Затем я пришел к шейдерам scenekit (.fsh) и подумал, что, возможно, это хорошее решение. Однако я также хочу иметь возможность увеличивать масштаб фрактала Мандельброта, и я не смог найти способ ввода переменных в свой мандельброт (моя ссылка: https://www.weheartswift.com/fractals-xcode-6/)

Не могли бы вы, ребята, рассказать/привести пример (Swift, пожалуйста) о самом быстром способе рисования отдельных пикселей или, по крайней мере, о способе рисования необработанных пикселей на экране без необходимости использовать что-то промежуточное, например, создание CGImage?


person Simon    schedule 06.04.2015    source источник
comment
Почему вы считаете, что рисование CGImage происходит медленно? Вы запускали инструменты в своем коде? Что именно вы обнаружили, когда сделали это?   -  person matt    schedule 07.04.2015
comment
Вы хотите вычислить образцы фракталов на графическом процессоре (используя шейдер OpenGL)? Или вы хотите вычислить их на процессоре (используя Swift) и просто быстро нарисовать? Вы создавали новый CGImage каждый раз, когда вычисляли пиксель, или вы создавали один CGImage после вычисления всех пикселей, или что-то среднее между ними?   -  person rob mayoff    schedule 07.04.2015
comment
@matt Это обходной путь, потому что я не смог найти более прямой способ рисования на экране, и мне также пришлось создать кучу пикселей в памяти, поэтому я предполагаю, что это действительно медленнее.   -  person Simon    schedule 08.04.2015
comment
@robmayoff Я предполагаю, что использование графического процессора намного быстрее, поэтому я бы предпочел делать это на графическом процессоре, и я также думаю, что такая задача должна выполняться на графическом процессоре. Я создал одно изображение для каждого кадра в худшем случае   -  person Simon    schedule 08.04.2015
comment
Предполагать? Вы знаете, сколько это стоит. Я бы предположил, что вычисление выполняется медленно, а отрисовка пикселей — нет.   -  person matt    schedule 08.04.2015
comment
Хорошо, допустим, я не доволен тем, как я это делаю в данный момент, потому что у меня есть ощущение, что это не лучший способ сделать это. В основном мне интересно, насколько близко я могу подобраться к setPixelXY(x, y, color)   -  person Simon    schedule 08.04.2015
comment
Вы UIView и у вас есть реализация drawRect:, или вы CALayer и у вас есть контент, или вы GLKView с фреймбуфером OpenGL. Вот как все выглядит на экране в iOS.   -  person matt    schedule 08.04.2015


Ответы (2)


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

Взгляните на этот пост в блоге, где я пишу текстуру, используя координаты частиц, переданные в функцию ядра: http://flexmonkey.blogspot.co.uk/2015/03/swift-metal-four-million-particles-on.html

person Simon Gladman    schedule 09.04.2015
comment
Вау, спасибо, это выглядит как удивительный источник дополнительных знаний :) Я углублюсь в это, когда у меня будет время! - person Simon; 09.04.2015

Если вы хотите вычислить фрактал на графическом процессоре, то это больше вопрос OpenGL (или Metal), чем вопрос Swift. Вам нужно делать более мелкие шаги:

  1. Получите сплошной цветной треугольник на экране с помощью OpenGL.
  2. Заполните экран двумя однотонными треугольниками.
  3. Залейте треугольники простым градиентом с помощью фрагментного шейдера.
  4. Заполните треугольники простой текстурой.
  5. Выполните двухэтапное рисование: рисуйте во внеэкранном буфере (с треугольниками и шейдером), затем используйте этот буфер в качестве текстуры для рисования на экране.
  6. Нарисуйте свой фрактал в закадровом буфере с помощью шейдера.

Обратите внимание, что шаг 6 может быть сложным, и вам может понадобиться помощь, но нет смысла даже начинать его, пока вы не сможете успешно выполнить шаги 1-5. Вы сможете найти множество руководств, которые помогут вам выполнить шаги 1-5, хотя вам, возможно, придется перевести их на Swift с C, C++ или Objective-C.

Страница, на которую вы ссылаетесь, полностью пропускает шаги 1-5, потому что программа просмотра сцен Xcode позаботится о них за вас. Если вы хотите написать отдельное приложение, вам нужно научиться выполнять эти шаги.

person rob mayoff    schedule 07.04.2015
comment
Итак, в конце концов я получу экран с двумя треугольниками, которые вместе заполняют весь экран и имеют один и тот же шейдер, который в сумме отображает Мандельброта? Если это так, как я должен это сделать, я попытаюсь следовать вашим инструкциям. - person Simon; 08.04.2015