Горячее
Лучшее
Свежее
Подписки
Сообщества
Блоги
Эксперты
Войти
Забыли пароль?
или продолжите с
Создать аккаунт
Регистрируясь, я даю согласие на обработку данных и условия почтовых рассылок.
или
Восстановление пароля
Восстановление пароля
Получить код в Telegram
Войти с Яндекс ID Войти через VK ID
ПромокодыРаботаКурсыРекламаИгрыПополнение Steam
Пикабу Игры +1000 бесплатных онлайн игр Собирайте грибы, готовьте и общайтесь. Экономический симулятор лесной фермы

Грибники и Кланы

Симуляторы, Стратегии, Фермы

Играть

Топ прошлой недели

  • cristall75 cristall75 6 постов
  • 1506DyDyKa 1506DyDyKa 2 поста
  • Animalrescueed Animalrescueed 35 постов
Посмотреть весь топ

Лучшие посты недели

Рассылка Пикабу: отправляем самые рейтинговые материалы за 7 дней 🔥

Нажимая «Подписаться», я даю согласие на обработку данных и условия почтовых рассылок.

Спасибо, что подписались!
Пожалуйста, проверьте почту 😊

Помощь Кодекс Пикабу Команда Пикабу Моб. приложение
Правила соцсети О рекомендациях О компании
Промокоды Биг Гик Промокоды Lamoda Промокоды МВидео Промокоды Яндекс Маркет Промокоды Пятерочка Промокоды Aroma Butik Промокоды Яндекс Путешествия Промокоды Яндекс Еда Постила Футбол сегодня
0 просмотренных постов скрыто
18
TehnoMagEG
TehnoMagEG
Лига Разработчиков Видеоигр
Серия Вся наша жизнь спираль

Вся наша жизнь спираль: Итоги 2021⁠⁠

4 года назад

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


Что-же было сделано за 2021 год, и что стоит ожидать в 2022ом.


1) Проработан и почти доведен до ума модуль построения Мира (статьи из серии Синтез субатомных частиц). Тем не менее, в будущем году я продолжу работу над ним, ибо необходимо доработать несколько узких моментов и сделать связь с сетевым модулем.


2) Доведен до стадии пред релиза рендер планет. Самое главное, исправлен очень противный баг при рендере в Dx12, который, по до сих пор не понятным для меня причинам, давал артефакты на неровностях ландшафта.

(@MrMSE, вопрос со светом все еще открыт, т.к. встроенный Атмосферный Скаттеринг пока не удалось заставить работать так, чтобы можно было сделать "правильный" терминатор)


3) Начата работа над системой шардинга и системой быстрого развертывания сервера (система будет доступна в OpenSource. Пишется на Node.JS).


4) Подготовлены материалы для рефакторинга системы импульсной физики кораблей, для возможности работы через мультидрединг (сейчас сильно зависит от FPS, что сильно сказывается на плавности геймплея)


5) Готовятся материалы для начала работ над конструктором кораблей и станции (пока в концепции)


6) Готовится материал для начала работ над интерьерами станций и АТС.


7) Готовятся материалы для более глубокой оптимизации 3Д туманностей, из-за слишком плохой производительности на видеокартах до RTX эры.


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

Показать полностью
[моё] Unrealengine 4 Unreal Engine 4 Gamedev Lima Текст Cold Fusion
4
8
TehnoMagEG
TehnoMagEG
Лига Разработчиков Видеоигр
Серия Вся наша жизнь спираль

Вся наша жизнь спираль: Синтез субатомных частиц часть 2⁠⁠

4 года назад

В прошлом посте (Вся наша жизнь спираль: Синтез субатомных частиц) мы кратенько рассмотрели сложности работы с float и рендер туманностей.

Сегодня мы рассмотрим планеты и построение сцены относительно игрока.


Начнем с простого.

Свет.

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

Их всего 3:

- Point Light - свет излучается из точки по некому радиусу с затуханием

- Spot Light - или прожектор. Источник излучается из точки по конусу, опять таки с затуханием

- Direction Light - самый простой источник света. Свет идет по направлению, без источника как такового.


