Хабрахабр

Про Godot, GLSL и WebGL, шейдеры используемые в мини игре

Статья разбита по такой очередности:

  • Ссылки и краткое описание.
  • Очень краткое описание игровой логики, и используемых возможностей Godot.
  • Про используемые шейдеры.
  • Еще немного про Godot, и его особенности.
  • WebGL2 работает
  • Мультиплеер

Скачать Win/Linux версии можно по ссылка на itch.io

Исходный код всей игры доступен на github-е или gitlab.

Игровой процесс:

(звука в игре нет) Минимальный, это не полноценная игра.

Раунды начинаются когда HP сферы ноль, и нет роботов в игре. Цель игры — продержаться максимальное количество раундов.

Боты также дают бонус но случайно. При уничтожении фигур появляются бонусы, раз за раунд, дают скорость анимации выстрела, урон (только по главной сфере), и высоту прыжка, по цвету синий, красно/зеленый, желтый. Персонаж игрока восстанавливает +1HP каждый новый раунд.

Используемые ресурсы:

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

(про него ниже еще напишу) Используется модуль futari-addon.

В игре две модели имеют анимации.
Движения персонажа игрока я сделал в Godot, оригинальная модель
Вторая модель это sphere-bot которая имеет качественные анимации.

Все используемые готовые сторонние модели объектов перечислены по ссылке.

Логика игры и возможности Godot:

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

Используется всего один Viewport для 3D сцены, и несколько Viewport-ов (низкого разрешения) в которых стоят ортогональные камеры для 2D-Viewport-ов (тоже низкого разрешения) в которых идет обработка Multipass/Feedback шейдеров, о них ниже.

Есть дополнительные настройки графики (Esc — Settings). Все текстуры имеют mipmap, и работают даже в браузере. Например можно сделать любое разрешение для игры, до размера 32x32 пикселя, например я поставил 320x240 разрешение в настройках, запустив игру в браузере, и включил максимальное сглаживание MSAA вот что вышло

Все источники света работают в реальном времени, их 16 штук всего.

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

Матрица поворота частиц(кусков пола), в моих шейдерах, это просто короткая запись из этой формулы,:

mat4 rotationAxisAngle( vec3 v, float angle )
{ float s = sin( angle ); float c = cos( angle ); float ic = 1.0 - c; return mat4( v.x*v.x*ic + c, v.y*v.x*ic - s*v.z, v.z*v.x*ic + s*v.y, 0.0, v.x*v.y*ic + s*v.z, v.y*v.y*ic + c, v.z*v.y*ic - s*v.x, 0.0, v.x*v.z*ic - s*v.y, v.y*v.z*ic + s*v.x, v.z*v.z*ic + c, 0.0, 0.0, 0.0, 0.0, 1.0 );
}

0,0. к примеру v=vec3(0. 0) это поворот по оси z, и angle=PI/2. подставить их и получиться нужный поворот. 0,1.

Анимация разрушаемых блоков считается физическим движком в реальном времени

Your browser does not support HTML5 video.

Физика в Godot довольно ограничена, и начинает сильно уменьшать FPS уже при десятке активных объектов, поэтому отключены все столкновения между разрушенными кусками, и другие, установлены уровни для физики, также стоит ограничение на количество одновременных разрушений, и максимальное число Ботов одновременно (шесть).

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

bot_hit.gd функция _integrate_forces и все что ей вызывается, это движения противника-бота
player_l.gd во первых функцией move_and_slide отключается бесконечная инерция, и функция process_collision отталкивает объекты.

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

Несколько дублирующихся объектов в одном, и несколько GIProbe, формы и параметры источников света-все так и задумано, сделано для обхода ограничений OpenGL или ограничений в Godot.

Панорама окружения:

В этой игре используется статическая панорама, картинка получена из этого шейдера (с1 с2 цвета, ldir положение)

vec3 sky(vec3 d, vec3 c1, vec3 c2) { vec3 ldir = normalize(vec3(0.,0.,-1.)); vec3 col = mix(c1*100., c2*100., min(abs(d.y)*2. + .5, 1.)) / 255.*.5; col *= (1. + vec3(1., .7, .3) / sqrt(length(d - ldir))*2.); //sun return clamp(col,vec3(0.),vec3(1.));
}

для получения панорамы убрать комментарий со строке 57 panorama_uv(fragCoord,ro,rd); и поставить комментарий на строку 58

Динамические панорамы для Godot в прошлых демках (ютуб и там ссылки на код) панорама облаков и панорама цикла дня/ночи с движением облаков

Если нужно конвертировать CubeMap в панораму окружения для Godot, я сделал простейший веб конвертер.

Совсем простые шейдеры:

Например spawn.shader) Шейдеры для частиц статически определяющие их позицию для анимации или без.

Your browser does not support HTML5 video.

Для дополнительного свечения вокруг объектов, не только шаров, это одна строка gglow.shader (цифры можно менять как надо)

float intensity = pow(0.122 + max(dot(NORMAL, normalize(VIEW)),0.), 010.85);

