среда, 22 июня 2011 г.

GPU Gems 3 Рендеринг SpeedTree Следующего поколения (Перевод) Часть 1

Исходная статья: http://http.developer.nvidia.com/GPUGems3/gpugems3_ch04.html

Александр Харламов
Корпорация NVIDIA
Ян Кэнтлей
Корпорация NVIDIA
Юри Степаненко
Корпорация NVIDIA

4.1 Введение

SpeedTree - пакет связующего ПО от IDV Inc. для создания деревьев реального времени. Игры, которые используют SpeedTree имеют большую гибкость в выборе того, как выполнять SpeedTrees. Мы обсуждаем несколько особенностей GeForce 8800, которые допускают высококачественные расширения следующего поколения к SpeedTree. Во-первых, отсечение силуэта добавляет детали к веткам и схемам ствола. Затем, теневое отображение добавляет реалистическое самозатенение на уровне индивидуальных листьев. Дополнительно, мы далее совершенствуем освещение с моделью распространения света "двусторонний лист" и рендерингом расширенного динамического диапазона (HDR). Наконец, мультитиповое сглаживание наряду с альфой к освещению обеспечивают очень высокое визуальное качество, свободное от проблем ступенчатости.

4.2 Отсечение Силуэта

Древесные ветви и стволы являются органическими, не регулярными, и составными. Иллюстрация 4-1 показывает типичный, реальный пример: хотя ветви являются приблизительно цилиндрическими, детальный силуэт груб и неправилен. Ствол дерева средней или низкой полигональности, скажем, 1 000 полигонов, не сможет фиксировать эти детали. Получающиеся прямые многоугольные края - тонкая, но важная вещь, которую вы видите на создаваемом компьютером изображении.
clip_image002
Иллюстрация 4-1 Фотография реальной древесной ветви, с нерегулярным силуэтом.
Многие алгоритмы доступны, чтобы помочь в представлении большого количества деталей, замеченных в ветви, изображенной в иллюстрации 4-1. Самым старой и наиболее широко осуществленных из этих методик является отображение выпуклостей. Отображение выпуклостей обеспечивает разумно-хорошее представление внутренней области ветви, такой, как область в пределах зелёного квадрата в иллюстрации 4-1. Однако, алгоритм полностью неспособен обработать подробности силуэта, подсвеченного в синих квадратах. Он также не в состоянии обрабатывать параллакс, который наблюдатель может видеть в переменной глубине коры. Усовершенствование отображения выпуклостей состоит в паре сопутствующих методов: отображение рельефности (Oliveira and Policarpo 2005) и отображение окклюзии параллакса (POM)(Tatarchuk 2006). Обе методики выполняют поверхностную трассировку лучей вдоль поверхности объекта, которые могут добавить параллакс и самоокклюзию. (Мы используем отображение рельефности как общий термин, охватывающий и то, и другое.) С отображением окклюзии параллакса эффект снова ограничен внутренней областью объекта, и силуэт остался не изменённым. Отображение рельефности предлагает несколько расширений, одно из которых поддерживает силуэты, но это требует дополнительной предварительной обработки. Наконец, составление мозаики модели и отображение смещения может также быть полезным, но это создаст существенные сложности в геометрии, обработка которой может не стоить своих усилий во время создания целого леса деревьев.
Наш подход должен исправить рельефное отображение на стволах деревьев, чтобы обрабатывать внутренние детали, и выполнять дополнительный переход для обеспечения подробностей силуэта. Ни одно из этого не поддержано программами построения теней SpeedTree, но они могут быть легко добавлены благодаря инструментам, формату файла, и API, что добавляет дополнительную функциональность, включая дополнительные текстурные карты.
Для силуэтов мы используем методику, которую мы называем отсечение силуэта. Хотя методика значительно отличается от оригинала, описанного в Sander et al. 2000, результирующий эффект очень похож. Наши методика вытесняет ребра от силуэта объекта перпендикулярно к вектору видимости. Эти силуэты подвергаются трассировке лучей высотной карты, подобной рельефному отображению для определения, какие пиксели должны закрываться силуэтом. Как с рельефным отображением, используемым на полигонах ветвей, эта методика не требует никакой дополнительной предварительной обработки.
4.2.1 Вытеснение Ребер Силуэта
Первым шагом в рендеринге силуэтов является вытеснение ребер. Мы делаем это используя гладкие нормали для каждой из вершин, определяя край силуэта в пределах треугольника. Если точка нормали вершины и угол обзора меняет знак вдоль края треугольника, то мы находим новую вершину на том краю, где точка вектора обзора и интерполированная нормаль равнялись нулю. Иллюстрация 4-2 иллюстрирует процедуру.
clip_image004
Иллюстрация 4-2 Вытеснение силуэта на треугольнике, вид сбоку
Обнаружение силуэтов и вытеснение ребра может быть выполнено непосредственно на Технологии DirectX 10. Мы вычисляем точки между нормалями вершины и углом зрения внутри вершин теней. После этого геометрические тени сравниваются с точками и строятся два треугольника в местах, где точки равны нулю, как показано в иллюстрации, 4-2c и иллюстрации 4-2d. Поскольку эти два треугольника сгенерированы как полоса, максимальное число выхода вершин от геометрии теней четыре. Если точка не изменяется в пределах треугольника, геометрия теней ничего не выводит. Если единственная нормаль вершины окажется ортогональной к зрительному вектору, то наши вычисления произведут выродившийся треугольник. Естественно, мы не хотим напрасно тратить время, обрабатывая такие треугольники, таким образом мы проверяем этот случай, и если находится, что две из позиций треугольника - наш не устраивающий нас случай, мы не генерируем этот треугольник программой теневой геометрии. Иллюстрация 4-3 показывает пример промежуточного вывода.
clip_image006
Иллюстрация 4-3 Стволы дерева с ребрами силуэта (в каркасе)
Чтобы гарантировать непрерывность вдоль силуэта, алгоритм требует гладкие для каждой вершины, геометрические нормали. Это требование находится в противоречии с дополнительной методикой "сокращения светового шва" SpeedTree, посредством чего нормали ветвей изогнуты далеко от геометрической нормали для избегания освещения неоднородностей. Для поддержки обоих особенностей, две различных нормали должны быть добавлены к атрибутам вершины.
4.2.2 Рассмотрение Высоты
Как только ребра были отсечены, мы используем карту высоты, чтобы представить детальный объектный силуэт. Карта высоты - та же, которая использовалась для рельефного отображения, но ребра силуэта нуждаются в более сложной карте высоты, прослеживающей алгоритм. Мы отсекаем дополнительную геометрию от вершины V 0 и V 1, как показано в иллюстрации 4-4. Для этого ребра мы будем нуждаться в следующем:
· Основание тангенса, чтобы вычислить разбросанное освещение
· Позиция вершины, правильная к теневым ребрам
· Координаты текстуры
· Вектор представления, для рассмотрения высоты
clip_image008
Иллюстрация 4-4 Атрибуты Вершины для отсечённой Геометрии
Нет никакой потребности вычислить новые значения для основания тангенса и координат текстуры, для вершин V 2 и V 3. V 2 атрибуты равны атрибуту V 1, тогда как V 3 атрибут равен атрибуту V 0, даже при том, что это является теоретически неправильным.
Иллюстрация 4-5 демонстрирует, как это работает. Там показано, что мы вычисляем различные вектора обзора для каждой вершины. В пиксельных тенях мы сначала изменяем координату текстуры ребра (точка A), делая шаг назад в направлении вектора обзора (вектор обзора находится в пространстве тангенса после геометрии теней). Мы фиксируем расстояние вдоль вектора обзора, чтобы получить всего лишь экспериментальное значение, и достигаем пункта B. Не исключено, что пункт B может быть различным для различных фрагментов. После этого мы выполняем обычную отображающую карту, прослеживающую высотный поиск. Если мы находим пересечение, то мы вычисляем "разбросанное" освещение и затенение для этого фрагмента. Иначе, фрагмент - антиалайзинговый (см. Раздел 4.6.3), или выбрасывается.
clip_image010
Иллюстрация 4-5 Рассмотрение Высоты Вдоль Вектора обзора
Для ребер силуэта поиск через карту высоты прослеживается вдоль более длинной занимаемой площади в пространстве текстуры, потому что, по определению, вектор обзора пересекает сеть под острым углом в силуэте. Таким образом, ребра требуют большего количества шагов последовательного перебора чем рельефное отображение на основных полигонах ствола. К счастью, ребра являются всегда маленькими с точки зрения затененных пикселей экрана, и в результате "стоимость" за пиксель не существенна. Мы также фиксируем длину поиска в пространстве текстуры к максимальному значению, чтобы далее ограничить стоимость. Иллюстрация 4-6 показывает цилиндр с прикрепленными ребрами. Это иллюстрирует, как ребра вытеснены от простой геометрии. Иллюстрация 4-7 показывает тот же цилиндр, затекстурированный. Рельефное отображение объединено с реалистическим видом силуэтов, показывая визуальные результаты.
clip_image012
Иллюстрация 4-6 Каркас с Ребрами Силуэта
clip_image014
Иллюстрация 4-7 Результат Рельефного Рассмотрения Отображения и Высоты
Хотя алгоритм, представленный здесь, приводит к превосходным результатам, во многих способах это просто. Мы полагаемся  простое линейное рассмотрение карты высоты для рельефного отображения. Это может быть улучшено при использовании комбинации последовательных переборов и двоичных поисков как в Policarpo 2004 или использованием дополнительных предвычислений, чтобы ускорить алгоритм рассмотрения (Dummer 2006, Donnelly 2005). Также, самозатенение может быть вычислено прослеживанием дополнительных лучей.
4.2.3 Уровень Силуэта Деталей
Даже с оптимизацией можно заметить, что силуэты не требуются для большинства деревьев. На расстоянии визуальное воздействие силуэтов является незначащим. Поскольку они действительно требуют большинство пикселей и циклов геометрии, мы удаляем их из отдаленных деревьев. Для каждого древесного типа есть зона перехода, во время которой ширина силуэтов во внешних координатах постепенно уменьшается, и в итоге обнуляется как функция расстояния, как показано в иллюстрации 4-8. Таким образом они не занимают памяти, когда они удалены. Практически, число видимых силуэтов ограничено меньше чем десятью в типичных сценах, таких как те, которые появляются в Разделе 4.7.
clip_image016
Иллюстрация 4-8 Функция Спада Силуэта