Логично предположить, что для звезды лучше всего подойдет последний. Звезда не точка, это огромная сфера, каждая точка которой излучает свет.

Хорошо, с этим определились. Но, Direction Light светит только в одном направлении, а звезда во все сразу. Это проблема, но решается достаточно просто. Мы просто берем, и привязываем направление света на позицию игрока. Тогда получится, что свет всегда идет от звезды к игроку.


А как быть с планетами и прочими макро объектами? Ведь если игрок сместится, то также сместится освещенная часть планеты.

Тут нам помогут уже простейшие шейдера.


Первым делом исключим наши объекты из списка объектов, на которые влияет источник света (иными словами сделаем их Unlit). А дальше, возьмем позицию источника света, посчитаем вектор направления к планете и возьмем dot product от каждой нормали вершины планеты. Вуаля, мы получим маску, которая будет эмулировать этот самый DirectionLight

Вторая проблема, которая вытекает из первой - тени. Большие объекты, особенно если у них есть кольца - отбрасывают на них тень, которая

а) Привязана к источнику света

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

Снова обращаемся к шейдеру.

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

Делается это достаточно просто (хотя тут ноды лучше не использовать)

/*
* INPUT:
* LightLocationWS Light Position in WorldSpace
* LightSourceRadius Light Radius
* ParentBodyLocationWS Parent Body (Shadow Caster) location in WorldSpace
* ParentBodyRadius Parent Body Radius
* WorldPosition AbsoluteWorldPositionWS
* VertexNormal VertexNormalWS
*/
MaterialFloat3 LL = LightLocationWS;
MaterialFloat3 PL = ParentBodyLocationWS;
MaterialFloat LSR = LightSourceRadius;
MaterialFloat PBR = ParentBodyRadius;
MaterialFloat3 rc = WorldPosition - PL;
MaterialFloat c = dot(rc, rc) - (PBR*PBR);
MaterialFloat b = dot(normalize(LL - PL), rc);
MaterialFloat d = b*b - c;
MaterialFloat t = -b - sqrt(abs(d));
MaterialFloat st = step(0, min(t,d));
MaterialFloat shadow = lerp(-1, t, st);
return shadow;
В результате получится вот такой эффект, который не зависит от расстояния и от размера объекта

Со светом разобрались, теперь перейдем непосредственно к построению сцены.

В прошлом посте я рассказывал о пересчете позиций и размеров объектов через их угловой размер. Используем это, приняв то, что игрок будет находится всегда в координате [0,0,0], и то, что нам известно его физическое положение в мире.


Но это сработает только с планетами, звездами и прочими макрообъектами, а что делать с другими игроками? Их рисуем как есть по смещению к позиции игрока - они достаточно маленькие и смысла пересчитывать их размеры нет. Однако, что будет, если другой игрок достаточно далеко, а планета, к которой мы летим, нет, и она уже видна на экране? В этом случае другой игрок может оказаться ЗА планетой, хотя по факту он должен быть перед ней.


В решении этой проблемы нам поможет инструмент, под названием Custom Depth Pass и CustomDepth Stencil Buffer (CustomDepth Stencil Write Mask и CustomDepth Stencil Value)


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


Самый простой вариант (но не самый корректный) отсортировать объекты через дополнительную фазу Translucent (через приоритеты + через стенсил)

где CheckDepth это CustomNode, которая имеет следующее внутри себя

uint SceneDepth = Depth;
return SceneDepth > 1 ? 0 : 1;
SceneDepth тут это как раз таки то самое CustomDepth Stencil Value, которое можно задать свое для каждого объекта в отдельности. Если объекты пересекаются, то значения буфера складываются. Например, если у нас пересеклись объекты со значением 1 и 2, то на выходе будет 3. Тогда, в материале объекта, со значением 1, если полученное число будет больше 1, то нам нужно скрыть этот объект.


Почему именно такие цифры.

Как я уже говорил, Этот буфер является бит маской. и он представлен в виде 8ми позиций в двоичной системы счисления. Для простоты расчетов этот буфер проверяется побитого. И чтобы еще больше упростить расчет, то следует указывать только один бит для объекта.

Следовательно цифры, которые мы можем использовать принадлежат степени двойки, т.е.