Показ текста-цифр в 3D, как я понял в Godot нет средств для этого (без создания дополнительного FBO (viewport)) поэтому простой шейдер печатающий цифры из текстуры (чтобы был mipmapping), код шейдера

Элементы UI:

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

Про модуль futari-addon:

Он работает практически также как этот шейдер для 2D-частиц на видео (смотреть с 1:41).

На видео строится 2D-SDF карта всех полигонов один раз на старте и полученная текстура просто отправляется частицам, частицы сами строят normal в текущей позиции и меняют движение.

futari-addon делает практически тоже самое, только вместо 2D карты-текстуры передаются координаты 3D сфер и плоскостей которые обрабатываются по условию в шейдере частиц, поэтому свободно можно менять их положение и другие параметры.

Плюс ветер (в моем 2D-примере ветер добавить очень просто, как еще одну текстуру с +- значениями к скорости, и частицы просто добавляют значение скорости из этой карты по своему положению).

Модуль futari-addon очень хорош, использовал его вместо создания своей системы для частиц.

Эффект щита:

Код шейдера в файле en_m.shader Частицы которым передаются координаты удара по сфере и положение игрока, и угасание используя буфер transform feedback.

Your browser does not support HTML5 video.

Щит у Ботов:


Шейдер по типу трехмерного шума sheild.shader по сути все работает благодаря функции flow оригинал тут
Задний фон определяется gl_FrontFacing, и закрашивается в более темный и зеленый, а не синий.
Реакция на удар-просто передается таймер события удара.

Your browser does not support HTML5 video.

Почти все эффекты сделаны используя эту логику.
Один из шейдеров из игры.
В качестве источника я поставил ортогональную камеру которая снимает на маленькое расстояние объекты в определенной группе (не обрабатывая всю сцену)
.

Эффект поля льда:

Шейдер указан выше, в проекте файл ice_feedback.shader, и fragment шейдер для плоскости который создает иллюзию глубины пола используя простой depth цикл:

while(current_depth < depth){ ofs -= delta; depth = textureLod(texture_depth, ofs,0.0).r; current_depth += layer_depth;
}

Your browser does not support HTML5 video.

Эффект поля частиц:

Шейдер тот-же, координата y (высота) частиц по яркости цвета буфера кадра от шейдера, цвет также по яркости цвета (шейдер частиц я не сохранял отдельно, он в проекте в объекте floor/visible_/floor3/grass/grass).

Your browser does not support HTML5 video.

Динамическая анимация флага:

Я использовал уже готовый код ссылка на оригинал. В Godot есть SoftBody для анимации ткани, но это CPU, поэтому я не использовал. Этот флаг отталкивается от трех шаров сбоку и голова персонажа четвертый шар.
Логика multipass-шейдера, как в примере выше, только с тремя осями, код multipass шейдера (1)flag.shader, шейдер рисующий флаг просто показывает текстуру с меняет геометрию плоскости (2)flag.shader.

Your browser does not support HTML5 video.

Появление фигур:

У фигур нет UV, поэтому triplanar-texture-mapping для наложения текстуры, и разрезание по треугольникам (vertex), весь код в cchess.shader

Your browser does not support HTML5 video.

Анимация hitbox-а (красная рамка) который наносит урон персонажу игрока, и след от рамки (частицы очевидно):

Your browser does not support HTML5 video.

Используется всего лишь уже указанный шейдер gglow.shader.

Для частиц используется всего две текстуры, круг и квадрат.

Мне Godot очень понравился своими возможностями. Godot очень хорош и прост (не для новичка).

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

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

Также отмечу что Godot никак не защищен от особенностей внешних факторов, это WASM в браузерах, ограничения ANGLE, сильные ограничения самих браузеров, и конечно-же десятки багов в драйверах видеокарт, это все приходится вручную обходить.

(управление заклинивает во время компиляции шейдеров и лагов FPS (например в браузере)), также другие лаги связанные с особенностями 3D-рендера в Godot, я сделал обход части из них, но они всеравно есть/могут быть. Лаги — есть большая проблема с управлением, это 100% на стороне Godot, я не исправлял это.

Ссылка на WebGL2/WASM версию. Не запускайте игру по ссылке, если у вас Windows.

Работает только в Chrome 76+ и Firefox (Linux).

Но судя по всему это баг в ANGLE, а это wontfix почти наверняка.
Багрепорт уже закрыть, и ANGLE также править никто не будет. Про Виндовс отправлен багрепорт (ссылка), если это баг браузера то гугл реагирует через 2 месяца. Значит на Windows в браузере не заработает.

По ходу этого проекта был исправлен один баг в Chrome благодаря чему заработал transform-feedback и моя прошлая демка (выше видео с панорамой дня/ночи), которая до этого не работала.

Обновлю эту часть как будет сделано. Это TODO.

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

2 с поддержкой WebRTC будет добавлена поддержка WebRTC, мультиплеер в браузере будет работать (пусть хоть только в Linux, хоть так). И как только выйдет Godot 3.

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»