Внутренняя архитектура рендеринга
Эта страница представляет собой общий обзор внутреннего устройства рендерера Godot 4. Она не применима к предыдущим версиям Godot.
Цель этой страницы — документировать принятые проектные решения, наилучшим образом соответствующие Философии дизайна Godot, а также предоставить отправную точку для новых участников рендеринга.
Если у вас есть вопросы по внутренним компонентам рендеринга, на которые здесь нет ответов, смело задавайте их на канале #rendering в Godot Contributors Chat.
Примечание
Если у вас возникли трудности с пониманием концепций на этой странице, рекомендуется ознакомиться с учебным пособием по OpenGL, например LearnOpenGL.
Современные низкоуровневые API (Vulkan/Direct3D 12/Metal) требуют для эффективного использования промежуточных знаний высокоуровневых API (OpenGL/Direct3D 11). К счастью, разработчикам редко приходится работать напрямую с низкоуровневыми API. Рендереры Godot полностью построены на OpenGL и RenderingDevice, который является нашей абстракцией над Vulkan/Direct3D 12/Metal.
Методы рендеринга
Forward+
Это прямой рендерер, использующий кластерный подход к освещению.
Кластерное освещение использует вычислительный шейдер для группировки источников света в трёхмерную сетку, выровненную по пирамиде. Затем, во время рендеринга, пиксели могут определить, какие источники света влияют на ячейку сетки, в которой они находятся, и выполнять расчёты только для тех источников света, которые могут повлиять на этот пиксель.
Такой подход может значительно повысить производительность рендеринга на настольном оборудовании, но существенно менее эффективен на мобильных устройствах.
Мобильные устройства
Это прямой рендерер, использующий традиционный однопроходный подход к освещению. Внутреннее название — Forward Mobile.
Предназначен для мобильных платформ, но может работать и на настольных компьютерах. Этот метод рендеринга оптимизирован для высокой производительности на мобильных графических процессорах. Архитектура мобильных графических процессоров существенно отличается от архитектуры настольных из-за специфических ограничений, связанных с потреблением заряда батареи, тепловыделением и общей пропускной способностью при чтении и записи данных. Вычислительные шейдеры также поддерживаются очень ограниченно или не поддерживаются вовсе. В результате мобильный рендерер использует исключительно растровые шейдеры (фрагментные/вершинные).
В отличие от настольных графических процессоров, мобильные графические процессоры выполняют тайловый рендеринг. Вместо того, чтобы визуализировать всё изображение как единое целое, оно делится на более мелкие тайлы, помещающиеся в более быструю внутреннюю память мобильного графического процессора. Каждый тайл визуализируется и затем записывается в целевую текстуру. Всё это происходит автоматически в графическом драйвере.
Проблема в том, что это создаёт узкие места в нашем традиционном подходе. При рендеринге на десктопе мы сначала рендерим всю непрозрачную геометрию, затем обрабатываем фон, затем прозрачную геометрию и, наконец, постобработку. Каждый проход должен считывать текущий результат в память тайлов, выполнять необходимые операции и затем записывать его обратно. Затем мы дожидаемся завершения всех тайлов, прежде чем перейти к следующему проходу.
Первое важное изменение в мобильном рендерере заключается в том, что он не использует формат текстур RGBA16F, как десктопный рендерер. Вместо этого он использует формат текстур R10G10B10A2 UNORM. Это вдвое сокращает требуемую полосу пропускания и обеспечивает дополнительные преимущества, поскольку мобильное оборудование часто дополнительно оптимизирует графику под 32-битные форматы. Однако мобильный рендерер имеет ограниченные возможности HDR из-за снижения точности и максимальных значений цветовых данных.
Второе важное изменение — это использование подпроходов везде, где это возможно. Подпроходы позволяют нам выполнять этапы рендеринга сквозным образом для каждого тайла, экономя на накладных расходах, связанных с чтением и записью данных в тайлы между каждым проходом рендеринга. Возможность использования подпроходов ограничена невозможностью чтения соседних пикселей, поскольку мы вынуждены работать только в пределах одного тайла.
Это ограничение подпроходов приводит к невозможности эффективной реализации таких функций, как свечение и глубина резкости. Аналогично, если требуется чтение текстуры экрана или текстуры глубины, необходимо полностью записать результат рендеринга, что ограничивает возможности использования подпроходов. При включении таких функций используется сочетание подпроходов и обычных проходов, что приводит к заметному снижению производительности.
На настольных платформах использование подпроходов не повлияет на производительность. Тем не менее, этот метод рендеринга может работать лучше, чем Forward+, в простых сценах благодаря меньшей сложности и меньшему потреблению полосы пропускания. Это особенно заметно на слабых видеокартах, интегрированной графике или в VR-приложениях.
Учитывая его низкоуровневую направленность, этот метод рендеринга не предоставляет таких высококлассных функций, как SDFGI и Объёмный туман и объёмы тумана. Также недоступны некоторые эффекты постобработки.
Совместимость
Примечание
Это единственный метод рендеринга, доступный при использовании драйвера OpenGL. Он недоступен при использовании Vulkan, Direct3D 12 и Metal.
Это традиционный (не-кластерный) прямой рендерер. Внутри компании он называется GL Compatibility. Он предназначен для старых видеокарт без поддержки Vulkan, но всё ещё очень эффективно работает на новом оборудовании. В частности, он оптимизирован для старых и недорогих мобильных устройств. Однако многие оптимизации переносятся и на старые, что делает его хорошим выбором для старых и недорогих настольных компьютеров.
Как и Mobile рендерер, рендерер Compatibility использует текстуру R10G10B10A2 UNORM для 3D-рендеринга. В отличие от мобильного рендерера, цвета подвергаются тональной компрессии и хранятся в формате sRGB, поэтому поддержка HDR отсутствует. Это позволяет избежать необходимости в дополнительном проходе тональной компрессии и использовать низкобитную текстуру без существенного образования полос.
Визуализатор Compatibility использует традиционный однопроходный подход к отрисовке объектов с источниками света, но многопроходный подход используется для отрисовки источников света с тенями. В частности, в первом проходе он может отрисовывать несколько источников света без теней и до одного источника DirectionalLight3D с тенями. В каждом последующем проходе он может отрисовывать до одного источника OmniLight3D, одного источника SpotLight3D и одного источника DirectionalLight3D с тенями. Источники света с тенями будут влиять на сцену иначе, чем источники света без теней, поскольку смешивание света происходит в пространстве sRGB, а не в линейном пространстве. Это различие в освещении повлияет на внешний вид сцены и должно учитываться при проектировании сцен для визуализатора совместимости.
Учитывая его низкоуровневую направленность, этот метод рендеринга не обеспечивает высококлассных возможностей рендеринга (тем более по сравнению с Mobile). Большинство эффектов постобработки недоступны.
Почему не использовать отложенный рендеринг?
Forward (Упреждающий) рендеринг обычно обеспечивает лучший баланс между производительностью и гибкостью, особенно при использовании кластерного подхода к освещению. Хотя deferred (отложенный) рендеринг в некоторых случаях может быть быстрее, он также менее гибок и требует хаков для использования MSAA. Поскольку игры с менее реалистичной графикой могут значительно выиграть от MSAA, мы решили использовать упреждающий рендеринг для Godot 4 (как и Godot 3).
При этом некоторые части forward рендеринга выполняются с отложенным подходом, чтобы обеспечить некоторую оптимизацию, когда это возможно. Это особенно актуально для VoxelGI и SDFGI.
В будущем может быть разработан кластерный developed (отложенный) рендерер. Такой рендерер можно использовать в ситуациях, когда производительность важнее гибкости.
Драйверы рендеринга
Godot 4 поддерживает следующие графические API:
Vulkan
Это основной драйвер в Godot 4, и большая часть разработки сосредоточена именно на нем.
Vulkan 1.0 требуется в качестве базовой версии, а дополнительные функции Vulkan 1.1 и 1.2 используются при их наличии. volk используется в качестве загрузчика Vulkan, а Vulkan Memory Allocator используется для управления памятью.
При использовании драйвера Vulkan поддерживаются методы Forward+ и Mobile Методы рендеринга.
Создание контекста Vulkan:
Создание контекста Direct3D 12:
Direct3D 12
Как и Vulkan, драйвер Direct3D 12 предназначен только для современных платформ. Он разработан как для Windows, так и для Xbox (тогда как Vulkan нельзя использовать напрямую на Xbox).
Оба метода Forward+ и Mobile Методы рендеринга можно использовать с Direct3D 12.
Основные шейдеры используются совместно с рендерером Vulkan. Шейдеры транспилируются из SPIR-V в DXIL с помощью Mesa NIR (подробнее).
Этот драйвер всё ещё находится в экспериментальном состоянии и доступен только в Godot 4.3 и более поздних версиях. Хотя Direct3D 12 поддерживает эксклюзивные функции Direct3D в Windows 11, такие как оконная оптимизация и Auto HDR, Vulkan по-прежнему рекомендуется для большинства проектов. Подробнее см. в запросе на включение изменений, который ввёл поддержку Direct3D 12 <https://github.com/godotengine/godot/pull/70315>`__.
Metal
Godot предоставляет нативный драйвер Metal, работающий на всём оборудовании Apple Silicon (macOS ARM). По сравнению с использованием слоя трансляции MoltenVK, это значительно быстрее, особенно в сценариях, требовательных к процессору.
Оба метода: Forward+ и Mobile Методы рендеринга можно использовать с Metal.
Основные шейдеры используются совместно с рендерером Vulkan. Шейдеры транспилируются из GLSL в MSL с помощью SPIRV-Cross.
Godot также поддерживает рендеринг Metal через MoltenVK, который используется в качестве запасного варианта, когда встроенная поддержка Metal недоступна (например, на x86 macOS).
Этот драйвер все еще является экспериментальным и доступен только в Godot 4.4 и более поздних версиях. Для получения дополнительной информации см. запрос на извлечение, который ввел поддержку Metal.
OpenGL
Этот драйвер использует OpenGL ES 3.0 и предназначен для устаревших и бюджетных устройств, не поддерживающих Vulkan. Для работы этого драйвера на настольных платформах используется профиль OpenGL 3.3 Core Profile, поскольку большинство графических драйверов для настольных компьютеров не поддерживают OpenGL ES. Для экспорта в веб используется WebGL 2.0.
Можно использовать OpenGL ES 3.0 непосредственно на настольных платформах, передав аргумент командной строки --rendering-driver opengl3_es, хотя это будет работать только на графических драйверах, которые имеют собственную поддержку OpenGL ES (например, Mesa).
С драйвером OpenGL можно использовать только метод рендеринга Совместимость.
Основные шейдеры полностью отличаются от рендерера Vulkan.
Многие расширенные функции не поддерживаются этим драйвером, поскольку он ориентирован в первую очередь на бюджетные устройства.
Сводка драйверов/методов рендеринга
В настоящее время возможны следующие комбинации API рендеринга + метода рендеринга:
Vulkan + Forward+ (опционально через MoltenVK на macOS и iOS)
Vulkan + Mobile (опционально через MoltenVK на macOS и iOS)
Direct3D 12 + Forward+
Direct3D 12 + Mobile
Metal + Forward+
Metal + Mobile
OpenGL + Compatibility (опционально через ANGLE на Windows и macOS)
У каждой комбинации есть свои ограничения и характеристики производительности. По возможности обязательно протестируйте свои изменения на всех методах рендеринга, прежде чем открывать запрос на извлечение.
Абстракция RenderingDevice
Примечание
Драйвер OpenGL не использует абстракцию RenderingDevice.
Чтобы сделать сложность современных низкоуровневых графических API более управляемой, Godot использует собственную абстракцию под названием RenderingDevice.
Это означает, что при написании кода для современных методов рендеринга вы фактически не используете API Vulkan, Direct3D 12 или Metal напрямую. Хотя это всё ещё более низкоуровневое API, чем OpenGL, это упрощает работу над рендерером, поскольку RenderingDevice абстрагирует многие особенности, специфичные для API. RenderingDevice представляет собой уровень абстракции, аналогичный WebGPU.
Выполнение Vulkan RenderingDevice:
Реализация Direct3D 12 RenderingDevice:
Реализация Metal RenderingDevice:
Архитектура основных классов рендеринга
На этой диаграмме представлена структура классов рендеринга в Godot, включая абстракцию RenderingDevice:
Основные шейдеры
В то время как шейдеры в проектах Godot пишутся с использованием custom language inspired by GLSL, основные шейдеры пишутся непосредственно на GLSL.
Эти базовые шейдеры встроены в редактор и экспортируют двоичные файлы шаблонов во время компиляции. Чтобы увидеть любые изменения, внесённые в эти шейдеры GLSL, необходимо перекомпилировать редактор или экспортировать двоичный файл шаблона.
Некоторые характеристики материала, такие как отображение высот, преломление и затухание при приближении, не входят в базовые шейдеры и реализуются в стандартном шейдере BaseMaterial3D с использованием языка шейдеров Godot (не GLSL). Это достигается процедурной генерацией необходимого кода шейдера в зависимости от характеристик, включённых в материале.
По соглашению, файлы шейдеров, содержащие _inc в имени, включаются в другие файлы GLSL для более эффективного повторного использования кода. Для этого используется стандартная предварительная обработка GLSL.
Предупреждение
Шейдеры основных материалов будут использоваться всеми материалами в сцене – как со стандартным BaseMaterial3D, так и с пользовательскими шейдерами. Поэтому эти шейдеры должны быть максимально простыми, чтобы избежать проблем с производительностью и гарантировать, что компиляция шейдеров не станет слишком медленной.
Использование ветвления if в шейдере может привести к снижению производительности из-за увеличения использования VGPR в шейдере. Это происходит даже если все пиксели в данном кадре оцениваются как true (истина) или false (ложь).
При использовании препроцессорного ветвления #if количество требуемых версий шейдеров в сцене увеличится. В худшем случае добавление одного логического значения #define может удвоить количество версий шейдеров, которые может потребоваться скомпилировать в данной сцене. В некоторых случаях константы специализации Vulkan могут быть использованы как более быстрая (но и более ограниченная) альтернатива.
Это означает, что добавление новых встроенных функций материалов в Godot затруднено, как в базовые шейдеры, так и в BaseMaterial3D. Хотя BaseMaterial3D может использовать динамическую генерацию кода, чтобы включать код шейдера только при включении этой функции, при использовании этих функций в проекте всё равно потребуется генерировать больше версий шейдеров. Это может сделать подтормаживания компиляции шейдеров более заметными в сложных 3D-сценах.
Дополнительную информацию см. в сообщениях блога Проблема Перестановки Шейдеров и Ветвление на графическом процессоре.
Основные шейдеры материалов GLSL:
Forward+: servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl
Mobile: servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
Compatibility: drivers/gles3/shaders/scene.glsl
Генерация шейдера материала:
Другие шейдеры GLSL для методов рендеринга Forward+ и Mobile:
Другие шейдеры GLSL для метода рендеринга Compatibility:
Разделение 2D и 3D рендеринга
Примечание
Следующее применимо только к методам рендеринга Forward+ и Mobile, но не к Compatibility. Для эмуляции этого при использовании Compatibility-рендера или для масштабирования разрешения 2D можно использовать несколько областей просмотра.
2D и 3D визуализируются в отдельных буферах, поскольку 2D-рендеринг в Godot выполняется в sRGB-пространстве LDR тогда как 3D-рендеринг использует линейное пространство HDR.
Для 2D-рендеринга используется цветовой формат RGB8 (RGBA8, если включено свойство Прозрачность на области просмотра). 3D-рендеринг использует 24-битный беззнаковый нормализованный целочисленный буфер глубины или 32-битный знаковый буфер с плавающей запятой, если 24-битный буфер глубины не поддерживается оборудованием. 2D-рендеринг не использует буфер глубины.
Масштабирование 3D-разрешения выполняется по-разному в зависимости от того, используется ли билинейное масштабирование или масштабирование FSR 1.0. При билинейном масштабировании специальный шейдер для повышения разрешения не запускается. Вместо этого текстура области просмотра растягивается и отображается с помощью линейного сэмплера (что обеспечивает фильтрацию непосредственно на аппаратном уровне). Это позволяет максимально повысить производительность билинейного 3D-масштабирования.
Функция configure() в RenderSceneBuffersRD перераспределяет 2D/3D-буферы при изменении разрешения или масштабирования.
Динамическое масштабирование разрешения пока не поддерживается, но планируется в будущей версии Godot.
Код C++ конфигурации буфера 2D- и 3D-рендеринга:
FSR 1.0:
Методы 2D-рендеринга
2D-рендеринг освещения выполняется за один проход, что обеспечивает лучшую производительность при большом количестве источников света.
Во всех методах рендеринга реализована 2D пакетная обработка для повышения производительности, что особенно заметно при большом количестве текста на экране.
MSAA можно включить в 2D для "автоматического" сглаживания линий и полигонов, но FXAA не влияет на 2D-рендеринг, поскольку рассчитывается до его начала. Методы 2D-отрисовки Godot, такие как узел Line2D или некоторые методы draw_*() элемента CanvasItem, предоставляют собственный способ сглаживания, основанный на полосах треугольников и цветах вершин, для работы которого MSAA не требуется.
2D поле расстояний со знаком, представляющее узлы LightOccluder2D в области просмотра, автоматически генерируется по запросу пользовательского шейдера. Его можно использовать для различных эффектов в пользовательских шейдерах, например, для глобального 2D освещения. Оно также используется для расчета столкновений частиц в 2D пространстве.
2D SDF-генерация шейдера GLSL:
Методы 3D-рендеринга
Пакетирование и создание экземпляров
В рендерере Forward+ для группового рендеринга идентичных непрозрачных или альфа-тестированных объектов используется инстансирование Vulkan для повышения производительности. (Объекты с альфа-смешением никогда не инстансируются.) Это не так быстро, как статическое слияние сеток, но всё же позволяет отбирать экземпляры по отдельности.
Визуализация светового, декаль- и отражательного зондов
Примечание
Визуализация декалей в настоящее время недоступна в средстве визуализации Compatibility .
Рендерер Forward+ использует кластерное освещение. Это позволяет использовать столько источников света, сколько нужно; производительность во многом зависит от покрытия экрана. Бестеневые источники света могут быть практически бесплатными, если они не занимают много места на экране.
Все методы рендеринга также поддерживают рендеринг до 8 направленных источников света одновременно (хотя и с более низким качеством теней, если тени включены для более чем одного источника света).
Мобильный рендерер использует однопроходный подход к освещению с ограничением в 8 источников OmniLight + 8 источников SpotLight, воздействующих на каждый ресурс Mesh (плюс ограничение в 256 источников OmniLight + 256 источников SpotLight в поле зрения камеры). Эти ограничения жестко заданы и не могут быть изменены в настройках проекта.
В рендерере Compatibility используется гибридный подход к освещению: однопроходный и многопроходный. Источники света без теней визуализируются за один проход. Источники света с тенями визуализируются за несколько проходов. Это необходимо для повышения производительности на мобильных устройствах. В результате производительность плохо масштабируется при наличии большого количества источников света, отбрасывающих тени. Рекомендуется размещать в пирамиде видимости камеры одновременно лишь несколько источников света с тенями и распределять их так, чтобы каждый объект попадал под один или два источника света с тенями одновременно. Максимальное количество источников света, видимых одновременно, можно настроить в настройках проекта.
Во всех 3 методах освещение без теней значительно дешевле освещения с тенями. Для повышения производительности освещение обновляется только при изменении самого источника света или объектов в его радиусе. Godot в настоящее время не разделяет рендеринг статических и динамических теней, но это планируется в будущих версиях.
Кластеризация также используется для отражательных зондов и рендеринга декалей в рендерере Forward+.
Наложение теней
Оба метода, Forward+ и Mobile, используют PCF для фильтрации карт теней и создания мягкой полутени. Вместо фиксированного шаблона PCF эти методы используют шаблон диска Фогеля, который позволяет изменять количество сэмплов и плавно изменять качество.
Godot также поддерживает мягкие тени по методу percentage-closer soft shadows (PCSS) для более реалистичного рендеринга полутеней. Тени PCSS доступны только в отрисовщике Forward+, так как они слишком требовательны для использования в отрисовщике Mobile. PCSS также использует ядро в форме диска Фогеля.
Кроме того, оба метода теневого отображения вращают ядро на попиксельной основе, помогая смягчить артефакты недостаточной выборки.
Модуль рендеринга Compatibility поддерживает теневое отображение для источников света DirectionalLight3D, OmniLight3D и SpotLight3D.
Временное сглаживание
Примечание
Доступно только в рендерере Forward+, но не в Mobile или Compatibility рендерах.
Godot использует собственную реализацию TAA, основанную на старой реализации TAA из Spartan Engine.
Для работы временного сглаживания необходимы векторы движения. Если векторы движения сгенерированы неправильно, при движении камеры или объектов возникнет двоение изображения.
Векторы движения генерируются на графическом процессоре в основном шейдере материала. Это достигается путём запуска вершинного шейдера, соответствующего предыдущему отрендеренному кадру (с предыдущим преобразованием камеры), в дополнение к вершинному шейдеру для текущего отрендеренного кадра, с последующим сохранением разницы между ними в цветовом буфере.
Альтернативно, FSR 2.2 можно использовать в качестве решения для масштабирования, которое также предоставляет собственный алгоритм временного сглаживания. FSR 2.2 реализован поверх абстракции RenderingDevice, а не напрямую с использованием референсного кода AMD.
Решение TAA:
FSR 2.2:
Глобальное освещение
Примечание
VoxelGI и SDFGI доступны только в рендерере Forward+, но не в Мобильных или Совместимых рендерах.
Запекание LightmapGI доступно только в рендерах Forward+ и Mobile и может быть выполнено только в редакторе (не в экспортированном проекте). Рендеринг LightmapGI поддерживается рендером Compatibility.
Godot поддерживает GI (глобальное освещение) на основе вокселей (VoxelGI), GI на основе знаков расстояний (SDFGI), а также запекание и рендеринг карт освещения (LightmapGI). При желании эти методы можно использовать одновременно.
Запекание карт освещения происходит на графическом процессоре с использованием вычислительных шейдеров Vulkan. Графический редактор освещения реализован в классе LightmapperRD, который наследует класс Lightmapper. Это позволяет реализовать дополнительные редакторы освещения, открывая путь к будущему портированию процессорного редактора освещения, представленного в Godot 3.x. Это позволит запекать карты освещения при использовании рендера Compatibility.
Core GI C++ код:
scene/3d/voxel_gi.cpp - узел VoxelGI
editor/plugins/voxel_gi_editor_plugin.cpp - пользовательский интерфейс редактора для узла VoxelGI
Основные шейдеры GI GLSL:
servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl
servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl - режим отладки отрисовки VoxelGI
servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl - режим отладки отрисовки каскадов SDFGI
servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl - режим отладки отрисовки зондов SDFGI
servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl
servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl
servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl
Код Lightmapper C++:
scene/3d/lightmap_gi.cpp - узел LightmapGI
editor/plugins/lightmap_gi_editor_plugin.cpp - Пользовательский интерфейс редактора для узла LightmapGI
scene/3d/lightmapper.cpp - класс Abstract
modules/lightmapper_rd/lightmapper_rd.cpp - Реализация светового картографа на базе GPU
Шейдеры Lightmapper GLSL:
Глубина резкости
Примечание
Доступно только в рендерах Forward+ и Mobile, но не в рендере Compatibility.
Рендереры Forward+ и Mobile используют разные подходы к рендерингу глубины резкости, что приводит к разным визуальным результатам. Это делается для наилучшего соответствия характеристикам производительности целевого оборудования. В Forward+ глубина резкости вычисляется с помощью вычислительного шейдера. В Mobile глубина резкости вычисляется с помощью фрагментного (растрового) шейдера.
Доступны формы боке (‘bokeh’) в виде прямоугольника, шестиугольника и круга (от самой быстрой до самой медленной). При включенном временном сглаживании глубину резкости можно подвергать случайному смещению (jitter) в каждом кадре для улучшения её внешнего вида.
Код глубины резкости C++:
GLSL-шейдер глубины резкости (вычислительный — используется для Forward+):
GLSL-шейдер глубины резкости (растровый — используется для Mobile устройств):
Эффекты экранного пространства (SSAO, SSIL, SSR, SSS)
Примечание
Доступно только в рендерере Forward+, но не в Mobile или Compatibility рендерах.
Модуль рендеринга Forward+ поддерживает затенение окружающего пространства в экранном пространстве, непрямое освещение в экранном пространстве, отражения в экранном пространстве и подповерхностное рассеивание.
SSAO использует реализацию, производную от Intel ASSAO (конвертированную в Vulkan). SSIL создан на основе SSAO для обеспечения высокопроизводительного непрямого освещения.
Если включены и SSAO, и SSIL, части SSAO и SSIL используются совместно, чтобы снизить влияние на производительность.
SSAO и SSIL по умолчанию выполняются с половинным разрешением для повышения производительности. SSR всегда выполняется с половинным разрешением для повышения производительности.
Код C++ эффектов экранного пространства:
Шейдер GLSL для экранного пространства с затенением:
servers/rendering/renderer_rd/shaders/effects/ssao_blur.glsl
servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl
servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl
Шейдер GLSL для непрямого освещения в экранном пространстве:
servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl
servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl
servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl
Шейдер GLSL отражений в экранном пространстве:
servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_scale.glsl
servers/rendering/renderer_rd/shaders/effects/screen_space_reflection_filter.glsl
Подповерхностное рассеяние GLSL:
Рендеринг Sky
См. также
Godot поддерживает использование шейдеров для рендеринга фона неба. Карта яркости (используемая для создания фонового освещения и отражений для PBR-материалов) автоматически обновляется на основе шейдера неба.
Ресурсы SkyMaterial, такие как ProceduralSkyMaterial, PhysicalSkyMaterial и PanoramaSkyMaterial, генерируют встроенный шейдер для рендеринга неба. Он аналогичен тому, что BaseMaterial3D предоставляет для материалов 3D-сцен.
Подробную техническую реализацию можно найти в статье Пользовательские шейдеры неба в Godot 4.0.
Код C++ для рендеринга неба:
servers/rendering/renderer_rd/environment/sky.cpp - Sky rendering
scene/resources/sky.cpp - Sky resource (not to be confused with sky rendering)
scene/resources/sky_material.cpp SkyMaterial resources (used in the Sky resource)
GLSL-шейдер для рендеринга неба:
Объемный туман
Примечание
Доступно только в рендерере Forward+, но не в Mobile или Compatibility рендерах.
См. также
Godot поддерживает подход на основе вокселей, выровненных по усечённой пирамиде видимости (froxel), для рендеринга объёмного тумана. В отличие от фильтра постобработки, этот подход более универсален, поскольку работает с любым типом освещения. Fog также может использовать шейдеры для создания настраиваемого поведения, что позволяет анимировать туман или использовать 3D-текстуру для представления плотности.
Ресурс FogMaterial генерирует встроенный шейдер для узлов FogVolume. Он аналогичен шейдеру BaseMaterial3D для материалов 3D-сцены.
Подробное техническое объяснение можно найти в статье Fog Volumes arrive in Godot 4.0.
Код C++ для создания объемного тумана:
servers/rendering/renderer_rd/environment/fog.cpp - General volumetric fog
scene/3d/fog_volume.cpp - FogVolume node
scene/resources/fog_material.cpp - FogMaterial resource (used by FogVolume)
Шейдеры GLSL для объемного тумана:
Отбраковка окклюзии
Хотя современные графические процессоры могут справиться с отрисовкой большого количества треугольников, количество вызовов отрисовки в сложных сценах все еще может быть узким местом (даже с Vulkan, Direct3D 12 и Metal).
Godot 4 поддерживает отбраковку окклюзии для уменьшения перерисовки (при отключенном предварительном проходе по глубине) и снижения пропускной способности вершин. Это достигается путём растеризации буфера низкого разрешения на CPU с помощью Embree. Разрешение буфера зависит от количества потоков CPU в системе, поскольку обработка выполняется параллельно. Этот буфер содержит формы окклюзии, запечённые в редакторе или созданные во время выполнения.
Поскольку сложные окклюдеры могут создавать большую нагрузку на CPU, готовые окклюдеры можно автоматически упрощать при их создании в редакторе.
Отбраковка окклюдеров в Godot пока не поддерживает динамические окклюдеры, но узлы OccluderInstance3D по-прежнему можно переключать и перемещать. Однако при таком обновлении сложных окклюдеров это будет работать медленно. Поэтому обновление окклюдеров во время выполнения лучше всего выполнять только для простых форм окклюдеров, таких как четырёхугольники или кубоиды.
Такой подход на базе CPU имеет несколько преимуществ по сравнению с другими решениями, такими как порталы и комнаты или решение по отсечению на базе GPU:
Ручная настройка не требуется (но ее можно настроить вручную для достижения наилучшей производительности).
Отсутствует задержка кадров, которая является проблемой в сценах смены камер или при быстром движении камеры за стеной.
Работает одинаково на всех драйверах и методах рендеринга, без непредсказуемого поведения в зависимости от драйвера или оборудования графического процессора.
Отбраковка окклюзии выполняется путём регистрации сеток окклюдера с помощью узлов OccluderInstance3D (которые, в свою очередь, используют ресурсы Occluder3D). Затем RenderingServer выполняет отбраковку окклюзии, вызывая Embree в RendererSceneOcclusionCull.
Код C++ для отсечения окклюзии:
Дальность видимости (LOD)
Godot поддерживает созданный вручную иерархический уровень детализации (HLOD) с расстояниями, указанными пользователем в инспекторе.
В RenderingSceneCull функции _scene_cull() и _render_scene() отвечают за определение большей части уровня детализации. Каждая область просмотра может отображать одну и ту же сетку с разным уровнем детализации (что обеспечивает корректный рендеринг на разделенном экране).
Код C++ диапазона видимости:
Автоматическая сетка LOD
Класс ImporterMesh используется для импорта 3D-сеток в редакторе. Его функция generate_lods() управляет генерацией с помощью библиотеки meshoptimizer.
Генерация LOD-сетки одновременно генерирует теневые сетки. Это сетки, вершины которых объединены независимо от сглаживания и материалов. Это используется для повышения производительности рендеринга теней за счёт снижения пропускной способности вершин, необходимой для рендеринга теней.
Функция _render_scene() класса RenderingSceneCull определяет, какой уровень детализации сетки следует использовать при рендеринге. Каждая область просмотра может отображать одну и ту же сетку с разными LODs (уровнями детализации) (что обеспечивает корректный рендеринг на разделенном экране).
Уровень детализации сетки автоматически выбирается на основе метрики покрытия экрана. При этом учитываются изменения разрешения и поля зрения камеры без вмешательства пользователя. Пороговый множитель можно настроить в настройках проекта.
Для повышения производительности рендеринг теней и рендеринг отражательных зондов также выбирают собственные пороговые значения уровня детализации сетки (которые могут отличаться от рендеринга основной сцены).
Генерация уровня детализации сетки при импорте кода C++:
Код C++ для определения уровня детализации сетки: