Поэтапно сотворяю космос из ничего

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

Сперва определим форму скайбокса.

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

Вы знаете, что такое скайбокс?
Знаю
Знаю (вариант для тех, кто не знает, но не хочет палиться)
Не знаю.

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

Это важно отметить, так как я в качестве примеров буду использовать сразу 2 изображения: вид «изнутри» скайбокса, и вид со взглядом со стороны на него.

Как-то так.

Шейдер будет смешивать несколько эффектов друг с другом. Теперь это шЕйКеР бадумтс.

Рассмотрим каждый из них по отдельности.

Звёзды

Их основой можно сделать либо текстуру, либо математику. Словом, вот сделанный на коленке пример:

Положения точек определяются математически.
Положения точек определяются математически.

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

Дисклеймер: Видеоролики в статье чуть пережатые, и в миниатюре могут выглядеть плохо из-за деталей. Могу порекомендовать либо открывать их на весь экран, либо посмотреть нарезку этих видосов в хорошем качестве -> тут <-.

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

Если возводить значение цвета пикселя в степень, можно регулировать яркость. Это удобно тем, что чёрные цвета остаются чёрными, белые – белыми, а промежуточные стремятся к краю, но никогда его не достигнут.

X – старый цвет. Y – новый. 0 – чёрный. 1 – белый.<br />
X – старый цвет. Y – новый. 0 – чёрный. 1 – белый.

Вот так выглядит визуализация этих графиков на нашей модели.

А вот так, если чуть поусложнять формулу, чтобы подсвечивались даже самые тусклые звёзды.

Осторожно глазам..

Звёзды выглядят более выраженными.

Но довольно нам игр! Подобрали себе подходящие параметры и двигаемся дальше.

Градиент

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

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

Вот ещё вариант с космическим диско. Но тут осторожно глазам.

В общем, можно как-угодно цветами манипулировать: растягивать, вытягивать, дробить, засветлять.

Кстати, любые параметры (например, силу переливания или яркость) можно делать динамическими в зависимости от внутриигрового контекста. Но его нет - так что это на будущее.

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

Я в итоге так однозначно и не определился как лучше: когда вверху словно симпатичное подобие неба, а внизу вся чёрная сосредоточенность зловещего неумолимого, или наоборот.

Потому держите ровно то же самое видео, но отзеркаленное по вертикали. Не рендерить же мне новое, честное слово.
Небо где лучше?
Наверху
Внизу

Мерцание

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

Есть много способов вынудить их это делать, но в целом всё сводится к подбору алгоритма, определяющего, где и как сильно будет выполняться подсвечивание.

Например, синус позиции точки в мировой координате Z при вольной амплитуде, шаге и постоянно увеличивающейся фазе подсветит следующие зоны сферы:

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

Ну красиво же!

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

Вот вариант, при котором эффект касается только звёзд:

В качестве формулы используется умножение (result = original * bright). Оно позволяет почти не трогать тёмные участки и гораздо сильнее подсвечивать светлые. Это буквально принцип «чем более ты яркий, тем сильнее ты станешь ещё ярче».

Однако. Все эти светлые волны вокруг – скопления плотных, мелких, тусклых звёздочек. Дело в том, что в самой текстуре, чёрное месиво вокруг самых ярких звёзд, не полностью чёрное. Там находятся куча малозаметных звёзд, яркостью 0-4% от полной. Они и вызывают эти округлые подсвечивания.

Чтобы от них избавиться, можно либо вручную вмешаться в изображение и в фотошопе притемнить все недостаточно тёмные фрагменты ..либо просто внести правку в шейдер, чтобы все эти скопления оставались на месте, но эффект оказывал влияние только на звёзды яркостью 5-100%.

Дополнительные вычисления, конечно, негативно скажутся на производительности – видеокарта отрендерит пиксель не за 1 наносекунду, а за 1,0001. Однако я готов пойти на такие жертвы.

Собственно, таков результат.  Мы просто заигнорили серое стадо. Яркие звёзды по-прежнему мерцают.

Здесь я хотел показать лишь то, как сильно будут меняться звёзды. О том, какие именно - мы поговорим далее.

Но напоследок, поиграемся с множителем и степенью! Осторожно глазам.

