Использование разных частиц в Godot 3. Без использования эффектов постобработки.

Ссылки:

Запустить WebGL2 и скачать другие версии ссылка на itch.io.

Исходный код на github.

Статья разбита на разделы:

  1. Сглаживание мелких частиц, разные способы.

  2. Много шаров - частиц без потери производительности. И 3d-проекция в шейдере.

  3. Система отпечатков Screen space decals.

  4. Прочее.


1. Сглаживание частиц

Использую плоский объект размером в 2 или 4 раза больше чем отображаемая графика, самая критичная графика по центру текстуры, выглядит так, слева в 2 раза больше справа в 4 раза:

И черное становится прозрачным.

Идея в том чтобы иметь хотяб 1 пиксель вокруг основной линии при даже самых маленьких углах поворота и удалении от объекта. Я использую 4-х кратный отступ на самом дальнем объекте:

Код шейдера particlelineAAbase.shader включает три версии для теста - без фильтрации, с процедурной фильтрацией используя dFd* функцию, и используя текстуру, порядок слева на право:


2. Проекция трехмерных частиц на плоскость

Использую intersection и projection логику в фрагментном шейдере.

Идея в том что - отобразить 1000 трехмерных шаров-частиц для видеокарты(GPU) стоит слишком дорого, и 1000 трехмерных шаров-частиц у меня уже нагружают GPU на 100%. Когда рендеринг 1000 кругов(не шаров) использует меньше 25% GPU.

И поворачивая плоский круг или квадрат относительно камеры можно иметь полноценный шар-частицу:

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

Исходный код шейдера шара particle_cloud_base.shader и код шейдера куба и линии.

Для шара оригинал кода взят из iquilezles.org.


3. Система отпечатков Screen space decals

Использую код шейдера из Screen-Space-Decals, мои модификации:

  1. Поворот относительно позиции, по нормали к поверхности при установке.

  2. Затухание на краях куба с dacal.

  3. Логика Material-ID для того чтобы Decals оставались только на выбранной поверхности не затрагивая другие объекты рядом.

Работает так:

Про логику Material-ID:

В Godot нет возможности записывать дополнительную информацию в основном render-pass, информацию о типе материала. Поэтому я использую отдельный Viewport в котором есть только статическая сцена:

Красный канал для material-ID синий для значения глубины(depth). Глубина(depth) используется чтобы вырезать объекты. Логика выглядит так, на скриншоте частицы и персонаж не существуют на Material-ID Viewport и вырезаются по depth:

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


4. Прочее

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

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

В качестве оригинала такой логики я использовал этот шейдер Garden Fireworks - @P_Malin.

Шейдер для картинки загрузки - мой старый шейдер.

Анимация форм функций - моя старая демка. (старая версия так и не заработала в WebGL,по прежнему работает только в браузере на Linux)

Логика - 360 линий поворачиваются на 1 градус каждая и вращаются вокруг центральной оси, каждая линия имеет форму одной из функций. Выглядит также как в оригинальной демке:

Баги:

В ходе написания этих шейдеров нашел несколько багов в драйверах Nvidia:

Краш компилятора, баг с матрицами в Vetrex шейдере, также запуская некоторые шейдеры в Vulkan там тоже есть баг в драйвере.

Лицензия и используемые материалы:

  1. Все 3d модели взяты со sketchfab и имеют CC-non comercial лицензию.

  2. Музыка взята с сайта patrickdearteaga.com

  3. Весь мой код и все шейдеры имеют лицензию MIT license.

Ссылка на список используемых ресурсов.

Спасибо за чтение этой статьи.