惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google Online Security Blog
Google Online Security Blog
S
Security @ Cisco Blogs
Recent Commits to openclaw:main
Recent Commits to openclaw:main
人人都是产品经理
人人都是产品经理
The Hacker News
The Hacker News
W
WeLiveSecurity
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
博客园 - 司徒正美
雷峰网
雷峰网
L
LINUX DO - 最新话题
博客园 - 叶小钗
云风的 BLOG
云风的 BLOG
The Last Watchdog
The Last Watchdog
V2EX - 技术
V2EX - 技术
S
Security Affairs
有赞技术团队
有赞技术团队
月光博客
月光博客
T
Threatpost
T
Tor Project blog
O
OpenAI News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
V
V2EX
Know Your Adversary
Know Your Adversary
Project Zero
Project Zero
博客园 - 三生石上(FineUI控件)
D
Docker
AWS News Blog
AWS News Blog
AI
AI
P
Proofpoint News Feed
K
Kaspersky official blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
S
Securelist
F
Fortinet All Blogs
F
Full Disclosure
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
量子位
Hacker News - Newest:
Hacker News - Newest: "LLM"
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
P
Palo Alto Networks Blog
Cyberwarzone
Cyberwarzone
Cisco Talos Blog
Cisco Talos Blog
美团技术团队
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
MyScale Blog
MyScale Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Hail to the Rainbow. Разработка игры длиною в вечность. Освещение, лайтмаппинг и приемы оптимизации
NoskovSS · 2026-04-17 · via Все публикации подряд на Хабре

Время на прочтение8 мин

Охват и читатели12K

Туториал

Всех приветствую! В прошлом году я начинал цикл статей на тему разработки моей инди – игры. Hail to the Rainbow. С тех пор прошло немало времени, и игра уже успела выйти в релиз на трех платформах: Steam, VK Play и GOG. К сожалению, тяжело одновременно вести работу над игрой и готовить при этом материалы или дневники разработчика. Всегда поражаюсь способностям тех, кто умудряется находить на это силы и время. Однако, темы статей я запланировал давно, поэтому очень хотелось бы рассказать о нюансах и тонкостях работы, пусть даже после выхода игры.

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

Теперь по основной теме, которую мне давно хотелось разобрать. Так сложилось, что в работе с движком Unity я во многом использую олдскульные и кустарные методы, в том числе и в графике. Сейчас большинство разработчиков пересаживается на новые технологии, HDRP рендер, глобальное реалтайм освещение, RTX и тд. Я же по-прежнему сижу в Unity built-in render и пытаюсь выжать максимум классическими техниками, использую статичный лайтмаппинг и некоторые самописные хитрости. Кстати, последние новости от Unity по поводу будущего выпиливания старого рендера меня очень огорчили. У меня есть некоторый опыт работы в новом HDRP, и честно говоря, он вызывает лишь разочарование своей топорностью и низкой производительностью. На мой взгляд, классический рендер визуально мало чем уступает благодаря своей гибкости и дополнительным расширениям. Впрочем, допускаю, что в новой среде у меня пока еще мало опыта для окончательных выводов.

Старый добрый лайтмаппинг.

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

Предпросмотр в Bakery.

Предпросмотр в Bakery.

В сценах Hail to the Rainbow я активно миксую две основных категории объектов. Крупные объекты с запеченным светом, здания, трубы, крупногабаритные пропсы с более-менее простой uv развёрткой для запечки. Развертку для лайтмаппинга я чаще всего делаю самостоятельно, не доверяю автоматике. Порой для тех же зданий удобно регулировать качество карт в зависимости от важности элемента. К примеру, для фасада развертка делается плотной для достижения высокой детализации. Для крыш, боковых стен, которых игрок почти не увидит или увидит издалека, развертку можно сделать менее плотной, то есть выделить для этих зон низкий Texel Density.

Плотность UV2 развертки.

Плотность UV2 развертки.

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

Назначение позиции лайт проб для объектов без лайтмаппинга.

Назначение позиции лайт проб для объектов без лайтмаппинга.

Вообще построение сцен в играх мне очень нравится тем, что они содержат в себе огромное количество фейковых приёмов и фокусов. К примеру, на некоторых локациях определённые удалённые от игрока объекты, вроде зданий или деревьев я исключал из реалтайм освещения Directional light, при этом использовал для их подсветки либо лайтмапы, либо лайт пробы. В целом, основной принцип работы со светом и оптимизацией – чем меньше реалтайм света и теней, тем лучше. Это позволяет значительно снижать полигонаж в кадре и количество Draw Calls – вызовов отрисовки.

Полностью запеченный свет на объекте за пределами карты.

Полностью запеченный свет на объекте за пределами карты.

Готовая сцена с запеченным светом + реалтайм освещение солнца.

Готовая сцена с запеченным светом + реалтайм освещение солнца.

Сама запечка с рефлексами. Некоторые объекты не отображаются, поскольку используют Light Probes.

Сама запечка с рефлексами. Некоторые объекты не отображаются, поскольку используют Light Probes.

Глобально я использовал во всех сценах режим Distance Shadowmask. На расстоянии до 50-80 метров объекты отбрасывают реальные тени + к поверхностям применяется запеченный мягкий Global Illumination свет, с помощью лайтмаппинга, либо Light Probes.  Далее отрисовываются уже полностью запечённые тени. Это позволяет не терять художественную выразительность и затенения на больших расстояниях.  В некоторых случаях для экономии я полностью запекал свет, к примеру в некоторых комнатах со слабой освещенностью. Но там, где свет должен создавать качественный акцент, обращать на что-то внимание, подчёркивать детали, я использовал реалтайм светильники. При этом, очень жаль, что в Unity (по крайней мере в версии 2019) нет встроенного метода отсечения светильников на расстоянии, из-за чего отрисовка некоторых лампочек в помещениях после 40-60 метров становится бессмысленной тратой ресурсов. Для решения этого вопроса пришлось сделать свой контроллер, который хранил в списке источники света, раз в 2-3 секунды пробегался по списку и активировал, или дезактивировал лампы для экономии.

Переход от реалтайм теней к запеченным

Переход от реалтайм теней к запеченным

Terrain Lightmapping.

Поскольку процесс запекания не быстр и каждый раз после каких-либо изменений пересчитывать свет на уровне слишком утомительно, я применил для некоторых природных объектов один интересный приём. Для декора на террейне я достаточно часто использовал объекты в виде детализированных сугробов, заснеженных веток, комков снега и камней. Как правило, эти объекты имели несколько уровней лодов. Чтобы не тратить время и текстурное лайтмап-пространство я написал шейдер, использующий лайтмапу террейна и проецирующий её сверху на объекты (для этого необходимо было, чтобы лайтмапа содержала в себе именно карту террейна, и ничего более). Это позволило отключить у объектов Light Probe режим, зачастую создающий дополнительные Draw Calls. В нашем случае шейдер и карта освещения имитировали амбиент для всех этих многочисленных объектов без особой нагрузки. Поскольку карта света у террейна и объектов одна, в тёмных областях и более светлых, сугробы достаточно гармонично сливались со снежной поверхностью, создавая ощущение цельной структуры.  Дополнительно в данном шейдере использовалась и система блендинга с террейном, при максимальном сближении с поверхностью террейна нижняя часть объектов плавно миксовалась (переходила к тем же картам, альбедо, нормал и тд., что и у самого террейна). В совокупности данный метод вполне неплохо себя показал и позволил создавать дополнительную более сложную геометрию на поверхности снега, смешивая ее и избегая грубых жёстких рёбер и переходов. Эта же техника оказалась подходящей и для создания снежно-морозного налета нижней части объектов, находящихся в снегу.

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

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

Блендинг террейна с природными элементами.

Блендинг террейна с природными элементами.

Налет снега на нижней части объекта передается от террейна.

Налет снега на нижней части объекта передается от террейна.

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

Прокачка теней.

Для тех, кто знаком с движком Unity или играл в игры на нём, не секрет, что стандартные тени из коробки выглядят достаточно уныло. Тень от солнца (Directional Light) одинаково чёткая по всей протяжённости, либо размытая и мерцает, если снизить качество Shadow map resolution. Тени от Point или Spot светильников также весьма грубы и не поддаются модификациям. В таких условиях, например, сложно сделать мягкий свет в пасмурную погоду или от рассеянных источников (можно сделать запечкой, но я имею в виду именно реалтайм светильники).

В первую очередь для Hail to the Rainbow я решил прокачать тени от солнца. На реальной местности тени весьма разнообразны, они имеют разную степень чёткости. Тень у основания объектов, всегда чёткая, но по мере удаления всё больше размывается. К примеру, тень на стене от рядом стоящего человека будет чёткой, а от здания, расположенного вдалеке - значительно размытой. Благодаря этому тени не превращаются в однообразную кашу, а несут в себе информацию, придают объем. Это очень здорово отражено в Half - life Alyx. Основной свет и тени там также запечены в лайтмапы, видно, насколько тени от далёких источников мягкие и плавные. Однако, отдельные объекты, динамические в том числе, отбрасывают чёткие реалтайм тени.

Пример освещения в Half - life Alyx.

Пример освещения в Half - life Alyx.

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

Размытие теней при удалении от объектов в Hail to the Rainbow.

Размытие теней при удалении от объектов в Hail to the Rainbow.

Регулировка степени размытия.

Регулировка степени размытия.

Немного прокачать я решил и тени от Spot освещения. Мне хотелось достичь наибольшей мягкости и иметь возможность использовать размытые тени низкого разрешения. Тогда мне на глаза попалась статья, где описывался метод смешивания  Shadow maps в базовом шейдере обработки теней Shadow Library. Степень размытия я так же, как в примере привязал к параметру Range. В результате мне стала доступна более мягкая и ненавязчивая версия теней.

Размытие тени низкого разрешения.

Размытие тени низкого разрешения.

Рисуем светом.

Интересный подход в этот раз я решил использовать для акцентов освещения от Directional Light. Поскольку локации зимние и снег в основном однородный, изначальный вариант освещения солнца мне показался слишком скучным: заснеженные поля были однообразными, не было световых контрастов, художественных затенений и вообще какого-либо разнообразия.

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

Пример локации с движущимися тенями от облаков и световыми акцентами.

Пример локации с движущимися тенями от облаков и световыми акцентами.

В канале G я нарисовал несколько рандомных пятен для имитации движущихся теней от облаков. В шейдере отрисовки Cookie к этому каналу добавлено смещение во времени, для анимации движения.

Пример Cookie карты для Directional Light.

Пример Cookie карты для Directional Light.

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

Еще один пример сцены с акцентами освещения.

Еще один пример сцены с акцентами освещения.

Volumetric Light.

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

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

Сцены с полноценным (честным) волюметрик светом.

Сцены с полноценным (честным) волюметрик светом.

Наиболее ходовым стали обычные процедурные конусы с Soft Additive шейдером (тот же тип шейдеров, который обычно используется для мягких Particles). Также я использовал иногда и плоские спрайты, если эффект располагался далеко от игрока. Меши с мягким шейдером оказались достаточно простыми с точки зрения производительности, не имели артефактов и шумов, какие иногда дает постэффект при низких настройках.

Фейковый конус-волюметрик.

Фейковый конус-волюметрик.

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

Яркий свет за пределами здания.

Яркий свет за пределами здания.

Особенно активно я использовал простейшие спрайты, а именно компонент Sprite Renderer с мягким шейдером, в кат-сценах игры. Практически во всех заставках присутствуют спрайты для подчеркивания контрастов и придания глубины: на задних планах, за персонажем, иногда в качестве засветов на переднем плане и т.д.

Пример кат-сцены с использованием световых спрайтов.

Пример кат-сцены с использованием световых спрайтов.

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