Итак. Теперь давайте поговорим про зонирование.

Какие звёзды стоит подсвечивать? Ваши мысли?
Случайные
Последовательные
Гибридные
Пронозвёзды

Я вот остановился на варианте «зависящие от угла обзора камеры».

Он мне понравился тем, что, если стоять на месте и не двигаться – картинка не будет мерцать и привлекать лишнего внимания, глаза будут болеть меньше. Эффект начнёт проявляться при медленном вращении камерой. При быстром просто будет малозаметным из-за резкого изменения всего фона.

Вот пример подобного зонирования:

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

Можно менять размер и плотность областей, причём подбирать их осторожно, так как разные варианты иначе воспринимаются. Где-то мерцание будет казаться хаотичным и ненавязчивым, а где-то формула прям очень палится (как на примере выше), и оно уже не выглядит опрятно.

Эффект не предназначен бросаться в глаза. Он скорее призван избавить от ощущения статичного фона и подчеркнуть некую «живость» звёздочек.

Если же всё причесать, подобрать подходящие формулы, можно прийти, например, к такому результату:

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

Вообще, формула такого зонирования – не самая дальновидная. Просто я не смог придумать лучше.

Волны

Натянутое на глобус фиг пойми что – это, конечно, хорошо. Но где все эти космические потоки, вселенские цветастые скопления?

Терпения, компадре. Как только я стырю из интернета какую-нибудь приятную картинку бесшовного дыма и впишу её прямиком в алгоритм – вот тогда заживём.

Собственно, вот картинка. Посмотри, красивая какая.

Поэтапно сотворяю космос из ничего

А вот я добавил её на свою космическую сферу.

…хм.. просчитался... но где..

Ладно. Картинка подойдёт разве что для практики. Потом добавлю на свою комическую аферу что-то чистое и лицензированное. Может нарисую сам, посмотрим. А пока притворимся, что никто ничего не видел.

Основные принципы математической обработки изображения на этом этапе не отличаются от того, что писал выше: RGB-каналы, масштаб, растягивание, смещение, смешивание, амплитуда, подгон, подлог, интерлюкс, интерпрайз и прочие незнакомые мне слова.

Из нового тут вот что: анимация.

Самая простая в виде прямого движения будет выглядеть так:

Обратите внимание, что звёзды стоят на месте.

Пока сделаем перерыв.

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

Наслаждайтесь. И берегите глаза.

Я поставил на фон Бетховена. Всё для вашей медитации.
Здесь тоже хорошая музычка играет.
А здесь нет.
Финальное залипалово. Только попробуйте НЕ УЗНАТЬ ОТКУДА ЭТА МУЗЫКА. Каждого найду!

Летим дальше.

Я немало экспериментировал со всем этим.

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

Выглядит двойная волна примерно так:

Первая волна отвечает за то, чтобы сделать космос менее «пустым» и «плоским». Вторая – за цветовое разнообразие.

Их цвета будут регулярно меняться между несколькими вариантами.

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

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

Ниже гипертрофированный пример ярко-синей и зелёной волны.

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

Простыми словами: смешанный цвет (голубой) виден; оригинальный цвет (зелёный) нет.
Аналогично с красной волной: смешанный цвет (розовый) виден; оригинальный цвет (красный) нет.

Мы практически на финише.

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

«Скорость изменения цвета» X 10
А здесь обычная скорость. Видео длится 4 минуты. Смотреть не рекомендую, но вдруг вам было бы интересно глянуть на всё это в нормальном виде.

Кстати, волна чёрного цвета выглядит как анти-волна, что наоборот, стирает цвет из пространство-времени.

Итоги

Таким получился мой космос.

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

Напоминаю, что нарезку видосов в хорошем качестве можно посмотреть -> тут <-.

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

3030
66
11
22 комментария

Космическое хрючево ждёт пополнение?😏

2
1

"космосодержащий элемент" - звучит как старфилд.
Игросодержащий продукт.

3

О, ну раз меня сравнивают с великими – значит уже на верном пути.

2

А если я смогу продать шейдер за огромные деньги, он тогда будет называться ШЕЙХер

2

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

💖🐟

2