Отложенное затенение - это всего лишь методика «откладывания» фактической операции затенения для более поздних этапов, это может быть полезно для уменьшения количества проходов, необходимых (например) для визуализации 10 источников света, для которых требуется 10 проходов. Моя точка зрения заключается в том, что независимо от используемой вами технологии рендеринга, существуют определенные возможные оптимизации рендеринга, которые уменьшают количество объектов (вершин, нормалей и т. Д.), Которые необходимо обработать конвейером рендеринга.
Существует не де-факто стандарт для оптимизации рендеринга, а целый ряд методов, которые могут использоваться взаимозаменяемо или вместе для достижения определенных характеристик производительности. Использование каждой техники в значительной степени зависит от характера сцены.
Отложенный рендеринг пытается решить проблему при увеличении количества источников света, что при рендеринге в прямом направлении может привести к взрыву числа проходов.
Эти методы напрямую не оптимизируют часть отложенного затенения, но, согласно вашему описанию, часть отложенного затенения НЕ является вашей проблемой. Ваша проблема заключается в том, что вы отправляете всю сцену в конвейер рендеринга. Таким образом, ваш движок должен обработать (например, все 100 миллионов вершин) в вашей сцене только для того, чтобы иметь возможность отправить результат в g-буфер, в то время как большинство из этих 100 миллионов вершин могут быть просто отброшены, а не отправлены в предварительно обработать вершину и пройти фрагменты.
В случае прямого рендерера вершина N будет обрабатываться на стадии вершины как общее значение, vertex count*lights count
а на стадии фрагмента - как общее значение fragments count*number Lights
, отложенное затенение эффективно уменьшает это значение только vertex count
для стадии вершины и fragments count
для количества фрагментов перед разрешением фактическое затенение. Но все же N может быть слишком большим для обработки, особенно когда большинство из них можно тривиально отбраковать.
Это делает отбор более эффективным в случае прямого рендеринга / нескольких проходов. Но имейте в виду, что большинство движков будет использовать подход двойного рендеринга, потому что одно только отложенное затенение не может разрешить прозрачные объекты, это делает использование этих оптимизаций обязательным, я не знаю ни одного коммерческого движка, который делает все это.
Отбор Frustum
Только объекты, которые полностью или частично включены в усеченный вид, когда-либо должны быть переданы в конвейер рендеринга. Это основная концепция отбраковки усеченного конуса, к сожалению, проверка того, находится ли сетка в / за пределами усеченного ракурса, может быть дорогостоящей операцией, поэтому разработчики движка используют приблизительный ограничивающий объем, такой как (AABB) ограничивающая ось выравнивания по оси или ограничивающая сфера. даже если это может быть не так точно, как при использовании реальной сетки, разница в точности не стоит проверять с помощью реальной сетки.
Даже с ограничивающими томами вам не нужно проверять каждый из них, в качестве альтернативы вы можете построить иерархию ограничивающих томов для более раннего отбора, используя это в значительной степени зависит от сложности сцены.
Это хорошая и простая техника для двигателя меньшего размера, и она почти используется в каждом двигателе, который я когда-либо использовал. Я рекомендую использовать «нормальную» проверку Bounding Volume / Frustum без иерархий, если ваш движок не требует рендеринга очень сложных сцен.
Отбраковка спины
Это обязательно, зачем рисовать грани, которые все равно не будут видны? API-интерфейсы рендеринга предоставляют интерфейс для включения / выключения отбраковки задней поверхности Если у вас нет веской причины, почему бы не включить его, как в некоторых приложениях САПР, которым необходимо при определенных обстоятельствах рисовать заднюю поверхность, это необходимо сделать.
Окклюзия выбраковка
Используя Z-буфер, вы можете разрешить определение видимости. Но проблема в том, что Z-буфер не всегда хорош с точки зрения производительности, поскольку Z-буфер может быть разрешен только на более поздних этапах конвейера, объекты, подлежащие окклюзии, должны быть растеризованы и могут быть записаны в Z-буфер и Цветовой буфер перед неудачей теста Z.
Отбор окклюзии решает эту проблему, выполняя некоторые ранние тесты, чтобы отобрать окклюдированные объекты, которые находятся в усечённой области рендеринга. Одной из практических реализаций отбора окклюзии является использование запросов на основе точек и проверка, видимы ли определенные объекты с определенной точки зрения. Это также может быть использовано для отбраковки источников света, которые не влияют на окончательное изображение, это особенно полезно в отложенном механизме рендеринга.
Отличным примером такой техники в реальном мире является GTA5, где небоскребы, расположенные в центре города, не только украшают, но и служат окклюдерами, эффективно закрывая остальную часть города и предотвращая ее растеризации.
Уровень проработанности деталей
Уровень детализации является широко используемой техникой, идея состоит в том, чтобы использовать более простую версию меша, когда меш меньше вносит вклад в сцену. Есть две общие реализации; один просто переключает меш на более простой, когда он больше не вносит большой вклад, меш выбирается на основе некоторого фактора, такого как расстояние и количество пикселей (площадь на экране), занимаемых сеткой. Другая версия динамически тесселяции меша, это широко используется при рендеринге ландшафта.
Что если все это не сработало?
Ну, это хороший вопрос.
Первое, что вам нужно сделать, это профилировать ваше приложение с помощью графического профилировщика и определить, где находится узкое место. Имейте в виду, что узкое место может измениться при изменении содержимого. Узкие места также могут быть частью кода, работающего на процессоре, поэтому вам также нужно это измерить.
После этого вам необходимо выполнить некоторые оптимизации в узких местах, помните, что на этот вопрос нет правильного ответа, и он будет отличаться от аппаратного обеспечения к другому.
Некоторые общие приемы оптимизации GPU:
- Избегайте ветвления в шейдерах.
- Попробуйте разные структуры вершин, например, с
{VNT}
чередованием в одном и том же массиве или {V},{N},{T}
в разных массивах.
- Нарисуйте сцену спереди назад.
- Отключите Z-буфер в некоторых точках, например, если изображение не нуждается в Z-тестировании.
- Используйте сжатые текстуры.
Некоторые общие приемы оптимизации процессора:
- Используйте встроенные функции для небольших функций.
- По возможности используйте SIMD (одна инструкция, несколько данных).
- Избегайте кеш-памяти недружественных скачков памяти.
- Используйте VBO с «правильным» количеством данных. (в зависимости от вашего оборудования), но обычно меньше вызовов отрисовки лучше.
Но что, если мое узкое место было в отложенном затенении?
В этом случае, поскольку отложенное затенение больше относится к источникам света, наиболее очевидной является оптимизация фактических расчетов затенения. некоторые из пунктов, чтобы следить за:
- Рендеринг источников света, которые действительно влияют на конечное изображение Другими словами отбраковать огни, которые не способствуют. Это может быть эффективно реализовано с использованием отбора окклюзии, о котором я упоминал ранее.
- Нужен ли этот свет зеркальному или другим компонентам? Возможно, нет.
- Этот свет отбрасывает тень? Некоторые огни не должны отбрасывать тени.
- Может ли этот световой вклад быть предварительно вычислен? Если он не движется, возможно, некоторые аспекты могут быть предварительно вычислены.