1 2 4 8 16 ну итд


1, или 0b00000001 - это самый дальний объект (skycube), который должен быть скрыт, если его пересекает любой другой объект, следовательно если на него приходит любое другое значение, кроме как 1, то мы его скрываем.

Следующий объект 2 (0b00000010). Он не должен быть скрыт, когда к нему приходит значение 3 (собственное значение 2 + 1 от старкуба), но должен быть скрыт, когда приходит значение 4, ну итд.

При этом, если пересекаются два одинаковых объекта, то сокрытие одного или другого объекта будет разруливать не стенсил, но Translucency Sort Priority, который должен зависеть от дальности этих объектов.


У игроков, т.к. мы не изменяем их позиции и не пересчитываем их размер, мы укажем 0b10000000 для стенсил буфера, и таким образом они всегда будут рисоваться перед всеми остальными объектами. Сравнивать их дополнительно не нужно, т.к. если они должны быть ЗА объектом, то они уже давно вышли за расстояние, на котором их может быть видно, поэтому этот случай мы просто не рассматриваем.

Ну а теперь самое вкусное на сегодня - планеты

Всем известно, что когда нужно что-то нарисовать, то у меня лапки. Поэтому я сразу не рассматривал идею с рисованием текстур планет и сразу перешел к генерации из шума.

Нужно было учесть несколько моментов - у нас нет сцен на поверхности планет, поэтому нет смысла выделывать полноценный генератор, аля Elite. При этом все это должно смотреться интересно и +- реалистично.

Пришлось попотеть - написать свою, более гибкую функцию генерации шума, придумать, как прорисовывать детальки, и как передавать цвет на все это дело.

В результате, получилось следующее:

Планета рисуется через функцию слоев материала (часть функционала для рисования ландшафта в UE4). Задается общий шум для ландшафта, а потом отдельными слоями дорисовываются детали: каньоны, горы, итд.

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

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

и в довершение всего, применим к этому SkyAtmosphere - стандартный компонент визуализации UE4 (который наконец доделали в 4.26)

Здесь осталась одна нерешенная проблема. Изначально, для наложения деталей я выбрал не верный подход через 6planar mapping. Для слоя можно выбрать одну из 6ти сторон планеты, но не более того. В ближайшее время это будет заменено на проекцию по произвольному вектору, что позволит добавить более мелкие детали, и сделать более незаметным то, что поверхность планеты на самом деле двухмерна.

И на этом пока что все. До связи до следующего раза.

Показать полностью 8
[моё] Unrealengine 4 Gamedev Lima Длиннопост Unreal Engine 4
22
16
TehnoMagEG
TehnoMagEG
Лига Разработчиков Видеоигр
Серия Вся наша жизнь спираль

Вся наша жизнь спираль: Синтез субатомных частиц⁠⁠

4 года назад

Прошел год с моего последнего поста, пора пилить следующий.

Сегодня снова поговорим о сети и об организации мира Синтеза.


Главное изменение сетевой модели, который получил Синтез - это полный авторити сервер.

Тем не менее, проблемы, которые я описывал ранее в L.I.M.A., никуда не делись, поэтому появился другой модуль, позволяющий обсчитывать сразу несколько "карт" и сливать их в одну карту, с репликой, по необходимости, на клиенты. Модуль имеет открытый исходный код и может быть найден тут: https://github.com/Delta-Proxima-Team/UE4-Module-RelatedWorl...

Если описать простым языком, то он работает по принципу инстанцев в небезызвестной Elite: Dangerous, с той лишь разницей, что можно передавать информацию сразу с нескольких инстанцев в единое мировое пространство клиента.


Карта, в отличии от L.I.M.A. в Синтезе полностью статична. Каждая звездная система заботливо расположена руками, а т.к. место действия происходит в отдельном шаровом звездном скоплении, то их не много. Но конкретно о карте и ее топологии поговорим в другой раз, т.к. при разговоре о ней, нужно будет коснуться и фракций, которые в ней обитают, а об этом, на данный момент я говорить не готов. Вместо этого поговорим об общем ее строении и проблемах, связанных с ней.


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


Подсчет углового размера любого небесного тела можно представить вот таким-вот образом:

, где D - расстояния от наблюдателя до границы объекта, а d - диаметр этого объекта.

Если расстояние D известно, то можно через обратное преобразование получить его радиус.

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

В ходе нехитрых преобразований, мы получим вот такую вот формулу:

В коде, конечно-же, формула будет выглядеть как VisibleDistance * (RealRadius/RealDistance), т.к. отношение RealRadius к RealDistance безразмерный коэффициент. Это была первая проблема.


Вторая проблема это float и разница в единицах измерений (от сантиметра до светового года).

Как известно, если говорить, о целой части float, то она дает достаточную точность для целых чисел, значение которых можно уложить в 3 байта. Если дать больше конкретики, то это число 16 777 215 (16,7 км в единицах анрила). Дальше начинаются проблемы с точностью. Для обхода этой проблемы, и помня, как была решена проблема с размерами объектов, было принято решение делать "Continuous calculation". В такой системе, при подаче некоторого числа на вход, необходимо так-же указать его единицы, и, если оно выше или ниже некоего предела оно будет последовательно переведено в более подходящее для этого числа единицы (пример: если мы дадим на вход 100 000 см. то сначала будет выполнен перевод в 1 000 м, а потом в 1 км ). Таким образом, какое бы расстояние мы бы не передали, то на выходе, оно всегда будет занимать меньше трех байт. Погрешности, конечно-же, никуда не делись, но они нивелируются по мере уменьшения масштаба вычислений. Условно, чем ближе наблюдатель к объекту, тем меньше погрешность. Ну и соответственно, чем дальше, тем погрешность больше, но из-за большого расстояния - глазу не заметно и она не имеет тенденции к накоплению.


Третья проблема - туманности. Т.к. космос бесшовный, то они должны быть 3д. Как нарисовать 3д туманность? Эксперименты показали, что метод Density RayMarcher подойдет лучше всего.

(полученную из фрактала текстуру следует подчистить от артефактов)

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


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


Как бонус: один из ранних рендеров безатмосферных планет.

Показать полностью 5
[моё] Unreal Engine 4 Gamedev Lima Длиннопост
3
TehnoMagEG
TehnoMagEG
Лига Разработчиков Видеоигр
Серия Вся наша жизнь спираль

Вся наша жизнь спираль: от стазиса к синтезу⁠⁠

5 лет назад

Это будет весьма небольшой пост. За последние 9 месяцев много всякого произошло, и проектом практически не было времени заниматься. Однако много думали. И пришло понимание того, что времени и ресурсов все это сделать как мы хотим и отладить, на данный момент нам не хватит ни при каких условиях.


В результате было принято решение отправить проект в стазис, взять часть модулей, переработать и использовать в другом, более простом проекте, который позволит их довести их до ума, а также покажет: будет ли это все работать так, как мы изначально задумывали в L.I.M.A.

Так на свет появился проект под названием "Холодный синтез" (Cold Fusion).


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

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


Подробности о проекте, сложностях и принятых решениях (и костылях) будут также выходить под заголовком "спирали", т.к. тематика очень близкая, но с дополнительным тегом #ColdFusion, а так-же в отдельном чате нашего дискорд канала: https://discord.gg/aNfW5FQ в том-же формате, что и самый первый пост.


Ближайший пост будет посвящен созданию планет, их поверхностям, и как это работает в сетевом окружении, а так-же более подробно расскажу о Вселенной Синтеза.

Показать полностью
[моё] Unreal Engine 4 Gamedev Lima Текст
0
5
TehnoMagEG
TehnoMagEG
Лига Разработчиков Видеоигр
Серия Вся наша жизнь спираль

Вся наша жизнь спираль: сеть⁠⁠

6 лет назад

И снова здравствуйте. Год назад я выкладывал пост, под названием «Вся наша жизнь спираль», в котором немножко рассказал об игре, над которой работаю. Вот он: https://pikabu.ru/story/vsya_nasha_zhizn_spiral_5831544 Этот пост можно считать его продолжением.

Не писал достаточно долго по нескольким причинам. Основная, я опять подзабил на проект и занимался основной работой, также появились некоторые трудности, которые заставили меня снова залезть в дебри Unreal Engine 4 и смотреть, что Эпики там понакрутили. Но я снова в седле, и т.к. очередной этап разработки завершен, то можно и написать статью об этом.

