Поэтапно сотворяю космос из ничего
Так как моя будущая игра предполагает иметь в себе космососодержащий элемент, пришлось написать крутой шейдер для этого. Делюсь историей, результатом и промежуточными версиями.
Сперва определим форму скайбокса.
Один приятель сказал, что нужно пояснение, что такое скайбокс. Я ему ответил, что на DTF все умные, они и так знают, что это. Давайте подтвердим это.
Часто их форма кубическая, но в текущем контексте лучше использовать низкополигональную сферу. Треугольников больше, зато точки на гранях становятся более равноудалёнными от центра – благодаря этому бесшовные текстуры лучше лягут на поверхность, а анимация будет менее кривой, чем на кубической форме.
Это важно отметить, так как я в качестве примеров буду использовать сразу 2 изображения: вид «изнутри» скайбокса, и вид со взглядом со стороны на него.
Шейдер будет смешивать несколько эффектов друг с другом. Теперь это шЕйКеР бадумтс.
Рассмотрим каждый из них по отдельности.
Звёзды
Их основой можно сделать либо текстуру, либо математику. Словом, вот сделанный на коленке пример:
Можно подзапариться и допилить до более привлекательного вида, но мне стало лень, так что я пошёл фоткать ночное небо. Затем мне стало лень дважды, и я просто взял доступные в сети изображения.
Дисклеймер: Видеоролики в статье чуть пережатые, и в миниатюре могут выглядеть плохо из-за деталей. Могу порекомендовать либо открывать их на весь экран, либо посмотреть нарезку этих видосов в хорошем качестве -> тут <-.
Если возводить значение цвета пикселя в степень, можно регулировать яркость. Это удобно тем, что чёрные цвета остаются чёрными, белые – белыми, а промежуточные стремятся к краю, но никогда его не достигнут.
Вот так выглядит визуализация этих графиков на нашей модели.
А вот так, если чуть поусложнять формулу, чтобы подсвечивались даже самые тусклые звёзды.
Осторожно глазам..
Но довольно нам игр! Подобрали себе подходящие параметры и двигаемся дальше.
Градиент
Натянутая на глобус чужая картинка – это, конечно, хорошо. Но давайте хоть какой прилив добавим.
Пожалуй, самая лёгкая часть. Просто добавляем красок, чтобы лучше прочувствовать вселенскую хтонь.
Вот ещё вариант с космическим диско. Но тут осторожно глазам.
В общем, можно как-угодно цветами манипулировать: растягивать, вытягивать, дробить, засветлять.
Кстати, любые параметры (например, силу переливания или яркость) можно делать динамическими в зависимости от внутриигрового контекста. Но его нет - так что это на будущее.
Вот вам симпатичный (наверно) пример космического градиента. Здесь будет только вид от первого лица, а камера будет крутиться, чтобы можно было более полноценно оценить вид изнутри.
Я в итоге так однозначно и не определился как лучше: когда вверху словно симпатичное подобие неба, а внизу вся чёрная сосредоточенность зловещего неумолимого, или наоборот.
Мерцание
Натянутая на глобус чужая подсвеченная синевой, картинка – это, конечно, хорошо. А ты попробуй заставить звёзды сиять.
Есть много способов вынудить их это делать, но в целом всё сводится к подбору алгоритма, определяющего, где и как сильно будет выполняться подсвечивание.
Например, синус позиции точки в мировой координате Z при вольной амплитуде, шаге и постоянно увеличивающейся фазе подсветит следующие зоны сферы:
И если видео выше вам кажется больно уж несуразным, то вы только посмотрите на то, что получится если такое зонирование наложить на наши звёзды:
Однако в конечный результат такое, разумеется, не пойдёт. Нам в принципе не нужно касаться градиента, потому впредь мы будем выводить его на экран, но в новых расчётах тактически игнорировать.
Вот вариант, при котором эффект касается только звёзд:
Однако. Все эти светлые волны вокруг – скопления плотных, мелких, тусклых звёздочек. Дело в том, что в самой текстуре, чёрное месиво вокруг самых ярких звёзд, не полностью чёрное. Там находятся куча малозаметных звёзд, яркостью 0-4% от полной. Они и вызывают эти округлые подсвечивания.
Чтобы от них избавиться, можно либо вручную вмешаться в изображение и в фотошопе притемнить все недостаточно тёмные фрагменты ..либо просто внести правку в шейдер, чтобы все эти скопления оставались на месте, но эффект оказывал влияние только на звёзды яркостью 5-100%.
Дополнительные вычисления, конечно, негативно скажутся на производительности – видеокарта отрендерит пиксель не за 1 наносекунду, а за 1,0001. Однако я готов пойти на такие жертвы.
Здесь я хотел показать лишь то, как сильно будут меняться звёзды. О том, какие именно - мы поговорим далее.
Но напоследок, поиграемся с множителем и степенью! Осторожно глазам.
Итак. Теперь давайте поговорим про зонирование.
Я вот остановился на варианте «зависящие от угла обзора камеры».
Он мне понравился тем, что, если стоять на месте и не двигаться – картинка не будет мерцать и привлекать лишнего внимания, глаза будут болеть меньше. Эффект начнёт проявляться при медленном вращении камерой. При быстром просто будет малозаметным из-за резкого изменения всего фона.
Вот пример подобного зонирования:
Можно менять размер и плотность областей, причём подбирать их осторожно, так как разные варианты иначе воспринимаются. Где-то мерцание будет казаться хаотичным и ненавязчивым, а где-то формула прям очень палится (как на примере выше), и оно уже не выглядит опрятно.
Эффект не предназначен бросаться в глаза. Он скорее призван избавить от ощущения статичного фона и подчеркнуть некую «живость» звёздочек.
Если же всё причесать, подобрать подходящие формулы, можно прийти, например, к такому результату:
Вообще, формула такого зонирования – не самая дальновидная. Просто я не смог придумать лучше.
Волны
Натянутое на глобус фиг пойми что – это, конечно, хорошо. Но где все эти космические потоки, вселенские цветастые скопления?
Терпения, компадре. Как только я стырю из интернета какую-нибудь приятную картинку бесшовного дыма и впишу её прямиком в алгоритм – вот тогда заживём.
Собственно, вот картинка. Посмотри, красивая какая.
А вот я добавил её на свою космическую сферу.
Ладно. Картинка подойдёт разве что для практики. Потом добавлю на свою комическую аферу что-то чистое и лицензированное. Может нарисую сам, посмотрим. А пока притворимся, что никто ничего не видел.
Основные принципы математической обработки изображения на этом этапе не отличаются от того, что писал выше: RGB-каналы, масштаб, растягивание, смещение, смешивание, амплитуда, подгон, подлог, интерлюкс, интерпрайз и прочие незнакомые мне слова.
Из нового тут вот что: анимация.
Самая простая в виде прямого движения будет выглядеть так:
Пока сделаем перерыв.
Покуда есть возможность, приведу примеры всяких симпатичных реализаций такой волны.
Наслаждайтесь. И берегите глаза.
Летим дальше.
Я немало экспериментировал со всем этим.
Так как у меня стоит задача сделать космос красивым, а не реалистичным – на текущий момент пришёл к тому, чтобы делать два слоя волн единой текстуры, двигающиеся в одном направлении – первая ярко, медленно, в холодных оттенках, вторая тускло, быстро и цветасто (но не слишком).
Выглядит двойная волна примерно так:
Первая волна отвечает за то, чтобы сделать космос менее «пустым» и «плоским». Вторая – за цветовое разнообразие.
Их цвета будут регулярно меняться между несколькими вариантами.
При этом, чтобы избежать чрезмерной «цветастости», при смешивании волн, красный и зелёный каналы второй волны будут обрезаться так, чтобы они не превышали синий канал первой волны.
Такое изменение приведёт к тому, что сама цветастость останется, но будет вписываться чуть более органично, не преобладая над основным синим оттенком окружения.
Ниже гипертрофированный пример ярко-синей и зелёной волны.
Обратите внимание: смешиваются волны правильно. Но как только вторая волна вылетает за первую – она приглушается, растворяясь в пустоте бесконечного космоса, навстречу неминуемому забвению.
Мы практически на финише.
Тайминг изменения цвета можете проследить здесь. Я определил 15 возможных комбинаций. Приложение случайным образом выбирает одно из них, и начинает меееееедленно переходить в него, а потом переключается на случайное новое.
Кстати, волна чёрного цвета выглядит как анти-волна, что наоборот, стирает цвет из пространство-времени.
Итоги
Таким получился мой космос.
Напоминаю, что нарезку видосов в хорошем качестве можно посмотреть -> тут <-.
А вот как это будет выглядеть в самой игре. Подписывайтесь, если не хотите пропустить её релиз!