Десять шпионок против шести русалок

Презентации новых GeForce6 6800 и Radeon X800 отгремели с шумом, помпой и показом новых, так сказать, “промоушн-героинь” (на сей раз nVidia, посмотрев, видимо, один старый советский фильм, определила свою маркетинговую политику как: “я на русалках больше заработаю”; в тоже время ATi свою стратегию преподнесла как “и на шпионках можно зеленых бумажек настричь”). Дело было в далеком апреле-мае, но только сейчас данные железки начали помаленьку добираться до полок наших кировских магазинов. Кроме того, с тех пор были презентованы различные дегенераты тех самых high-end-видюх с циферками чуть поменьше, не говоря уже о всяких буквенных вариациях. В связи с такими обстоятельствами будет не лишним обрисовать все эти новинки, как по их разновидностям, так и по функциональным возможностям, после чего задаться вопросом: “А надо ли нам это?”. И начнем мы, пожалуй, именно с разновидностей.

Часть первая: кто есть кто
Итак, у nVidia есть три сахарных предложения для потребителей (приводятся в порядке убывания сахара): GeForce6 6800, GeForce6 6600 и GeForce6 6200. Все практически идентичны по функциональным возможностям: третьи шейдеры и MRT (об этом — далее) есть теперь у всех GeForce’ов. Кое-что, правда, убрали с 6100, но это пока что не так существенно с учетом его производительности.
Серия 6800 наиболее разнообразна и включает аж четырех представителей: GeForce6 6800Ultra, GeForce6 6800GT, GeForce6 6800 и GeForce6 6800LE. Ultra — это флагман всей шестой серии, он содержит 16 пиксельных, 6 вершинных конвейеров и 256-бит шину памяти (вообще разрядность шины памяти у шестых “гефорсов” в рамках линейки 6800 неизменна) и память GDDR3. А также такие страшные частоты как у камня, так и у памяти, что nVidia, по сути дела, до сих пор не может наладить их бездефицитное производство. GT — это вариант с немного подрезанными крыльями, или, если кто не въехал, с немного пониженными частотами, но все остальное, как говорится, при нем. Так что GT, по крайней мере у буржуев, наличествует в достаточном объеме. Вариант 6800 уже изуродован посильнее. По сути дела, это брак предыдущих вариантов. Бедняге оставили только 12 пиксельных конвейеров и 5 вершинных, память — только обычную DDR, да и частоты понижены уже нехило. Но и это не самый плохой вариант из 6800-х, потому что существует еще и LE. Этот, по сравнению со старшими собратьями, уже обездвиженный инвалид-паралитик, живодеры оставили ему, чтоб не задохнулся, каких-то жалких 8 пиксельных и 4 вершинных конвейера, не дав, конечно, третьей DDR’ы.
Однако перейдем к линейке 6600. Моделям этой серии оставили только 8 пиксельных конвейеров и 4 вершинных, при этом сохранив функциональные возможности, по сравнению с 6800, без изменений. Отличие от 6800LE состоит в том, что у 6600 128-разрядная шина памяти. Кроме того, на 6800 ампутантах отрезание всего лишнего производится путем отключения бракованных конвейеров. Эта возможность заложена в них аппаратно, и для отключения достаточно изменить кой-какие биты в определенных байтах в BIOS’е видюхи. Соответственно, таким же образом их можно и включить, но не факт, что заработает нормально. Хотя, судя по уже накопленной энтузиастами статистике, включение либо только пиксельных, либо только вершинных конвейеров дает, как правило, положительный результат. А 6600 изначально рождается на свет мутантом-ампутантом (что, конечно же, удешевляет производство) с 8 пиксельными и 4 вершинными конвейерами. Что касается разновидностей 6600, то их всего лишь две: GeForce6 6600GT и просто GeForce6 6600. Передовик 6600GT может похвастаться повышенными частотами и третьей DDR’ой, в то время как упрощенный 6600 ни тем, ни другим порадовать не может. Но это ему и не нужно, потому что главным его достоинством является цена.
Остался на рассмотрении только GeForce6 6200. Он предлагается всего лишь в одном варианте — собственно 6200. Этот девайс представляет из себя жалкое зрелище, ведь он является ампутантом, которому еще раз провели ампутацию! Да-да, представьте себе, для его получения у бракованного 6600 отнимают еще 4 пиксельных и один вершинный конвейер.
Итак, все девайсы, что объявлены официально, мы осветили. Теперь осталось осветить то, что входит в ближайшие планы nVidia. А это выпуск двух видеочипов: первый — замена GeForce6 6800 (вероятное коммерческое название — GeForce6 6700), содержит 12 пиксельных и 5 вершинных конвейеров; второй — замена GeForce6 6200 (вероятное коммерческое название — GeForce6 6100), содержит 4 пиксельных и 3 вершинных конвейера. Заметьте, резня не заканчивается, и беднягу 6100 лишают еще и одной важной функциональной возможности — блендинга с плавающей точкой (см. далее).

На этом товары от nVidia мы описывать закончим и перейдем к продукции ATi. Все десятое семейство радеонов включает всего лишь два подсемейства: Radeon X800 и Radeon X700. Функциональные возможности их полностью идентичны, и на них мы сосредоточим свое внимание чуть позже. Среди X800 самым “бриллиантовым” яв­ляется Radeon X800XT PE (пока статья писалась, пришла линейка X850, не несущая ничего нового, кроме техпроцесса и частот, поэтому переписывать ничего не пришлось, однако формально “топовым” все же стал Radeon X850XT PE (R480)). Флагман оснащается 16 пиксельными, 6 вершинными конвейерами и 256-бит шиной памяти. Собственно говоря, как и его конкурент. Также ATi не поскупилась и на тактовые частоты для всего изделия, причем так не поскупилась, что тоже все еще решает те же проблемы, что и nVidia — с бездефицитным производством. Планку чуть ниже берет Radeon X800XT (сегодня — Radeon X850XT), этот продукт просто немного обделен тактовыми частотами, а в остальном ничем не уступает старшему собрату.
Теперь снова заводим речь об ампутантах. Самым полноценным из них является Radeon X800Pro (сегодня — Radeon X850Pro). Ему всего лишь снесли 4 пиксельных конвейера и, не дав третьей DDR’ы, скрепя сердце, зашили боевую рану. Но его товарища по роте Radeon X800SE ждала худшая участь. Ему снесли все 8 пиксельных конвейеров и тоже пожалели третьей DDR’ы.
Одновременно с появлением линейки X850 ATi представила еще одного участника соревнований из обоймы X800 — RadeonX800 XL, нечто между X800Pro и X800XT, поскольку он имеет все 16 пиксельных конвейеров в целости и сохранности, зато частоты — меньше, чем у Pro.
Теперь опишем боевые раны серии X700. Первый ее представитель — это Radeon X700XT, самый серьезный игрок серии. Он с рождения лишен восьми из шестнадцати пиксельных конвейеров, а шину родитель его, в лице ATi, подрезал до 128 бит, оставив в утешение GDDR3. Следующим катится Radeon X700Pro. Он отличается лишь тем, что не имеет третьей DDR’ы и его частоты чуть пониже. Зато ему просто в обязательном порядке памяти дают аж 256 Мбайт. Позади всех плетется просто Radeon X700. Ему уже 256 метров не дают, да еще и частоты нещадно режут. Уф-ф…
На этом пора заканчивать с разнообразием и переходить непосредственно к описанию новинок. Начнем мы с истории развития архитектур и функциональных возможностей ранее описанных видеомозгов.

Часть вторая: ретроспектива
Сегодня, судя по циферкам в кодовых названиях 3D-акселераторов (NV40, R420) мы имеем дело с четвертым их поколением. Но если вспомнить, что было четыре поколения назад, то припоминается, что существовали 3D-акселераторы как бы и до первого поколения (Riva да Rage там всякие). Конечно, это так, но, если взглянуть на это немного с другой точки зрения, то можно заметить, что первые зачатки программируемости графических конвейеров появились именно на том поколении, которое сейчас предлагается называть первым. Да, именно на первом поколении, на первых “гефорсах”, появились регистровые объединители (“register combiners”), которые, по сути дела, были предтечей шейдеров, а на “радеонах” тогда же (Radeon 7xxx) возникла просто возможность программировать различные “взаимодействия” между текстурными стадиями (что, конечно, попроще регистровых объединителей, но все же). А шейдеры — это специальные подпрограммы, которые исполняются самим 3D-акселератором. Бывают двух типов: пиксельные (для расчета цвета пикселей) и вершинные (для трансформации вершин), служат для повышения реализма в играх.
Далее последовали GeForce3 и Radeon 8500, а также DirectX 8.x в придачу к ним. Здесь уже программируемость конвейеров (причем на сей раз программируемыми стали не только пиксельные, но и вершинные конвейеры) раструбили по полной программе и обозвали эту возможность шейдерами ­(вообще на русский это забугорное слово по-хорошему не переводится, в лучшем случае получается что-то навроде “затенители”). Следует отметить, что первые шейдеры программистов не очень-то вдохновили на подвиги, причем наибольшей критике подверглись именно пиксельные шейдеры. Еще бы, ведь, во-первых, вычисления были целочисленные. Во-вторых, максимальный размер пиксельного шейдера составлял всего лишь 12 команд для версий 1.1, 1.2 и 1.3. Да и такой-то шейдер было весьма сложно написать, так как из этого небольшого количества команд 4 отводились под текстурные операции, а оставшиеся 8 — под арифметические. Правда, ATi несколько обогнала время, создав совместно с Microsoft версию 1.4, увеличив количество команд до 28, но шейдер при этом необходимо было по специальным правилам разбить на две части (так называемые фазы), в каждой из которых могло содержаться не более 14 команд, причем количество текстурных команд ограничивалось шестью (в каждой фазе), а остальные, как можно догадаться, арифметические. Версия 1.4 среди разработчиков поддержки практически не получила, так как, по сути дела, никто, кроме ATi, не выпустил чипы с ее поддержкой, несмотря на то, что она позволяла реализовать в один проход самый важный алгоритм освещения — по Фонгу. Но в Microsoft уже вели работу над DirectX 9 со второй и сразу третьей вер­сией шейдеров для него. Вторая версия, естественно, была существенно попроще и являлась обязательным требованием для совместимости с DirectX 9. В ней количество текстурных команд доросло до 32, а арифметических — до 64. Причем вычисления для пиксельных шейдеров перестали быть целочисленными, перейдя к вычислениям с плавающей точкой. В общем и целом Microsoft постаралась изо всех сил удовлетворить требования разработчиков по пиксельным шейдерам, а вот по вершинным, по сути дела, только увеличила количество команд, но основных требований не выполнила (нет возможностей создания новой геометрии и доступа к новосозданной геометрии, то есть нельзя создавать в шейдере новые вершины и грани). Эти требования, надо заметить, не реализованы до сих пор — даже в самой совершенной третьей версии вершинных шейдеров.
Но и на этом история с поддержкой DirectX 9 не заканчивается. Дело в том, что разработки nVidia в то время зашли несколько дальше, чем у ATi, но не настолько далеко, чтобы поддержать третью версию шейдеров. Поэтому калифорнийцы попросили у Microsoft создать промежуточную версию шейдеров, так называемую 2.0a. Созданная специально для GeForceFX, она все-таки достаточно серьезно шагнула вперед по сравнению со второй версией. В ней, во-первых, был реализован принцип поддержки различного количества команд в шейдере для конкретного аппаратного оборудования, причем инструкции могли быть любыми. Во-вторых, поддержана произвольная перестановка (arbitrary swizzling) компонент в регистре-источнике. В-третьих, добавлены инструкции градиента. В-четвертых, появились статические ветвления. Как видите, количество нововведений достаточно велико, и подробнее мы рассмотрим их в следующей части. А пока стоит отметить главную мысль этой части: сегодня к нам в системные блоки просятся программируемые 3D-акселераторы четвертого поколения, причем, как вы скоро увидите, разница между ними велика, как никогда прежде. Перейдем же к нашим героям!

Часть третья: разбор полетов
Сначала поговорим о радеонах. Надо сказать, что архитектура R420 и ее производные не претерпели практически никаких изменений в сравнении с предыдущим поколением R300 и R350, хотя мелкие усовершенствования, конечно, появились. Сначала окинем беглым взглядом изменения в шейдерах. Вершинные шейдеры так и остались на уровне старой доброй второй версии, из чего можно сделать вывод о том, что вершинные конвейеры либо вообще не подверглись никаким изменениям, либо они были весьма несущественными. А вот пиксельные шейдеры доросли аж до версии 2.0b. Что это за версия такая, придется объяснить поподробнее. В предыдущей части уже упоминалась версия 2.0a. Можно подумать, что 2.0b — это ее логическое продолжение, но на самом деле это не так. Версия 2.0b от ATi является скорее альтернативным расширением версии 2.0 в противовес 2.0a от nVidia. Это значит, что в чем-то 2.0b превосходит, а в чем-то уступает 2.0a. Основным нововведением в 2.0b являются так называемые статические ветвления. Это главное, чего недоставало вторым шейдерам, и в чем теперь Radeon догнал FX. Слово “статические” означает, что количество итераций в таком ветвлении задается исключительно константой, а возможность пропуска последовательности команд не предусмотрена вообще. Количество команд доросло до 512, как и у 2.0a. На этом все шейдерные нововведения и заканчиваются.
Но ATi, видимо, желая показать, что ее сотрудники не только чай пьют, дополнила свое творение еще одним усовершенствованием, более существенным. Это новый алгоритм сжатия текстур, названный канадцами 3Dc. А зачем вообще нужен новый алгоритм? Дело в том, что, когда разрабатывались все предыдущие форматы сжатых текстур, рассчитывали на то, что текстуры будут нести только цветовую информацию (в том смысле, что она будет интерпретироваться только как цвет), поэтому допускали существенные потери при сжатии. А сегодня, после того как с помощью шейдеров стали активно применяться всякие там бамп­мэппинги, старые расчеты уже не действуют. Элементы текстуры теперь, несмотря на свою цветовую сущность, могут нести информацию вовсе не о цвете. Теперь в текстуре может быть информация о материале: блестючесть, излучательность и сведения о нормалях. Если по поводу первых двух пунктов с потерями можно еще как-то смириться (хотя и для них потери очень нежелательны), то вот с нормалями такой фокус уже не пройдет. Эта разновидность текстур называется картами нормалей. И как вы уже, наверное, догадываетесь, 3Dc создан в первую очередь именно для них. На самом деле, судя по предоставляемым примерам сжатия самой ATi, потери все же есть, но они несущественные (на порядок меньше, чем в DXTC, где при сжатии карт нормалей становятся явно видны блоки разбиения текстуры). Что касается самого алгоритма сжатия, то ATi, можно считать, раскрыла все подробности его работы. Сейчас мы постараемся воспроизвести это по-русски. Известно, что информация в карте нормалей хранится в виде двойных слов, то есть первые три RGB-компоненты заменяют­ XYZ-координаты нормалей, а альфа-компонента не используется. Также известно, что все эти RGB-вектора нормализованы — всегда имеют единичную длину. Это дает нам возможность уменьшить размер карты в два раза, так как можно хранить только две компоненты вектора, а третья, исходя из вышеописанного правила, всегда восстановима. Но на этом сжатие не заканчивается, далее вся карта разбивается на блоки размером 4×4 элемента (один неупакованный блок занимает 512 бит), для R- и G-компоненты находятся минимальные и максимальные значения в блоке и рассчитывают­ся 6 промежуточных значений между ними. Таким образом, вместе с максимумом и минимумом получается 8 значений. Теперь для каждого элемента в блоке находится наиболее близкое значение из этих 8 значений. Чтобы закодировать восемь значений, нужно всего три бита. Таким образом, в запакованном блоке данных хранится 96 бит непосредственных данных и 32 бита для информации о минимуме и максимуме. Следовательно, 3Dc обеспечивает четырехкратное сжатие изображения. Также в формате предусмотрено и двукратное сжатие без использования свойств нормализованности карт нормалей, что может быть использовано для сжатия всяких карт “блестючести”, светимости и так далее. На этом лента новостей для R420 подходит, к сожалению, к концу. Не густо, однако…
Конкуренты в лице сотрудников nVidia чай в таком количестве не пили, так что у них побольше фенечек, способных удивить честной народ. Хотя на самом деле GeForce6 — тоже не революционный чип. Революционным был GeForceFX, тот самый провальный FX, который принес nVidia больше убытков, чем прибыли. Почему “шестерка” не революционна? А потому, что FX разрабатывался практически с нуля, в то время как GeForce6 основан на его, FX, архитектуре. Да, изменений на первый взгляд сделано много. Если же разобраться подробнее, то становится понятно, что, по сути, сделана лишь работа над ошибками по поводу совместимости с DX9. Добавлена поддержка MRT (см. ниже), а все команды вторых шейдеров исполняются без каких-либо штрафных тактов, а то и не двойных команд вместо одной. Плюс графические конвейеры переработаны так, чтобы девайс был совместим с третьими шейдерами. Естественно, что при таком подходе к совместимости именно те самые революционные третьи шейдеры, причем в первую очередь пиксельные шейдеры, получились не такими уж и революционными. В чем же подвох? Давайте разбираться.
Начнем с понимания того, чем вообще третьи шейдеры лучше предыдущих? Главное отличие кроется в так называемом динамическом управлении потоком команд (dynamic flow control). Опять какой-то страшный зверь! Но не пугайтесь сильно. Он, на самом деле, для нас, юзеров, будет почти незаметен, если, конечно, не считать повышения реалистичности изображения в играх.
Страшным же и зубастым он будет для мозгов замученных новыми технологиями разработчиков. Тем не менее, понять, что это такое, несложно. Просто раньше шейдеры исполнялись абсолютно линейно, одна команда за другой, однако с версии 2.0а появились статические ветвления или, если хотите, циклы. Они давали возможность повторять участок кода шейдера фиксированное количество раз, то есть в качестве числа итераций цикла выступала константа. В третьей версии в качестве количества итераций цикла может быть использована переменная типа uniform, то есть передаваемая в шейдер извне. Кроме того, появилась возможность делать выбор пути дальнейшего исполнения шейдера по условию, в том числе и пропуск команд, и ранний выход из шейдера. Тем не менее, переменная, рассчитанная в шейдере, все еще не может задавать количество итераций цикла. Видимо, это оставлено до следующей версии.
А подвох в том, что до сих пор для увеличения эффективности распараллеливания команд в пиксельных шейдерах пиксельные конвейеры объединяли по четыре штуки в так называемые квады. А поскольку расчет велся всегда по четыре пикселя, которые образуют квадрат, то такая оптимизация была очень эффективна и позволяла весьма значительно повысить производительность, поэтому ее активно использовали nVidia и ATi. Однако эта идея основывалась на распараллеливании за счет того, что все пиксельные конвейеры квада исполняли одно и то же, но с разными данными. При появлении же динамического управления потоком команд для отдельного пикселя может потребоваться исполнение команд, отличных от соседа в кваде. Каков же выход из ситуации? Либо вообще отказаться от квадов, либо исполнять все возможные ветвления для каждого пикселя квада. У GeForce6 квады оставлены, значит, он, скорее всего, исполняет все ветвления шейдера. Может быть, nVidia и удалось сделать какие-то дополнительные оптимизации, но наследство от FX сказывается, так как доподлинно известно о страшных штрафных тактах при использовании динамических ветвлений. Более того, в документации nVidia для разработчиков сказано следующее: ”используйте динамические ветвления очень осторожно и как можно реже, а лучше вообще не используйте их, но на будущих поколениях GPU производительность будет повышена, думайте об этом”. Да, так вот жестко…
Выводы из всего этого для разработчиков мы оставим для самих разработчиков, а вот для юзеров выводы сделать стоит. Во-первых, игры с поддержкой третьих шейдеров появятся, видимо, не скоро. Во-вторых, когда они появятся, GeForce6 в них будет нечего делать (но по поводу вторых шейдеров пугаться не стоит, их GeForce6 исполняет с вполне потребной производительностью). К тому же, как уже упоминалось, в него теперь добавлен MRT (Multiple Render Target), то есть множественные цели рендеринга. Вещь эта теперь очень даже полезна, ибо ее требует Half-Life 2 для DX9-рендеринга. На данный момент в основном применяется в алгоритмах визуализации реалистичной водной поверхности, но также может пригодиться в алгоритмах отложенного затенения. Представляет из себя эта технология просто возможность записывать данные в несколько текстур одновременно (на данный момент — до четырех).
Однако только на пиксельных шейдерах нововведения не заканчиваются — есть еще новая поддержка плавающих текстур, причем с фильтрацией и блендингом с плавающей точкой, плюс к тому кое-какие усовершенствования сделаны и в вершинных шейдерах. Разберемся сперва с плавающими форматами текстур и блендингом. С плавающими текстурами, думаю, более или менее все понятно. Просто теперь один элемент текстуры (тексель) может задаваться не только целочисленно 8 бит на компоненту, но и числом с плавающей точкой 16 или 32 бита на компоненту. Причем в такую текстуру можно и рендерить. Пригодится это, например, в алгоритмах теневого буфера или отсроченного затенения (deferred shading), а также мы получим существенное увеличение реалистичности изображения при любых алгоритмах освещения, особенно с использованием блендинга с плавающей точкой (HDR-рендеринг). Вот об этом, думаю, нужно поподробнее.
Аббревиатура HDR означает High Dynamic Range или, по-русски, высокий динамический диапазон. Динамический диапазон — это отношение максимального уровня яркости изображения к минимальному. Человеческое восприятие примерно равно 14 дБ. При использовании целочисленного кадрового буфера 8 бит на компоненту динамический диапазон будет равен примерно 2.4 дБ. Как видите, разница весьма серьезная. Из-за такой вот неточности хранения промежуточных данных, а также их смешения, то есть блендинга, накапливаются ошибки вычислений, а также те­ряются мелкие детали в наиболее ярких и темных участках изображения. В итоге конечная картинка получается недостаточно контрастной и реалистичной. Эту проблему и решает HDR-рендеринг. При хранении данных в 16-бит плавающем формате, который называется OpenEXR, динамический диапазон получается 12 дБ, что весьма близко к человеческому восприятию. Правда, чтобы добиться действительно реалистичной картинки, нужно использовать реалистичные модели освещения, то есть при обычных алгоритмах освещения HDR-рендеринг может ничего хорошего и не дать.
Теперь же перейдем к нововведениям в вершинных шейдерах. Если вы подумали о динамических ветвлениях, то ошиблись. В вершинных шейдерах они появились еще в версии 2.0a, поэтому нововведения эти несколько другого характера. Основной свежатинкой в вершинных шейдерах третьей версии является возможность выборки данных из текстур. Причем поддерживаются текстуры как целочисленных, так и плавающих форматов. Правда, у GeForce6 отсутствует какая-либо фильтрация этих самых текстур (инженеры nVidia из-за монстрообразных размеров чипа вынуждены были отказаться от этой роскоши), да и количество считываний в шейдере не более четырех (но это соответствует стандарту DX9). Применяться эта возможность будет, видимо, нечасто, но если будет, то в основном для создания реалистичной воды. Для ландшафтов же (это позиционировалось как основное ее применение) вряд ли, так как в основном рендеринг в играх уже многопроходный, а создавать этот самый ландшафт для каждого прохода не очень-то выгодно.
Есть, правда, еще одно нововведение в пиксельных и в вершинных конвейерах одновременно (точнее говоря, в их совместной работе), которое появилось еще на Radeon 9700, но nVidia реализовала ее только сейчас — на GeForce6. Существует оно пока что, к сожалению, только в Direct3D и называется экземплирование геометрии (geometry instancing). Суть идеи заключается в возможности убыстрения многократной отрисовки одного и того же объекта (это нужно в играх для отображения, например, различного рода эффектов с частицами, а также травы, листьев, кустов…). Для многократной отрисовки одного и того же индексного (иже с ним вершинного) буфера теперь не нужно постоянно вызывать функцию рисования. Достаточно вызвать ее один раз, при этом задав массив матриц трансформации для всех этих объектов. Налицо оптимизация для процессора — уменьшение числа вызовов процедур, плюс сокращается количество переключений различного рода состояний и режимов в самом драйвере видеокарты. Но есть еще одна оптимизация. Суть ее вот в чем: раньше вершинные конвейеры простаивали во время работы пиксельных конвейеров, и наоборот. А при использовании этой фишки вершинные конвейеры, передав данные пиксельным, начинают обрабатывать следующую порцию данных. Таким образом, достигается параллельная работа конвейеров, хотя, конечно, простои все равно возможны.

Часть четвертая: а зачем это надо
В этой части мы рассмотрим более или менее подробно некоторые алгоритмы и спецэффекты, которые могут появиться в играх в ближайшем будущем за счет использования вышеописанных технологий.
1) Отсроченное затенение или освещение (deferred shading или deferred lighting — одно и то же). Этот алгоритм предназначен для ускорения стандартных способов расчета освещения путем перемещения основных расчетов в область постобработки. Суть идеи в том, что в разные текстуры сначала записываются координаты, нормаль и специальная информация о цвете точки. Как вы обратили внимание, информация должна быть записана в несколько текстур (то есть нужно несколько проходов), но на новых наших подопечных есть MRT (вот для чего нужен этот зверь!). Потом информация из этих текстур используется для расчета освещения, причем для этого расчета потребуется вывести всего пару треугольников. В чем преимущество такого подхода? Преимущество в том, что при расчете освещения невидимые пиксели не обсчитываются вообще и скорость расчета самого освещения не зависит от количества и сложности геометрии, а зависит только от разрешения, с которым производится рендеринг. Однако, несмотря на явные преимущества такого подхода, отсутствие проблем с его использованием в игровых движках и вообще явную перспективность для использования в играх, на данный момент не заявлено ни одного проек­та, где бы он применялся.
2) Полностью реалистичный бампмэппинг с перекрытием и самозатенением (рис. 1).
Думаю, обяснять, что такое бампмэппинг, нет необходимости: это знают теперь уже все, и количество игр, где он использовался, по пальцам уже не сосчитать. Однако в играх до сих пор использовался dot3-mapping, то есть самая простая разновидность бампмэппинга, которую можно придумать. Рельеф­ она имитирует весьма посредственно, так как нет перекрытия одних виртуальных выпуклостей или впадин другими и они не отбрасывают друг на друга теней. Проблема решаема с помощью алгоритмов, которые дополняют dot3-mapping. Это offset mapping (он же parallax mapping) и horizon mapping. Первый создает иллюзию перекрытия выпуклостей, а второй добавляет самозатенение. Нам обещают такое счастье в играх на движке Unreal 3.
3) Подповерхностное рассеивание света (subsurface scattering) (рис. 2).

Подповерхностное рассеивание света — это довольно часто встречающееся в реальном мире явление. Заключается оно в том, что на большинстве полупрозрачных объектов свет заходит как бы вовнутрь и рассеи­вается не только на поверхности этого объекта, но и внутри. Таким свойством обладают, например, воск, матовое стекло и, что очень немаловажно именно для игр, человеческая (да и не только человеческая) кожа. В принципе, придумано множество различных алгоритмов для имитации этого эффекта, а подробное их описание заняло бы слишком много места. Имитацию этого эффекта можно встретить уже в различных технологических демонстрациях от nVidia и ATi (всякие шпионки да русалки — кожа там у них реалистичная). В играх же, судя по всему, этот эффект будет в грядущем Madden NFL 2007 (правда, на Xbox2).
4) Мягкие тени на основе фильтрации с процентным перекрытием (percen­tage clo­ser filter — PCF) (рис. 3).

Мягкие реалистичные тени с самозатенением для графических движков — давнишняя проблема для разработчиков. Фактически полностью ускоряемым и выполняемым в реальном времени без предрасчетов алгоритмом для мягких теней является PCF. Это алгоритм на основе теневого буфера. Теневой буфер — это тот же Z-буфер, но со стороны источника света. При рендеринге самого кадра координаты каждой точки трансформируются из экранной системы координат в систему координат источника света, после чего Z-координата точки сравнивается с соответствующим значением в теневом буфере и, если она больше, то точка в тени, иначе — на свету. Идея же PCF состоит в том, что Z-координата точки сравнивается с несколькими рядом лежащими значениями в теневом буфере, после чего конечный результат усредняется. Проблема лишь в том, что, дабы количество градаций полутени было достаточно большим и не резало глаз, надо сделать очень много таких сравнений. На старых версиях шейдеров для этого просто не хватало количества инструкций! Теперь это уже не проблема — 512 инструкций более чем достаточно, но при такой длине шейдера встает проблема тормозов. На помощь тут могут прийти динамические ветвления: сначала с помощью достаточно небольшого количества сравнений определяется, лежит ли точка в полутени, и, если лежит, то произ­водится большое количество сравнений в цикле, иначе этот самый цикл просто пропускается. Играми, где заявлено об использо­вании этого алгоритма (для подвижных объектов) являются проекты на движке Unreal 3.
5) Предрассчитанная передача излучения (precomputed radiance transfer — PRT). PRT — это алгоритм для имитации реалистичного освещения с учетом таких вещей, как вторичное освещение (то же самое, что отраженный свет) и распространение света в среде. Причем для расчета столь реалистичного освещения используются две самые простые и быстрые арифметические операции — умножение и сложение. На этом, в общем-то, все счастье и заканчивается, ибо, как следует из названия, нужно делать предварительные расчеты, причем весьма серьезные, и результат их занимает немало места. К тому же, как следует из предрасчетов, не все подлежит динамике, то есть двигаться может только источник света, а вот геометрия сцены должна обязательно оставаться неподвижной. Но и на этом беды не заканчиваются, так как источник света может быть только вне освещаемой сцены, как, например, луна или солнце, что весьма затрудняет использование PRT в играх. Впрочем, последнее ограничение можно обойти, но для этого потребуется весьма много сложных ухищрений. Играми, где заявлено об использовании этого алгоритма (для статических объектов) являются проек­ты на движке Unreal 3.
6) Динамическое фоновое перекрытие с тенями (dyna­mic ambient occlusion with sha­dows) (рис. 4).