Начну, пожалуй, с новостей. Их всего две:

1) Мы относительно недавно обзавелись сервером в дискорде: https://discordapp.com/invite/aNfW5FQ , т.ч. милости просим.

2) Мы приняли решение часть неигровых модулей выложить в Open Source под BSD лицензий.

Вот об одном (единственном доступном широкой публике на данный момент) open Source модуле, под названием Client Authority Network (CANet) мы и поговорим.

Данный модуль был написан с одной единственной целью: решить проблему синхронизации игроков в сетевом режиме игры. Казалось бы, в чем проблема? Объясняю, в стандартной сетевая модель UE4 постулирует следующие законы.

• Все игроки должны находится на одной локации в рамках одного сервера. 

• Все игроки должны считать логику на сервере, на клиенты транслируется только результаты обработки. 

• Все игроки должны иметь на сервере координаты в глобальной сетке карты.

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

Решение, казалось бы, напрашивается само собой: написать свою сетевую модель, которая не будет столь категорична к позициям игроков. Примерно это, CANEt и делает. Однако, чтобы написать свою сеть в UE4, это нужно переписать туеву кучу кода, и не факт, что после очередного обновления движка все будет работать так, как было задумано. Посему я решили схитрить. Я не стали переделывать всю сеть, а заместо этого перевернул работу оригинального, получив заместо стандартной модели сервер-клиент, модель клиент-роутер-клиент (почти честная PTP). В результате, все три закона стандартной модели стали недействительными. И проблема частично была решена. Почему частично? Осталась проблема синхронизации игроков в отдельно взятых локациях. Эту проблему модуль не решает, но, зато ее способна решить фича, которая перекочевала в UE4 прямо из Фортнайта, а именно Replication Graph, но сегодня речь не о нем.

Итак, как же работает CANet. CANet, как я уже говорил, переворачивает принцип работы сети в UE4 с ног на голову. Начинается все так-же, как и в оригинале. На сервер создаётся Game Mode, которая ждет подключения игрока. Как только игрок подключился, создается Player Controller и Player State, которые реплицируется на клиенты (Player Controller только владельцу подключения), а вот дальше начинаются отличия.

В оригинале, следующим этапом было бы создать на сервере чарактер игрока (ACharacter/APawn) и среплицировать его на клиенты. В случае CANet это происходит немножко иначе:

• На сервере создается специальный класс UClientChannel, который привязан к APlayerState в качестве компонента и реплицируется вместе с ним.

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

• Если APlayerState привязан к APlayerController, то UClientChannel начинает считаться авторитетным и начинается покадровая проверка свойств из буфера.

• При проверке, если контрольная сумма свойства в буфере не сошлась с суммой свойства чарактера, то свойство помечается как изменившееся и записывается во второй буфер.

• В конце кадра, если буфер имеет не нулевую длину, то отправляем его на сервер.

• Сервер сохраняет себе свойства в свой буфер и перенаправляет его остальным клиентам. 

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

Иными словами, обязанности сервера плавно переходят на клиенты, а на самом сервере, чарактеров и прочих актеров просто не существует.

Существует и ряд проблем: в частности, нужно понимать, что, отдав права на изменение переменных на клиенты мы, по сути, открываем особо одаренным товарищам целый плацдарм для читерства. Для противоборства этому, как раз и существует отдельный буфер на сервере. Этот буфер в будущем будет передаваться подсистеме чит-детектора, который по определенным правилам будет выискивать читеров, и отключать их от игровой сессии.

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

На этой ноте, наверно можно и заканчивать. Сам модуль можно найти по адресу: https://github.com/TehnoMag/UE4-Module-CANet , а в следующий раз мы поговорим либо о Replication Graph либо о Wave Function Collapse (WFC) генерации в UE4 и его роли в L.I.M.A. strace_.

Показать полностью
[моё] Unreal Engine 4 Gamedev Lima C++ Текст Длиннопост
24
limaindiamike

LIMA - Танцуй со мной⁠⁠

6 лет назад
Перейти к видео



Я самый свежий в клубе хочу танцевать Я самый свежий в клубе хочу танцевать Я подхожу подруга к тебе по днк Я подхожу подруга
Танцуй со мной , у бара у бара

[моё] Lima Танцы Видео
2
TehnoMagEG
TehnoMagEG
Лига Разработчиков Видеоигр

Нужна помощь с кодом [Проблема решена]⁠⁠

7 лет назад

В общем хотел еще вчера залепить пост о том, как я перешел на каскадные модули, но вместо этого придется просить помощи, ибо я себе уже мозг сломал =/

Нужна помощь с кодом [Проблема решена]

В общем суть. Это кусок дебага в конфигурации DevEditor x64; юнит Runtime/Engine/Private/Particles/ParticleGPUSimulation.cpp


Из моего кастомного каскадного модуля приходят локация и размер частицы. Дальше это передается уже штатным кодом на указанный выше юнит. Локация выставляется; а вот с размером происходит следующая фигня:


Она попадает в переменную BaseSize (1.5 по X и Y это норм);

Дальше высчитывается UVFlipSizeOffset. Оно 0.5 по условию

потом идет пересчет сайза по X и Y. Тут уже странность, ибо он становится 7.49 по осям

А вот после суммирования с UVFlipSizeOffset происходит какая-то магия, ибо на выходе у меня всегда 0.5 по осям (независимо от BaseSize).


За любую помощь буду признателен.

Показать полностью
[моё] Unreal Engine 4 Gamedev C++ Lima Без рейтинга
20
3
TehnoMagEG
TehnoMagEG
Лига Разработчиков Видеоигр
Серия Вся наша жизнь спираль

Вся наша жизнь спираль⁠⁠

7 лет назад

Ну начнем по маненьку.

Для начала, хотелось бы рассказать технической части (из готового) и немножко о геймплее.


Если кто заходил ко мне в контактик (на всякий случай ссылка: https://vk.com/lima_strace), то вы видели, что записи посвящены мультиплееру и генераторам L1 и L2, вот о последних и поговорим.


Весь игровой мир можно условно разделить на слои (layer). Всего их 4, начиная с нуля:


L0 – или слой Вселенной. По задумке, на поздней стадии разработки будет добавлен в сетевом режиме игры и будет показывать ближайшие игровые галактики, созданные другими игроками и добавленными на текущий игровой Хаб.


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


L2 – слой звездной системы. Как и L1 он представлен в виде небольшой структуры, в которой хранятся сиды планет, их стартовые (момент времени t0) позиции. В отличии от L1 этот слой разворачивается только в момент прибытия игрока в конкретную систему.


L3 – слой орбиты. Он присутствует только у тех планет, где L2 разместил станции. И содержит шаблон станции, данные по импортам-экспортам, продаваемых на верфях модулей кораблей.



Для генерации галактики был взят очень простой и быстрый метод.


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


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

Разумеется, все это сдабривается шумом для придания объема. В результате получается следующая картинка:

Сами звезды рисуются через единую систему частиц. Приходится использовать не совсем обычные функции для этого, т.к. необходимо передать достаточно внушительный объем данных на конвеер визуализации. Раньше для этого использовалась текстура, в которой каждый пиксель обозначал конкретную звезду. В формате R32G32B32A32, можно было задать 4 вектора, которых было достаточно для позиционирования, масштабирования и окрашивания, однако при тестировании оказалось, что метод не совсем удачный, т.к. не было учтено то, что для получении пробы точка выбирается по текстурным координатам (UV 0..1) и в некоторые моменты в качестве пробы могло прийти интерполированное значение от нескольких смежных пикселей, что в результате давало либо мерцание, либо наложение нескольких звезд в одной точке:


https://www.youtube.com/watch?v=L07smX_Fs9k (вставить видео не могу, поэтому ссылка)


Поэтому от этого метода было решено отказаться, а заместо него использовать другой. Этот новый метод основан на двух путях:


Путь 1 – простой. У Эмиттера в UnrealEngine4 есть не экспортируемая в редактор функция ForceSpawn, который позволят создать один или несколько партиклов в заданной локации и, если необходимо, с заданной скоростью. В дальнейшем можно получить объект этого партикла и установить параметры, такие как цвет, размер на необходимые. Из минуса этого метода можно назвать невозможность использования с GPU партиклами (банально не вернется объект), а также приличную нагрузку на процессор при обходе массива с ними.


Путь 2 – каскадный. Более сложный, т.к. требует понимания того, как реализованы частицы в UE4. Из минусов можно назвать то, что при работе каскадного модуля нельзя узнать точно, какая из частичек сейчас обрабатывается (на самом деле можно: если система частиц не имеет модуля Lifetime, а сама система частиц настроена только на один единственный прогон, то можно взять переменную ActiveParticles и отнять от нее единицу, и таким образом получить текущий индекс частицы), а также невозможность получить из этого модуля данные из игрового треда простым путем.

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


С планетами все несколько проще. Берется SimplexNose, который генерируется из сида планеты, мерджится с несколькими подобными нойсами и выбирается цвет, в зависимости от цветности точки по типу поверхности. Также из результирующего шума можно сгенерировать NormalMap и/или HeightMap для штатного тасселятора.


С планетами все несколько проще. Берется SimplexNose, который генерируется из сида планеты, мерджится с несколькими подобными нойсами и выбирается цвет, в зависимости от цветности точки по типу поверхности. Также из результирующего шума можно сгенерировать NormalMap и/или HeightMap для штатного тасселятора.


А вот самих локаций планет (т.е. посадок на них) не будет. Не будет их по нескольким причинам:

1) Нет и не будет достаточного кол-ва контента для их заполнения (Брабен, Крис, привет)

2) Для них необходима совершенно другая физика полета.

3) Полноценная терра генерация занимает приличное к-во времени, которое можно было бы потратить на более интересные для игрока вещи (например, квесты).


Теперь кратенько о геймплее и мультиплеере. Подробно буду рассказывать в последующих постах.


Геймплей можно условно разделить на 3 части:

Прибытие – Когда игрок только прибывает в новую галактику в ней никого нет (или есть, если включен сетевой режим). Нам дается небольшой корабль без команды, шахтерское и простенькое сборочное оборудование и, собственно, все. У нас несколько задач: первая – это найти как можно больше пригодных для заселения и богатых ресурсами планет; вторая – найти ресурсы и собрать маяк для моста Эйнштейна-Розена, ну а третья доставить и установить этот маяк в центре галактики недалеко от массивной черной дыры.


Воссоединение – Как только мост будет активирован, через него начнут прибывать колонисты. На этом этапе задача игрока помогать кораблям добраться до найденных ранее планет и всячески помогать им обустроить свой быт. Также игрок продолжает искать новые пригодные планеты.

Со временем колонии начнут выходить в космос, строить свои корабли и объединятся с соседями во фракции, налаживать торговые связи. Появляются местные валюты (может быть одна, может быть несколько [зависит от расположения фракций относительно друг друга]). Когда некоторое кол-во фракций будет сформировано, а их границы соприкоснутся начнется третий этап игры.


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


Конец игры наступает в случае, если в галактике остается только одна фракция и игрока отсылают исследовать новую галактику для начала нового цикла (событие «Новый день»); если игрок находит и активирует событие под кодовым названием «Мистерия»; если происходит событие «Дорога домой»



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


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

Показать полностью 3
[моё] Unreal Engine 4 Gamedev Lima Длиннопост C++
7
Посты не найдены
О нас
О Пикабу Контакты Реклама Сообщить об ошибке Сообщить о нарушении законодательства Отзывы и предложения Новости Пикабу Мобильное приложение RSS
Информация
Помощь Кодекс Пикабу Команда Пикабу Конфиденциальность Правила соцсети О рекомендациях О компании
Наши проекты
Блоги Работа Промокоды Игры Курсы
Партнёры
Промокоды Биг Гик Промокоды Lamoda Промокоды Мвидео Промокоды Яндекс Маркет Промокоды Пятерочка Промокоды Aroma Butik Промокоды Яндекс Путешествия Промокоды Яндекс Еда Постила Футбол сегодня
На информационном ресурсе Pikabu.ru применяются рекомендательные технологии