БУМАЖНЫй НОМЕР
![]() |
01.12.2001
Дмитрий Лаптев
Каждое
новое поколение видеоускорителей обещает нам невиданное доселе,
абсолютно точное воссоздание реального мира на плоском экране.
Справедливости ради надо признать, что за свою короткую историю графические технологии прошли огромный путь - от примитивных плоских картинок до захватывающих и действительно объемных миров. Причем для описания возможностей современной видеокарты одного показателя скорости мало. Сотни миллионов пикселей в секунду только «разогревают» потенциального покупателя, после чего на его голову обрушивается поток «страшных» терминов: трилинейная фильтрация, мультитекстурирование, сдвоенный или учетверенный конвейер… «И вы учтите, что в ней ГПУ работает с восемью источниками света!» 1.
От такого «учтите!» кто угодно испугается.
ГПУ! В ней? Теперь ясно, что без отражающих текстур никакой жизни не будет, и надо срочно копить деньги, чтобы наскрести хоть на пару источников света, а остальные шесть попросить в рассрочку.
Шутки шутками, но речь идет не о маленьких деньгах - топ-модельные видеокарты сегодня способны «съесть» половину цены системного блока. Так что есть резон хоть в общих чертах понять, за что мы платим, покупая графическое железо.
Задачки для процессоров
Игровой мир, как и наш, обычный, реальный, «раскладывается» в трех
измерениях, отсюда и пошел термин 3D (three dimensions). Из любой точки
объемного мира мы можем видеть сразу ширину, высоту и глубину объектов. Для
отображения объема на плоскости давно придуманы средства - проекции,
перспектива, наложение света, теней, как на чертежах и художественных полотнах.
Так что обмануть зрение и поместить на плоском экране «фотографию» не так и
сложно. Только вот беда - в современных играх картинку нельзя жестко закрепить
на экране. Стоит игроку (герою
игры)
чуть сдвинуться и тем более повернуться, как изображение мира превратится в
совершенно другую «фотографию».
Если решать задачу в лоб и обсчитывать каждую точку игрового объема, никакой памяти не хватит, и никакой современный процессор не сможет перемалывать такую массу данных в реальном времени. Для скромных размеров комнаты 5х5х3 метра, при условии, что один экранный пиксель соответствует одному квадратному сантиметру «натуры», потребовалось бы помнить 500х500х300 = 75 000 000 точек! Что уж говорить об играх, где уровни могут занимать сотни квадратных метров площади. Поэтому в игровых движках 2 обрабатываются лишь основные точки - вершины каркаса (или «скелета») объектов.
Тогда задача создания мира упрощается. Первым делом каркасы всех объектов надо развернуть и отмасштабировать, чтобы вид на экране предстал перед нами именно таким, как его видит герой игры или, допустим, одна из камер наблюдения в NFS. Эта процедура называется transformation, и раньше, во времена простых видеоускорителей, а не графических процессоров (GPU), она ложилась на плечи центрального процессора (CPU).
Грамотный расчет c заданной точки зрения серьезно упрощает и дальнейшую работу, ведь в действительности часть объектов окажется невидимой (их заслонят другие), да и видимые также будут наблюдаться лишь с одной стороны. Вид со спины нападающего на нас монстра рисовать не нужно, и уж совсем ни к чему ежесекундно готовить к показу обстановку в соседней комнате, скрытую от нас стенами.
Далее рассчитывается освещение - lighting 3.
На этом этапе еще только определяется, сколько света попадает на каждую из
вершин каркаса с учетом всех световых источников. Обычный метод «трассировки
луча» подразумевает отслеживание пути лучей от каждого из источников света до
каждой точки объемной картины. И
если
источников несколько, вычисления становятся настолько емкими, что без
аппаратного ускорения не обойтись. Впрочем, восьми упомянутых в начале
«светильников» достаточно для очень реалистичной световой раскраски. Но пока, на
этапе lighting, готовятся только опорные данные, их реальное применение для
создания поверхностей и теней - следующий комплекс процедур, а до них еще нужно
детализировать каркас, разбить поверхность на треугольники и четырехугольники
(полигоны, или примитивы).
Раскраска
Пока мы получили только основу будущей картины - форму объектов. Дальше на элементы формы надо надеть виртуальную одежду - текстуры. Текстура - это обыкновенная плоская картинка, хранящаяся в видеопамяти либо в оперативной памяти компьютера (тогда они подкачиваются по мере надобности по каналу AGP). Чтобы не расходовать память зря и перекачивать поменьше данных, текстуры часто хранят в сжатом виде. И ускорителю всего-то надо распаковать их и покрыть стены изображением кирпичей, персонажей - шкурами или доспехами, а деревья - листьями (происходящее на этом этапе принято называть рендерингом). Но здесь, хотя принципиально невидимые предметы уже отсечены, нам снова приходится удалять «лишние» поверхности, которые образуются из-за взаимного перекрытия объектов. Например, какая-нибудь часть стены наверняка окажется закрыта шкафом, и если просто покрыть текстурами стену и шкаф, то получится картинка, напоминающая бракованный фотоснимок, когда забывают перемотать пленку и кадры накладываются один на другой. Эта проблема решается введением z-буфера, в который записываются значения глубины (z-координата) каждого пикселя в формируемой картинке. Если на одной линии (взгляд игрока) оказываются точки разных объектов, то для вывода на экран отбираются пиксели с минимальной глубиной - те, которые находятся ближе к «точке зрения» игрока.
Наложение текстур ведет за собой еще массу задач. Если игрок не стоит
упершись лбом в стену, большинство поверхностей оказывается не под прямым углом
к направлению его взгляда, а уходят вдаль, в перспективу. Функция, заведующая
реалистичным отображением текстур под разными углами зрения, так и называется
«коррекция перспективы». Но для дорог,
стен,
заборов и прочих протяженных объектов народного хозяйства одной коррекции мало.
Застелить их одним комплектом текстур - значит, получить прямо перед глазами
крупноблочный рисунок (текстура слишком мала, чтобы покрыть крупный объект), а
вдали - мешанину пикселей (текстура слишком велика, чтобы влезть в уменьшенный
перспективой кусок объекта). С крупными объектами хорошо справляются большие
текстуры (например, 2048х2048 пикселей могут покрыть весь экран). А для
перспективы приходится применять MIP-mapping: одни и те же объекты на разных
расстояниях покрываются текстурами разного размера (MIP-уровня, разрешения).
Но здесь невооруженный глаз опять наталкивается на «ненатуральность» картинки. Стыки между текстурами разных MIP-уровней слишком заметны, да и текстуры одного уровня на разных объектах вносят все тот же эффект «нестыковки». Поэтому следующий этап «обмана зрения» - сглаживание швов между текстурами. Называется это 3D-фильтрацией, которая бывает билинейной, трилинейной и анизотропной. В любом случае стык формируется из нескольких точек текстуры (текселей) с одного края и нескольких - с другого. Билинейная фильтрация усредняет цвет четырех соседних точек, трилинейная - девяти, а анизотропная - шестнадцати и больше. Разумеется, самый качественный эффект дает анизотропная фильтрация, но и «торможение» игры от нее самое заметное.
Следующая сложность - естественный вид поверхностей, передача особенностей микрорельефа. В этом случае зрение обманывается с помощью дополнительного комплекта текстур, которые кодируют отражающую способность разных частей поверхности: темным цветом отмечаются впадины, светлым - вершины (bump-mapping). Разумеется, дополнительную текстуру не накладывают поверх основной, а только используют при расчете освещения. Ведь именно по тому, как поверхность отражает свет, мы не задумываясь отличаем дерево от металла или песка.
Особый случай представляют зеркальные поверхности: лакированные бока гоночных
машин или водная гладь. Для них применяют текстурирование «кубическими картами
окружающей среды» (CEM-mapping). Название
мудреное,
смысл же очень простой - в качестве дополнительных текстур используется уже
нарисованная ускорителем часть трехмерного мира. Причем в нее могут входить
детали не видимые напрямую, выходящие за пределы экрана. CEM-mapping требует
очень большого объема расчетов, и включать эту функцию без заметного торможения
игры позволяют только самые мощные ускорители. При недостатке мощности можно
обойтись без такой роскоши, а абстрактный блеск стекла или металла неплохо
передается текстурами отражения (reflection map).
Но и после такой тонкой работы виртуальный мир не приобретет естественного вида, пока мы не организуем затенение и тени. Да, это разные эффекты. Затенение имитирует неравномерность освещения объектов, классический пример - шар, который без должной раскраски, зависящей от освещения, не отличить от круга. Тени же отбрасывают любые предметы (друг на друга, на стены и пол), так что правильный их расчет - отдельная рутинная задача, решаемая пока что с сильными упрощениями даже на самых мощных видеокартах.
Доводка
Природа заготовила для обмана зрения еще несколько «спецэффектов». К примеру, туман. Считать его отдельным трехмерным объектом? Или готовить отдельные «туманные» текстуры для элементов картины? И то, и другое усложняет задачу, а поскольку туман в играх используется очень часто, пришлось выделить его получение в отдельную функцию 3D-ускорителя (fogging), она смешивает текстуры объектов с цветом тумана по определенным законам. Выделяют, как минимум, две разновидности тумана: простой и экспоненциальный, сгущающийся вдали.
А как быть с настоящими полупрозрачными объектами? К примеру, оконное стекло,
толща воды или пламя? Здесь, увы, одной функцией в ускорителе обойтись не
удалось. Пришлось пойти куда более затратным способом - ввести для каждой точки
в стандартное представление цвета еще один канал - a (альфа), характеризующий ее
прозрачность.
Как известно, любой цвет раскладывается на три составляющие - красную, зеленую и
синюю (RGB). Поэтому в стандарте true color каждая точка запоминается в трех
байтах, или 24 битах. Канал прозрачности потребовал добавки еще одного байта.
Для представления каждой точки в 32-разрядном цвете памяти, естественно,
требуется больше, зато радикально решаются проблемы с прозрачностью любых
объектов.
Античеткость
К этому моменту у нарисованной компьютерной графики остается одно отличие от видеозаписи - изображение получается чересчур четким. Их, конечно, больше - отличий - но это сразу бросается в глаза. Особенно достается наклонным линиям, они приобретают характерную ступенчатость. Теоретически можно, конечно, поднять разрешение экрана на небывалую высоту, и глаз уже не будет различать отдельные ступеньки, но не факт, что ускоритель потянет игру с приемлемой скоростью (хотя в будущем, конечно, этот путь обмана зрения еще сыграет свою роль). Да и просто обидно - телевизор с позорно низким разрешением 720х576, возведенным в стандарт, никакой ступенчатостью не страдает! Поэтому приходится включать «античеткость»: процесс сглаживания линий - anti-aliasing - попросту размывает границы, смешивая цвет фона и объекта. Результат все равно получается не идеальным, лучшего можно достичь с полноэкранным сглаживанием (full screen anti-aliasing), но скорость игры при этом упадет в полтора-два раза.
Кроме того, человеческое зрение (и оптика фото- и видеокамер) имеют ограниченную глубину резкости. Компьютер же будет прорисовывать все объекты до самого горизонта одинаково четкими. Если не принять мер, разумеется. Меру специально выдумывать не пришлось, достаточно еще раз подпустить тумана на заднем плане. И наконец, смазывающиеся при быстром движении контуры объектов тоже получаются не сами собой, их имитирует функция motion blur.
Работа по обману зрения, как видите, проводится титаническая. Тем не менее,
не выходит ни одной новой модели ускорителей, где список процедур не был бы
пополнен еще парой-тройкой фирменных технологий. Последнее время у всех
на
слуху текстурные и вершинные шейдеры - короткие программы, которые загружаются и
выполняются непосредственно в видеопамяти. Шейдеры позволяют создателям игр
применять особо тонкие, нестандартные приемы для виртуозной работы с
поверхностями, светом, тенями, и пока только самые дорогие карты на GeForce3 и
Radeon 8500 обеспечивают их поддержку.
Прицел на будущее
Впрочем, применение шейдеров - это дело завтрашнего дня, игровая индустрия больше ориентируется на широко распространенные карты. И даже включение приемов «обмана зрения» в DirectX 8.1 и OpenGL 1.3 не гарантирует их быстрое появление в играх.
Но будущее в компьютерном мире наступает очень быстро, настолько быстро, что порой не успеваешь к нему подготовиться. Каркасы, полигоны… все это очень здорово придумано, но никто не говорил, что это единственный путь для получения трехмерной картинки на плоском экране. Есть и некоторые альтернативы, которые уже сегодня прорабатываются производителями графических чипов и создателями игровых движков.
Во-первых, сам собой напрашивается вариант использовать вместо плоских
полигонов кривые линии и поверхности, из которых преимущественно состоят
реальные объекты. Главный плюс такого представления в том, что при близком
рассмотрении
(масштабировании) объекты не распадутся на отдельные точки и противоестественные
блоки, а сохранят идеальную гладкость. Это знакомо тем, кто работал с векторной
графикой в том же Corel Draw. Отрицательным же можно считать тот факт, что
объекты по-прежнему остаются «пустыми», тогда как в реальном мире все имеет свою
начинку. Что, спрашивается, мы увидим, срубив в виртуальном лесу дерево?
Придется снова хитрить, подсовывая игроку картинку среза.
Между тем, когда-нибудь можно будет вернуться «к истокам» и сохранять трехмерные образы именно так, как упоминалось в самом начале статьи. То есть помнить цвет каждой точки объемного мира (точка такая именуется вокселем, по аналогии с элементом плоскости - пикселем). Положим, абсолютно все точки помнить незачем - воздух, да и внутренности многих объектов можно оставить пустыми. А массивы вокселей, как и текстуры, можно хранить в сжатом виде. Но и с такими упрощениями потребуется не один гигабайт видеопамяти (!) для реализации не самых сложных игровых сцен. Пока этот объем кажется необъятным, но… посмотрим, как наши представления о скорости и объемах памяти изменятся через два-три года. Кроме того, никто не мешает совмещать этот подход с «плоским» обманом зрения.
Главный плюс «воксельного» подхода - недостижимая сегодня гибкость и очень простые алгоритмы для работы с графикой. А главный минус (кроме высоких требований к памяти) - мы снова будем вынуждены думать о масштабе и детализации. Масштаб сантиметр/воксель хорош для архитектуры, а для персонажей и мелких предметов придется выбрать масштаб помельче, иначе мы снова столкнемся с крупными «кубиками» на экране.
Можно подойти и прямо с противоположных позиций. Мы строим на экране
изображение, которое максимально естественно должно выглядеть для человеческого
глаза? Замечательно! Из некоей точки перед экраном (откуда будет смотреть на
нашу картинку человек), проводим воображаемые линии через
каждый
пиксель будущего изображения. За плоскостью экрана каждый луч упрется в
какой-нибудь объект игрового мира и преломится на его поверхности или отразится
от нее. То же произойдет и с отраженным лучом и т. д. Мы же будем следовать за
каждым лучом до тех пор, пока он не пропадет в какой-нибудь источник света. Путь
каждого луча и характеристики каждой поверхности, встреченной им, запоминаются.
Тогда, взяв за основу цвет и яркость источника света и раскручивая в обратной
последовательности путь нашего луча, мы сможем точно определить, каким цветом
окрасится искомая точка экрана.
Пока этот метод можно считать самым отдаленным (в смысле реализации на обычных компьютерах, а не специализированных, которые на похожих принципах уже создают спецэффекты в кинопроизводстве). Но что придумают «графические маги» в ближайшие годы, думаю, даже самые смелые эксперты не возьмутся сказать точно. Так что есть смысл следить за новинками - от них зависит, насколько быстро наше зрение обманут окончательно.
1 (обратно к тексту) - Этой
характеристикой карты на GeForce 2 консультант в одной фирме до смерти напугал
моего знакомого. А ГПУ - это не Государственное политическое управление НКВД
РСФСР, а всего лишь graphic processor unit (графический процессор).
2 (обратно к тексту) - Игровой движок -
совокупность главных моделей и алгоритмов игры: топография игровой арены,
физическое взаимодействие объектов, искусственный интеллект противника и т. д.
3 (обратно к тексту) - Отдельный блок
геометрического ускорителя, обсчитывающий transformation и lighting, так и
называется - T&L. Аппаратная поддержка T&L превратила просто графические
ускорители в графические процессоры. Например, в GeForce3 блок T&L при полной
загрузке способен выполнить 76 миллиардов операций с плавающей точкой в секунду.