4.3 Тени

Улучшив древесными силуэтами, мы переходим к повышению качества теней. Поскольку общие теневые методики являются определенными для каждой игры, встроенные тени SpeedTree предварительно вычисляются офлайново, и статический подход наименьшего общего знаменателя всё делает так, чтобы SpeedTree мог работать со многими различными движками. У этого подхода есть некоторые недостатки:
· Когда древесная модель анимирует из-за действия ветра, теневая анимация ограничена преобразованиями координат текстуры: протяжение, вращение, и так далее.
· Предварительно вычисленные тени не выглядят столь же реалистичными как динамические, особенно тени, спроектированные на стволы дерева.
· Листья не дают самотени.
4.3.1 Самозатенение Листа
Наша вторая главная цель состоит в том, чтобы листья смотрелись индивидуально затененными в пределах карты листьев. (SpeedTree использует и плоские карты листа, и трехмерные; это детализирует самозатенение.) Самозатенение листа не является прямым, потому что карты листа упрощены, 2D представления сложной трехмерной геометрии. Карты листа всегда поворачиваются "лицом" к камере, и в результате они все параллельны плоскости обзора. Иллюстрация 4-9 показывает дерево с картами листа. В этом методе мы используем теневое отображение. (См. King 2004 для введения в отображающие тень методики.) Чтобы заставить тени выглядеть визуально обращёнными, мы изменили и процесс генерации теневой карты и методику проектирования теневой карты.
clip_image018
Иллюстрация 4-9 Теневая Карта, Спроектированная Вертикально на Карты Листа
Наше поколение теневых карт для листьев в значительной степени следует за стандартным рендерингом. Карты листа поворачиваются "лицом" к позиции обзора. Выполняя рендеринг к теневой карте, они поворачиваются "лицом" к источнику света и таким образом делают хорошие тени. Однако, как иллюстрация 4-10 иллюстрирует, они вращаются вокруг их центральной точки, которая представляет проблему. В фигуре светло-голубая карта листа поворачивается к зрителю; зелёная карта листа представляет ту же самую карту, но теперь повёрнутую к источнику освещения. В иллюстрации, 4-10a, заметим, что зелёная карта листа будет оттенять только низкую половину синей карты во время теневого проектирования. Чтобы избежать это недоразумение, мы просто транслируем зелёную карту листа к источнику освещения, как показано в иллюстрации, 4-10b. Мы транслируем это произвольным, корректируемым количеством, равным приблизительно половине высоты листа.
clip_image002
Иллюстрация 4-10 Позиционирование Карты Листа


