⇣ Содержание
Опрос
|
реклама
Самое интересное в новостях
Анатомия игровых движков
Освещаем мирКогда освещение работает, вы его почти не замечаете. Но стоит только его убрать - вы сразу же это увидите. Существует несколько подходов к освещению, начиная от простого определения ориентации полигона к источнику света и добавления процента освещения на основе расстояния от полигона до источника, и заканчивая генерацией точных карт освещения для наложения на основные текстуры. А некоторые API имеют сразу несколько встроенных методов освещения. К примеру, OpenGL предлагает освещение по полигонам, по вершинами или по пикселям.При вершинном освещении определяется, сколько полигонов касаются одной вершины, и затем вычисляется результирующая нормаль к данной вершине (по нормалям всех примыкающих полигонов). Каждая вершина для данного полигона будет иметь несколько отличающуюся нормаль, так что вы можете проградуировать или интерполировать освещение по полигону, что приведет к более точному освещению. Преимущество такого подхода заключается в том, что «железо» может помочь выполнять освещение с помощью модуля аппаратной трансформации и освещения (T&L). Минусом является то, что при вершинном освещении не получается создавать тени. К примеру, обе руки на модели будут освещены одинаково, даже если свет падает справа, и левая рука должна находиться в тени от тела. Описанный подход вершинного освещения использует затенение (ретуширование). При использовании плоского освещения во время создании полигона движок будет закрашивать полигон нужным цветом. Такой процесс называется плоским затенением (каждый полигон имеет определенное значение освещенности по всей поверхности, что отнюдь не приводит к качественной картинке, не говоря уже о том, что вы сможете легко определить на экране границы каждого полигона). Что касается вершинного затенения (его также называют затенением по Гуро) движок рендеринга будет закрашивать уже каждую вершину нужным цветом. При отрисовке пикселя полигона его цвет будет вычисляться с помощью интерполяции цветов вершин, на основе удаленности пикселя от вершин. (Именно такой способ и используется на моделях в Quake III). Более изощренный способ затенения - по Фонгу. В отличие от простой интерполяции цвета вершин для определения цвета пикселя, здесь для каждого пикселя выполняются те же вычисления, что делались раньше для каждой вершины. При затенении по Гуро вы должны были знать, как свет падает на каждую вершину. При затенении по Фонгу вы должны знать это уже для каждого пикселя. Не удивительно, что затенение по Фонгу приводит к более точному освещению, но оно потребляет больше ресурсов, так как вычисления требуется провести уже для каждого пикселя. Самый простой способ - плоское затенение, но он не приведет к хорошему результату. Самый качественный - затенение по Фонгу, причем он позволяет создавать различные зрительные эффекты, типа полировки. Так что вам предстоит нелегкий выбор при разработке игры В различном светеСледующий подход к освещению базируется на вторых текстурных картах (картах освещения, light map), которые смешиваются с существующей текстурой для создания эффекта освещения. Все это прекрасно, но перед визуализацией вам нужно создать карты. Если же в игре у вас используетcя динамическое освещение (то есть источник света либо передвигается, либо включается/выключается), то вам будет необходимо создавать карты освещения на каждый кадр, изменяя их при движении динамического источника. Карты освещения можно создавать довольно быстро, но они требуют памяти для хранения соответствующих текстур. Конечно, можно задействовать технологию сжатия текстур для уменьшения занимаемого пространства, или сокращать размер текстур, даже превратив их в двухцветные (но тогда вы не получите цветного освещения) и т.д. Однако если на сцене используется несколько источников динамического освещения, то создание карт освещения может ощутимо ударить по производительности.Так что во многих играх используется гибридный подход к освещению. Quake III, к примеру, задействует карты освещения для мира и вершинное освещение для анимированных моделей. Предварительно просчитанное освещение не влияет на анимированные модели - они берут общую освещенность для всей модели от полигона, на котором стоит модель - затем на модель накладывается динамическое освещение для придания нужного эффекта. Гибридное освещение - это компромисс между производительностью и качеством, который многие люди не замечают, но который все же позволяет создать правдоподобные эффекты. Собственно, все игры и основываются на подобном принципе - создание максимально правдоподобного эффекта, пусть даже не совсем верного по своей сути. Конечно, в новом движке Doom все будет по-другому, но и сам движок требует 1 ГГц процессор и карточку не ниже GeForce2 для включения всех эффектов. Прогресс налицо, но и его цена - тоже. Как только сцена была трансформирована и освещена, происходят операции отсечения. Если не вдаваться в детали, при отсечении определяется, какие треугольники находятся полностью внутри сцены (в поле зрения - view frustum), а какие лишь частично заходят на сцену. Треугольники, полностью находящиеся на сцене, принимаются и обрабатываются. Если треугольник захватывается лишь частично, то его часть вне поля зрения должна быть отсечена, а остающаяся внутри сцены часть должна пройти повторную тесселяцию, чтобы новый полигон полностью попал внутрь поля зрения. Как только операция отсечения будет завершена, на следующей ступени конвейера происходит пересчет координат треугольников (его также называют scan-line conversion), когда сцена переносится на двумерное пространство координат экрана. Затем происходит непосредственно рендеринг. Текстурирование и кратная фильтрацияТекстуры очень важны для придания 3D сценам реалистичного вида. Они представляют собой маленькие картинки, которые разбиваются на полигоны и накладываются на объект или на какое-либо место в сцене. Большое количество текстур съедает ощутимый объем памяти, поэтому к текстурам применяются различные технологии уменьшения их размера. Сжатие текстур - одна из подобных технологий, при этом сжатие позволяет сохранить необходимое количество информации. Сжатые текстуры занимают меньше места на CD с игрой, и, что более важно, в оперативной памяти и в памяти на видеокарте. Еще одним плюсом является то, что когда карта запрашивает отображение текстуры на экране в первый раз, то из оперативной памяти по шине AGP в память видеокарты отсылается сжатая (меньшая по размеру) версия текстуры, что опять же немного экономит пропускную способность. Сжатие текстур - это хорошо. Ниже мы чуть подробнее остановимся на сжатии текстур.Кратная фильтрация (Mip-Mapping)Еще одной технологией, используемой в игровых движках для сокращения потребления памяти и пропускной способности, является кратная фильтрация текстур. При кратной фильтрации создаются несколько копий одной и той же текстуры, причем каждая последующая копия в два раза меньше по размеру предыдущей. Зачем же это надо? Для ответа на поставленный вопрос вам нужно понимать, как 3D карта отображает текстуру. В простейшем случае вы берете текстуру, прилепляете ее к полигону и отображаете его на экран. Здесь мы получаем отношение 1:1, когда один тексель (элемент текстуры) соответствует одному пикселю полигона данного объекта. Если же полигон затем уменьшился на экране в два раза, то на экран будут выведены, скажем, только четные тексели. Обычно ничего плохого в этом нет, но часто такой подход приводит к появлению различных артефактов. Представьте себе кирпичную стену. Скажем, оригинальная текстура - это и есть кирпичная стена с множеством кирпичей, но слой цемента между ними составляет всего один пиксель. Если вы уменьшите полигон в два раза от нормального размера, то при этом будут отображаться только четные пиксели, следовательно, цементная прослойка может вовсе исчезнуть с экрана. Вот мы и получаем нежелательный артефакт.При использовании кратной фильтрации изображение масштабируется программно, еще до отсылки видеокарте. Таким образом, его можно предварительно обработать, чтобы слой цемента не исчез. Когда 3D карта отображает полигон с текстурой на нем, она определяет масштаб и решает «давай вместо масштабирования самой большой текстуры, я возьму маленькую текстуру - она будет выглядеть лучше». В этом и заключается кратная фильтрация. Множественные текстуры и наложение карт неровностейИспользование одной текстуры позволяет получить реалистичную 3D графику, однако использование нескольких текстур приводит к еще более потрясающим эффектам. Для этого, конечно, потребуется несколько проходов рендеринга, которые будут потреблять скорость заполнения (fill rate). Однако многоконвейерные 3D ускорители типа ATi Radeon или nVidia GeForce2 и выше позволяют наложить несколько текстур за один проход. При создании многотекстурного эффекта на полигон накладывается первая текстура, затем над ним отображается еще один полигон с другой текстурой и с установленным коэффициентом прозрачности. Благодаря этому можно создать текстуры с эффектом движения, пульсации или даже текстуры с тенями (как мы описывали в части статьи про освещение). Просто нарисуйте первую текстуру, затем нарисуйте сверху полностью черную текстуру с коэффициентом прозрачности - и вы сразу же получите эффект тени. Такая технология называется наложением карт освещения (light mapping, иногда sometimes-dark mapping), и до выхода нового Doom именно такая технология использовалась при освещении уровней в движках Id.Наложение карт неровностей - это довольно старая технология, которая недавно вновь привлекла к себе внимание. Matrox стала первой компанией, внедрившей технологию наложения карт неровностей в популярных 3D играх несколько лет назад. Технология создает текстуру, которая отражает способ, которым свет попадает на поверхность. Благодаря этому на поверхности можно созi1123500.jpg" width="200" height="216" alt=" " border="0"> Наложение карт неровностей позволяет получить более эффектные детализированные текстуры, хотя и здесь требуется определенная ловкость рук, поскольку отображаемые неровности не изменяются относительно угла зрения пользователя. Учитывая по-пиксельные операции новейших карт ATi и nVidia этот недостаток можно устранить. Впрочем, наложение карт текстур до последнего времени не слишком часто использовалось разработчиками игр. Ситуация должна измениться - технология, как видим, полезная и интересная. Пробуксовка кэша - это плохоЭффективное управление кэшем текстур жизненно важно для ускорения игровых движком. Как и в любом кэше, хиты - это хорошо, а промахи - это плохо. Представьте себе ситуацию, когда текстуры будут постоянно загружаться и выгружаться из памяти видеокарты, в результате будет наблюi1123700_r.GIF" width="350" height="214" alt=" " border="0">Показана ситуация при использовании тройной буферизации и разрешении дисплея 1024x768x32. Кадровый буфер - 32 Мб. Некоторая память может быть выделена под код драйвера. После выделения памяти под цветовые и Z-буферы, под кэш текстур остается 20 Мб. Существуют различные технологии минимизации пробуксовки кэша, собственно они и подразумеваются под эффективным управлением кэшем текстур - жизненно важным элементом ускорения движков 3D игр. Управление кэшем текстур - полезная вещь, благодаря ней карта может запрашивать текстуру из основной памяти только один раз, а не много раз. Мы как бы говорим карте: «посмотри на все эти полигоны - они используют одну и ту же текстуру, так что давай мы загрузим ее один раз, и не будем загружать ее с каждым полигоном». Благодаря управлению кэшем текстур API (или программа, стоящая за драйвером видеокарты) не будет загружать текстуру на карту более одного раза. Мощные API типа OpenGL обычно сами управляют кэшированием текстур, то есть API часто само занимается хранением текстур на видеокарте и основной памяти компьютера на основе различных критериев. Однако главные проблемы здесь заключаются в том, что: а) часто вы не знаете правила, которые использует API и б) часто в кадре нужно отобразить больше текстур, чем вмещается в память видеокарты. Еще одной полезной технологией является сжатие текстур, которое мы уже немного затрагивали чуть выше. Текстуры сжимаются очень похожим на сжатие MP3 файлов способом, хотя о таком уровне сжатия приходится лишь мечтать. Если при сжатии WAV в MP3 мы получаем коэффициент сжатия 11:1, то при аппаратном сжатии текстур обычно получается отношение 4:1, но даже такие цифры заметно улучшают производительность. Кроме всего прочего, карта расжимает текстуры только при необходимости при отображении текстуры «на лету». Это очень хорошо, но мы лишь приоткрыли завесу над будущими технологиями. Как уже упоминалось, визуализатор заставляет карту отображать одну текстуру в один момент времени. Поэтому нам нужно удостовериться, что все полигоны, использующие одну и ту же текстуру, посылаются последовательно. Следовательно, очень неэффективно отображать сначала все полигоны для одного объекта, потом для другого и т.д. Если мы будем отображать полигоны с одной текстурой последовательно друг за другом, то мы можем передать текстуру только один раз. Quake III осуществляет подобную оптимизацию с помощью системы шейдеров. По мере обработки полигонов, они добавляются во внутренний список шейдеров, и как только все полигоны будут обработаны, визуализатор просматривает список по данной текстуре, и все полигоны с данной текстурой будут отосланы друг за другом. Описанный процесс не приводит к эффективному использованию T&L модуля на видеокарте (если он там есть). Ведь мы получаем большое количество маленьких групп полигонов, использующих одну и ту же текстуру в разных участках экрана, причем все они базируются на различных матрицах трансформации. То есть в данном случае большее время будет потрачено на настройку аппаратного T&L движка видеокарты. Подобный способ прекрасно работает для персонажей в игре, поскольку они используют одинаковую текстуру по всей модели. Но при отрисовке мира он не является эффективным, поскольку множество полигонов будут использовать одну и ту же текстуру стены. Конечно, обычно подобная ситуация не влияет заметным образом на скорость, поскольку текстуры для мира не слишком велики, так что система кэширования в API легко с ними справится и сохранит текстуру на карте при повторном использовании. На приставках обычно не используется никакой системы кэширования текстур (конечно, если вы ее не напишите). В случае PS2 лучшего всего использовать подход «текстура за один раз». В Xbox он не актуален, поскольку карта не обладает своей выделенной памятью (архитектура UMA), и текстуры всегда хранятся в основной памяти. Второе наиболее часто встречающееся узкое место современных стрелялок заключается в потугах прокачать по AGP шине слишком большое количество текстур. Следующее узкое место - обработка геометрии, которая отвечает за то, чтобы объекты появились именно там, где надо. Математика, использующаяся при генерации правильных координат каждой вершины в моделях, на сегодняшний момент отнимает больше всего вычислительных ресурсов 3D стрелялок. Так что вам следует постоянно следить за бюджетом текстур, если вы не хотите, чтобы ваша AGP карта была перегружена. Эффективным шагом будет снижение ограничение уровня кратной фильтрации по максимальному размеру, благодаря чему вы сможете уполовинить размер передаваемых по карте текстур. Конечно, визуальное качество ухудшится, особенно в заставках, зато частота кадров ощутимо возрастет. Такой подход очень хорош для игр по сети. И Soldier of Fortune II, и Jedi Knight II: Outcast используют ограничение кратной фильтрации, то есть они рассчитаны на будущие ускорители, которые пока лишь появляются на рынке. Для того чтобы эти игры работали с нормальным размером текстур, вам нужно минимум 128 Мб памяти на вашем видеоускорителе. В третьей части мы рассмотрим множество тем, включая управление памятью, эффект тумана, проверку глубины, сглаживание, вершинные шейдеры, API и т.д. Если Вы заметили ошибку — выделите ее мышью и нажмите CTRL+ENTER.
|