обзоры Обзор NVidia GeForce 256


Геометрический конвейер

Путь, который проходят треугольники при рендеринге, называется конвейером. Конвейер можно условно разделить на три стадии - рассчет освещенности, трансформация и растеризация. Растеризация выполняется силами 3D-ускорителя уже давно, а трансформация и рассчет освещенности (Transformation and Lighting, T&L) до сих пор выполнялись процессором. GeForce имеет блок T&L, называемый геометрическим процессором. Аппаратный T&L поддерживается в Direct3D 7 и OpenGL, но факт использования программой этих API совсем не означает автоматического задействования аппаратного T&L.

Вообще говоря, стадии трансформации (T) и рассчета освещенности (L) могут меняться местати в зависимости от реализации. При программном рассчете освещенности порядок таков: сначала L, затем T. В GeForce сначала выполняется T, затем L.

  1. Трансформация. Объекты (массивы вершин в собственной системе координат) переводятся в мировую систему координат (world space), затем в систему координат наблюдателя (view space). (Каждое преобразование представляет собой умножение на матрицу, поэтому последовательные преобразования можно свести к одному.)
  2. Отсечение. Вершины, которые не попадают в область видимости (clip frustum), отбрасываются.
  3. Рассчет освещенности. Сцена представляется в виде множества объектов и источников света. Рассчет освещенности может выполняться геометрическим процессором, OpenGL-драйвером или T&L-движком Direct3D или самой программой. Объекты как правило хранятся в виде массива вершин (vertex array) с информацией о нормалях. Нормали нужны для рассчета освещенности в вершинах (кстати по завершении этой стадии нормали теряются - далее они просто не нужны). Аппаратный рассчет освещенности выполняется в системе координат наблюдателя. (Софтверный рассчет освещенности выполняется перед стадией трансформации для каждого объекта индивидуально, в системе координат этого объекта.)
  4. Проецирование. Все вершины переводятся из системы координат наблюдателя в систему координат экрана (screen space). Вся геометрия становится корректной с точки зрения перспективы.
  5. Растеризация. Чисто "железная" стадия.

Рендеринг можно разделить на программную и аппаратную часть. Начинается конвейер с того, что программа готовит треугольники, а завершается аппаратной растеризацией. Переход от программной части к аппаратной выполняется только один раз - нельзя попросить GeForce рассчитать освещенность, а результат вернуть CPU. Далее я расскажу, где выполняется этот переход.

Плохие и хорошие вершины

Программа не может общаться непосредственно с аппаратурой - она работает с Direct3D-драйвером как с виртуальным устройством. GeForce (как и любой другой 3D-ускоритель с геометрическим процессором) реализует интерфейсы "TnLHAL", инкапсулирующие аппаратный T&L. Direct3D-программа может работать как с устройством TnLHAL, так и с устройством HAL. Во втором случае вместо аппаратного T&L для геометрических операций будет задействован софтверный T&L-engine самого Direct3D.

В OpenGL все проще. OpenGL-программа даже не знает, есть ли аппаратный T&L или нет. Вся геометрическая обработка скрыта внутри OpenGL-драйвера. OpenGL-драйвер GeForce очевидно пользуется аппаратным T&L, а драйверы 3D-ускорителей без аппаратного T&L выполняют геометрическую обработку программно.

Программа может работать с вершинами тремя способами:

  1. Приказать освещать и трансформировать вершины OpenGL-драйверу или Direct3D. В Direct3D такие вершины называются "Untransformed and Unlit vertices" (нетрансформированные неосвещенные вершины). Для таких вершин геометрический процессор GeForce работает на полную катушку.

  2. Сама рассчитывать освещенность для вершин, и передавать освещенные вершины для трансформации OpenGL-драйверу или Direct3D. В Direct3D такие вершины называются "Untransformed and Lit vertices" (нетрансформированные освещенные вершины).

  3. Сама рассчитывать освещенность для вершин и сама же трансформировать их. В Direct3D такие вершины называются "Transformed and Lit vertices" (трансформированные освещенные вершины). Этот вариант - наихудший для GeForce, так как освещать и трансформировать ему нечего - все уже "сделано" до него.

Существует путаница с терминологией между OpenGL и Direct3D. В Direct3D именование вершин ведется исходя из того, в каком виде вершины готовит сама программа (если программа сама освещает вершины, значит они "освещенные"). В OpenGL все называется с точностью до наоборот. Первый случай - "Lit vertices" (освещенные вершины). Второй и третий - "Shaded vertices" (затененные вершины). Дело в том, что в OpenGL именование ведется исходя из природы вершины - что с ней надо сделать. Если вершину надо "осветить" - то она называется "освещенной", и драйвер/ускоритель будут рассчитывать освещенность исходя из источников света. Если сама программа выполняет рассчет освещенности, она лишь передает данные о цвете вершины - этим цветом будет затенятся треугольник, а вершина называется "затененной". Соответственно, в OpenGL наихудшим случаем для GeForce будут "затененные вершины".

3D-ускоритель без геометрического процессора получает освещенные трансформированные (программой или драйвером - неважно) вершины непосредственно от CPU, либо через область системной памяти, называемую буфером вершин (vertex buffer). Хранить буфер вершин в видеопамяти (то есть кэшировать) не имело смысла, так как два экземпляра одного и того же объекта в системе координат экрана различались. Геометрический процессор может работать с неосвещенными нетрансформированными вершинами - это значит, что объекты хранятся в собственной (локальной) системе координат. Если в сцене присутствует несколько экземпляров одного объекта, можно использовать его многократно. А это значит, что его целесообразно кэшировать в видеопамяти (как текстуры). GeForce умеет это делать - эта возможность называется "vertex buffer in videomemory" (буфер вершин в видеопамяти).

Страница 3 - TreeDemo, ViewPerf