Простейший динамический LOD

Одним из популярных методов для ускорения рендера в 3D сценах является использование LOD – Level Of Details. При использовании LOD объекты, располагающиеся близко к камере, имеют самую высокую детализацию, на средних планах – среднюю детализацию, а на задних планах используются очень грубые, недетализированные объекты т.к. они все равно почти не видны. Такая сцена рендериться гораздо быстрее, чем сцена у которой на всех объектах выставлена максимальная детализация.

Простейшим способом организации LOD в Blender является использование модификатора Subdivision Surface, который сглаживает объекты тем сильнее, чем больший уровень сглаживания указан в модификаторе.

Для примера заполним сцену кубиками, предварительно добавив на каждый куб модификатор Subdivision Surface. Уровень подразделения в модификаторе выставим равным 0.

Далее мы в зависимости от положения камеры будем увеличивать уровень подразделения модификатора тем больше, чем ближе куб располагается к камере.

Чтобы обработать все кубы, пройдем в цикле по всем объектам сцены, имеющим тип “MESH”:

Проверим, есть ли на текущем меше модификатор Subdivision Surface, чтобы не обрабатывать объекты без модификатора, и сохраним указатель на модификатор в переменную subsurf_modifier:

Если нужный модификатор на объекте имеется, вычислим расстояние между этим объектом и камерой:

Проверим следующее условие:

  • Если расстояние меньше 5 – установим значение подразделения модификатора равным 2
  • Если расстояние до камеры больше 5, но меньше 10 – установим подразделение равным 1
  • Для всех остальных случаев (расстояние от объекта до камеры больше 10) – сбросим подразделение модификатора в 0

Если теперь мы выполним этот код, объекты которые расположены близко к камере будут подразделены модификатором на уровень 2, на среднем расстоянии – на уровень 1, а все остальные останутся не подразделенными.

Требуемый результат мы получили, однако не имеет смысла каждый раз запускать данный код вручную, если камера меняет свое положение.

Привяжем выполнение этого кода к процессу обновления сцены, который контролируется в Blender API через депсграф.

Для начала обернем весь код в функцию, чтобы его можно было легко вызывать:

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

Для того чтобы наша функция вызывалась при каждом обновлении сцены, добавим ее вызов в хендлер depsgraph_update_post:

Теперь выполним наш код и попробуем подвигать камеру в сцене.

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

5 1 голос
Article Rating
Подписаться
Уведомить о
guest

0 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии