пятница, 20 ноября 2009 г.

Тесселяция и дисплейсмент

Эта тема последнее время довольно популярна. Особенно в связи с выходом DirectX 11 и бенчмарком Unigine Heaven с его поддержкой.


Normal   Normal Wireframe   Displaced   Displaced Wireframe

Как ни странно, на этой картинке не DX 11 и пресловутая реалтайм тесселяция, а DirectX 9 и результат работы оффлайновой утилиты.

Пост обновлен 21.11.09

Утилиту я сделал под влиянием "глобального заговора" - моя 9600GT не поддерживает новомодную тесселяцию, а попытки сделать дисплейсмент в 3dsmax дают деформацию фигуры, море полигонов, и вообще не очень приятный результат.
При тесселяции полигон разбивается на тысячи мелких полигонов, а вершины деформируются по карте высот. Эту часть мы прекрасно можем сделать и без помощи GPU, но тысячи дополнительных полигонов не пойдут на пользу скорости. Задачу я попробовал решать в лоб - оптимизацией полигонов после дисплейсмента.

Сетка модели без оптимизации выглядит примерно так:

Карта высот 64х64, 4096 вершин, 8192 полигона 64x128, 8192 вершины, 16002 полигона. Невооруженным глазом заметно, что некоторые полигоны откровенно лишние. С учетом особенностей их расположения, есть широкое поле для оптимизаций.
Постараюсь не углубляться в технические детали. Сам процесс оптимизации в нашей утилите обьединяет соседние полигоны по разным критериям. Различные параметры позволяют задавать детализацию и устранять артефакты. Сама полученная сетка (см. начало поста) довольно далека от идеала - некоторые места слишком сложные, есть "висящие" вершины (примыкание вершины к грани треугольника) и пр. Важен другой факт - в модели двери 980 треугольников, это в 9 раз меньше, чем без оптимизации. Для максимального приблежения это вполне приемлимо, а на удаленных участках можно показывать плоскую текстуру. Моя видеокарта такую нагрузку просто не замечает.
Алгоритм оказалась очень требовательным к карте высот - чем "геометричнее" фигуры, тем меньше получается полигонов. Различные полутона, сглаживания, отверстия, градиенты - все это приводит к лишней полигональности.

Вручную нарисованная карта высот для оконной рамы дает на выходе 112 полигонов. Эту же фигуру в 3д пакете можно нарисовать с 74ю треугольниками. Возможно, если задаться целью или просто наплевать на правила, то можно и поменьше сделать. :) Важно другое - порядок чисел один и тот же, значит технология имеет право на жизнь.


Художники наверняка скажут, что это от лукавого и надо моделировать неровности руками. Это несомненно так, но я редко когда встречал, например, подручную библиотеку дверей, окон, камней - их для каждой модели предпочитают делать заново. В то же время библиотека текстур таких элементов - стандарт, и ничто не мешает хранить в ней еще и карты высот. В таком разрезе добавление дверей и окон сводится к расположению текстуры и нескольким запускам утилиты для генерации разных LODов.
Рано или поздно наступит светлое будущее, у всех будут DirectX 11 совместимые видеокарты, а эти текстуры пригодятся для аппаратного дисплейсмента. Но пока пользуемся тем, что есть :)

Update: Вспомнил, что карта высот для двери имеет соотношение 1/2, т.е. размер 64х128, а не 64х64, а сетка полигонов будет 63х127х2, т.е. 16002 треугольника. После оптимизации - 980, т.е. в 16 раз меньше.

Update 2: Подкрутил некоторые гайки и избавился от полигонов с высотой 0. В самом деле - зачем они нужны, если можно считать дисплейсмент добавлением деталей к существующей модели. Результат - 812 треугольников при таком же внешнем виде. По сравнению с 16002 оригинальными это уже оптимизация в ~19,7 раз, да и сетка довольно хороша.


Update 3: Человек - изворотливое создание. 699 треугольников.