Разработка кастомных шейдеров постобработки графики

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

От иммерсивных приложений до игровых миров и 3D-сцен

Наша выделенная команда для VR/AR/MR-разработки, Unity-продакшна и 3D-моделирования и анимации с собственными кейсами и презентациями.

Посетить персонализированный сайт
Показано 1 из 1 услугВсе 242 услуг
Разработка кастомных шейдеров постобработки графики
Сложная
от 2 рабочих дней до 2 недель
Часто задаваемые вопросы
Наши компетенции
Какие этапы разработки игры?
Последние работы
  • image_games_mortal_motors_495_0.webp
    Разработка игры для компании Mortal Motors
    671
  • image_games_a_turnbased_strategy_game_set_in_a_fantasy_setting_with_fire_and_sword_603_0.webp
    Пошаговая стратегия в фэнтези сеттинге With Fire And Sword
    860
  • image_games_second_team_604_0.webp
    Разработка игры для компании Second term
    490
  • image_games_phoenix_ii_606_0.webp
    3D-анимация — тизер для игры phoenix 2.
    533

Разработка кастомных шейдеров постобработки графики

Встроенные Volume эффекты в URP и HDRP — Bloom, Color Grading, Vignette — закрывают базовые потребности, но как только нужен нестандартный визуальный эффект (тепловое марево над асфальтом, хроматическая аберрация с кастомной кривой, pixel art posterization, outline detection по depth buffer) — начинается территория кастомных Renderer Feature и полноэкранных Blit Shader'ов.

В Unity 2022+ архитектура кастомного постпроцесса изменилась. Старый подход через OnRenderImage и CommandBuffer.Blit устарел. Новый стандарт — ScriptableRendererFeature + ScriptableRenderPass с Blitter.BlitCameraTexture.

Как устроен ScriptableRendererFeature в URP

ScriptableRendererFeature — это точка входа для добавления кастомного render pass в URP pipeline. Он регистрирует ScriptableRenderPass, который исполняется в заданном RenderPassEvent (BeforeRenderingPostProcessing, AfterRenderingPostProcessing и т.д.).

Внутри ScriptableRenderPass.Execute() правильный паттерн в Unity 6 / URP 17:

Blitter.BlitCameraTexture(cmd, source, destination, material, passIndex);

Это заменяет старый cmd.Blit(src, dst, mat). Разница не только синтаксическая: Blitter.BlitCameraTexture корректно обрабатывает VR single-pass instanced rendering и избегает UV flip артефактов в WebGL.

Материал для Blit использует Full Screen Shader Graph (тип графа Fullscreen Shader в URP ShaderGraph). В нём доступен URP Sample Buffer нода — он читает Color, Depth, Normal или Motion Vectors из G-Buffer. Это ключевое: без этой ноды нельзя сделать глубиноориентированные эффекты (outline по depth, depth of field кастомный) через ShaderGraph без написания HLSL.

Outline по Depth и Normal

Outline detection — частый запрос для стилизованных игр. Наивный подход: обводка через второй pass с увеличенными вершинами — работает для solid объектов, ломается на сложной геометрии и не даёт outline по силуэту сцены.

Правильный подход — полноэкранный edge detection через Depth и Normal buffers:

Depth-based edge: читаем глубину в текущем пикселе и соседних (4 или 8 соседей через Sample Texture 2D с offset). Если разница глубины превышает порог — пиксель на краю. Roberts Cross или Sobel operator — стандартные фильтры. В ShaderGraph: четыре Sample Texture ноды с ручными UV offset'ами (+1/-1 пиксель через Texel Size нода), вычисляем gradient magnitude.

Normal-based edge: аналогично по Normal buffer. Даёт линии там, где геометрия резко меняет направление нормали — это рёбра и складки поверхности, которые depth edge не видит. Комбинация depth + normal edge — стандарт для cel-shading outline.

Проблема depth outline: глубина в буфере не линейна, она записана в logarithmic или reversed-Z формате в зависимости от платформы. Прямое сравнение depth значений без linearization даёт неравномерную толщину линии. Нужно линеаризовать через LinearEyeDepth(depth, _ZBufferParams) — в ShaderGraph это Linear Eye Depth нода.

Тепловое марево и distortion эффекты

Screen-space distortion для heatwave или magic portal: Blit шейдер, который смещает UV текущего кадра по Normal map (flowing animated normal texture). Это простая идея, но в ней прячется проблема с render order.

Distortion шейдер должен работать с Opaque Texture (снимком экрана до прозрачных объектов). В URP это _CameraOpaqueTexture. Если эффект применяется как полноэкранный pass — он видит весь экран. Если нужен локализованный distortion (только над конкретным объектом, например горячим асфальтом) — нужен Distortion Renderer Feature, который рендерит distortion objects в отдельный render texture, затем применяет его как screen-space mask в финальном Blit.

Для HDRP distortion — встроенный Distortion render queue (отдельный от Transparent). Объекты с Distortion enabled автоматически попадают в distortion accumulation pass. Это проще, чем URP кастомный подход.

Типичные ошибки при разработке кастомных постэффектов

Wrong RenderPassEvent. Постэффект поставлен в BeforeRenderingPostProcessing — но должен быть после Bloom, иначе Bloom применяется поверх кастомного эффекта. Порядок событий в URP: Opaques → Skybox → Transparents → Post Processing → UI. Выбор RenderPassEvent определяет, где в этой очереди встанет кастомный pass.

Отсутствие Depth Priming Mode. На некоторых мобильных GPU (особенно Mali) глубинный буфер может быть недоступен при чтении в кастомном pass, если Depth Priming Mode в URP Renderer настроен на Auto вместо Forced. Это приводит к чёрному экрану или некорректным значениям глубины без каких-либо ошибок в консоли.

VR incompatibility. Кастомный шейдер постобработки, написанный без поддержки XR, ломается в VR — отрисовывается только для одного глаза или создаёт double-vision артефакт. Blitter.BlitCameraTexture автоматически обрабатывает это, но Custom Function ноды с ручным UV расчётом требуют UNITY_STEREO_EYE_INDEX_POST_VERTEX macro.

Тип постэффекта Срок
Простой fullscreen эффект (цветокоррекция, blur) 1–3 дня
Outline по depth/normal + настройка 3–5 дней
Distortion эффект (heatwave, portal) 3–6 дней
Сложный составной эффект (несколько passes) 1–2 недели

Стоимость рассчитывается индивидуально. Нужно знать рендер-пайплайн, платформу и наличие VR поддержки.