Плоская геометрия карт листа излагает более существенную проблему, применяя теневую карту. Применение теневой карты к плоской карте листа приведет к теням, спроектированным вдоль 2D карты листа лишь как удлиненные полосы (см. иллюстрацию 4-12). Единственный случай, который работает хорошо, является источником освещения около глаза.
Чтобы теневые карты листа выглядели более реалистично, без полос, во время теневого прохода мы изменяем затененную позицию, сдвигая её в направлении обзора. (Отметьте, что мы не изменяем геометрический объект, растеризованная позиция - карта листа - все еще 2D прямоугольник. Мы только выполняем сдвиг позиции, используемый для вычислений тени.) Коэффициент смещения сохранен в текстуре и повторяется через каждый индивидуальный лист в карты листа. Иллюстрация 4-11 показывает получающуюся текстуру. Используя эту новую позицию листа, мы проектируем затененный пиксель в световое пространство и производим выборку теневой карты. Поскольку эта операция изменяет различные листья в карте листа независимо, это должно быть выполнено в программе построения теней пикселя. Функция, используемая для того, чтобы выполнить эти операции, детализирована в Распечатке 4-1.
clip_image004
Иллюстрация 4-11 Текстура Листа и Сопровождение Смещенной глубиной Текстуры 

Пример 4-1. Код Программы построения теней Пикселя для Применения Теневой Карты со Смещениями

  1.    float PSShadowMapFetch(Input In)  
  2. {  
  3.   // Let In.VP and In.VV be float3;  
  4.   // In.VP - interpolated Vertex Position output by VS  
  5.   // In.VV - View Vector output by VS  
  6.   // OCT - Offset Coefficient Texture  
  7.   // SMPP - Shadow Map Pixel Position  
  8.   // SMMatrix - transform to Shadow Map space  
  9.   float3 SMPP = In.VP + In.VV * tex2D(OCT, In.TexCoord).x;  
  10.   float3 SMCoord = mul(SMMatrix, float4(SMPP, 1));  
  11.   float SM = tex2D(SMTexture, SMCoord);  
  12.   return SM;  
  13. }  


Иллюстрация 4-12 показывает результаты обоих типов смещения. (За исключением теневого термина, все другие освещения и цвета были удалены, чтобы подчеркнуть тень.) Два типа экспонатов видимы в иллюстрации, 4-12a: присутствуют вертикальные полосы из-за проектирования теневой карты вертикально вниз 2D карты листа. Есть также диагональные линии в позициях карт листа, когда теневая карта выполнена. В иллюстрации, 4-12b, устранены эти недочёты. Результат - очень детальная и естественная листва. В нашей демонстрационной версии в реальном времени изменяется самозатенение индивидуальных листьев, поскольку дерево двигается благодаря ветру.
clip_image006
Иллюстрация 4-12 Воздействие Смещений Листа с Самозатенением


Продолжение перевода в следующей части.

Комментариев нет:

Отправить комментарий