Да, но вам нужно сменить парадигму.
То, к чему вы привыкли, называется форвард рендерингом. Вы отправляете свою геометрию, а затем немедленно приступаете к проходу затенения. В базовом рендеринге вперед вы можете либо зациклить внутри шейдера для каждого источника света, либо выполнить один проход на источник света и смешать результат вместе (с аддитивным смешиванием).
Но многое изменилось. Входит: отложенный рендеринг
Теперь, когда есть так много вариантов, которые описывают их все в деталях, ответ здесь будет более чем приемлемым. Итак, здесь я просто собираюсь описать суть отложенного затенения, есть много других ресурсов, которые вы можете легко найти с помощью Google, надеюсь, после прочтения этого у вас будут правильные ключевые слова, чтобы найти то, что вам нужно.
Основная идея состоит в том, чтобы отложить затенение до окончания конвейера. У вас есть два основных шага:
- Рендеринг вашей геометрии и всей информации, необходимой для затенения в несколько целей рендеринга. Это означает, что обычно в базовой реализации у вас есть буфер глубины, буфер, содержащий нормали вашей геометрии и цвет альбедо. Вскоре вы обнаружите, что вам нужна другая информация о материалах (например, шероховатость, «металлический» фактор и т. Д.).
Это изображение из Википедии показывает три буфера (цвет, глубина и нормали)
Опять же, количество, тип и содержание используемых буферов довольно сильно различаются в разных проектах. Вы найдете набор буферов с именем GBuffers.
- После этого наступает время применения фактического освещения. Во время прохода освещения для каждого источника света вы хотите нарисовать объем света, который зависит от типа источника света:
- Для направленного света вы отображаете полноэкранный квад.
- Для точечного источника света вы визуализируете сферу, радиус которой основан на затухании вашего точечного источника света.
- Для точечного источника света вы создаете конус, размеры которого снова зависят от характеристик вашего источника света.
В пиксельном шейдере этого прохода вы передаете свои GBuffers и выполняете свое освещение и затенение, используя информацию, содержащуюся в них. Таким образом, вы обрабатываете только те пиксели, на которые воздействует каждый из источников света с заметным ускорением по сравнению с классическим рендерингом вперед.
Он также имеет различные недостатки, в частности, обработку прозрачных объектов и более высокое потребление полосы пропускания и видеопамяти. Но также сложнее обращаться с различными моделями материалов.
У вас есть и другие побочные преимущества (например, наличие большого количества информации, готовой к последующей обработке), а также ее довольно легко реализовать. Но это больше не самая крутая вещь для многих источников света.
Более новыми методами являются, например, Tiled Rendering . Основная идея заключается в том, чтобы разделить сцену на экранные «плитки» и назначить каждой плитке свет, воздействующий на нее. Это существует как в отложенном, так и в прямом направлении. Эти методы приводят к некоторым проблемам, когда у вас есть различные разрывы глубины в плитке, но, как правило, быстрее, чем у классической отсроченной, и это решает различные ее проблемы. Например, среди преимуществ, с использованием мозаичного отсрочки, вы считываете GBuffers один раз на освещенный фрагмент, а пиксели в одной и той же плитке последовательно обрабатывают одни и те же источники света.
Дальнейшее развитие на этой стороне - кластерное затенение, которое концептуально похоже на плиточные подходы, с использованием вместо плиток пространства экрана кластеров с трехмерным экстентом. Этот метод лучше справляется с проблемой разрывов глубины и обычно работает лучше, чем мозаичные методы.
ВАЖНОЕ ПРИМЕЧАНИЕ: я описал основы отложенного затенения. Существует множество вариаций, оптимизаций и улучшений, поэтому я призываю вас поэкспериментировать с простой версией, а затем провести некоторые исследования других методов, таких, которые я упоминал выше.