Фоновое перекрытие — это, по сути, семейство алгоритмов для расчета вторичного освещения. Однако до сих пор они давали результат без теней, либо требовались предварительные расчеты. Совсем недавно появился алгоритм, разрешающий все эти недостатки (правда, требует третьи шейдеры!), зато он пригоден для динамических объектов и рабо­тает, естественно, в реальном времени. Конечно, он не может похвастаться такими результатами реалистичности, как PRT, поскольку предназначен исключительно для расчета вторичного освещения (правда, не исключено, что в будущем на его основе появятся алгоритмы и для первичного освещения). Из недостатков сле­дует отметить (хотя какие недостатки, других алгоритмов с подобными характеристиками пока не существует), что необходимо построение бинарного дерева для геометрии сцены (а это значит, что нужен не только мощный VPU, но и неслабый CPU). Кроме того, сцена должна быть геометрически очень высокодетализированной, иначе появляются различные артефакты. Одним словом, это очень перспективный алгоритм, но время его появления в играх достаточно сложно предсказать из-за все-таки очень высоких требований к мощности всей системы.

Часть пятая: прекрасное далеко…
В принципе все, что можно сказать, уже сказано, осталось лишь подумать о будущем, которое оба гиганта 3D графики видят несколько по-своему. Впрочем, в самом ближайшем будущем нас ждет приблизительно одно и то же. И R520, и G70 будут поддерживать третьи шейдеры (да, эта технология будет долго еще использоваться). Вероятнее всего, обе компании сделают что-то вроде очередной работы над ошибками. ATi добавит третьи шейдеры (надеемся, что они сразу будут достаточно быстрыми), а nVidia, вероятно, просто несколько оптимизирует конвейеры для скорости и, может быть, добавит фильтрацию текстур в вершинные шейдеры. А вот в долгосрочной перспективе все куда интереснее. В будущих шейдерных моделях, видимо, наступит полная программируемость, а значит, от оптимизации с помощью квадов придется отказаться. Отсюда следует, что нужно искать замену этой оптимизации, иначе тормоза неминуемы. Для этого ATi собирается сделать конвейеры универсальными, и с простоями теперь вообще не надо будет бороться. NVidia же парирует эту идею тем, что достаточно быстрые универсальные конвейеры создать невозможно, и поэтому собирается пойти по пути создания многоядерного VPU. Так-то. Ну, нам пора закрываться на обед, а кто из компаний прав — мы узнаем, лишь когда доживем.


Рекомендуем почитать: