⇣ Содержание
Опрос
|
реклама
Самое интересное в новостях
Анатомия игровых движков
Эффективное использование памятиДавайте поговорим о том, как память на 3D карте используется сегодня, и какие улучшения нас ждут в будущем. Большинство 3D ускорителей сегодня работают с 32-битным цветом, где 8 бит отводятся на красный, 8 на зеленый, 8 на синий и 8 на атрибут прозрачности для любого пикселя. Такая палитра позволяет получить 256 оттенков для красного, синего и зеленого, что в совокупности дает 16,7 млн цветов - это именно то число цветов, которое человек способен вообще различить на мониторе. Почему же гуру в области дизайна игр Джон Кармак ратует за переход к 64-битному цвету? Если мы не можем увидеть разницы, то зачем нам нужно увеличивать число цветов? Дело здесь совершенно в другом. Предположим, что у нас есть модель, которая освещена несколькими источниками разного цвета. Мы берем оригинальный цвет модели, а затем просчитываем один источника света, который изменяет значение цвета. Затем мы просчитываем еще один источник, который тоже изменяет значение цвета. Здесь и выявляется проблема - мы можем оперировать только 8-ю битами, и после наложения 4-х цветов 8 бит недостаточно для приемлемого представления получившегося света. При этом мы становимся свидетелями ошибок квантизации, которые являются ошибками округления при недостаточном числе битов. То есть вам уже очень скоро будет недоставать битов, и при этом цветовая информация будет теряться. Если бы на каждый цвет отводилось 16 или 32 бита, то можно было бы повысить цветовое разрешение. И даже после наложения оттенка за оттенком мы бы получили адекватное финальное значение цвета. Однако подобное увеличение битов быстро приводит к увеличению потребляемой памяти.Не следует забывать, что большая часть памяти карты отводится под хранение текстур. Каждый 3D ускоритель несет ограниченное количество памяти, часть которой должна быть отведена под "передний" и "задний" буферы, z-буфер, ну и конечно, текстуры. Если на первой карте Voodoo1 было 2 Мб памяти, то на Riva TNT количество было увеличено до 16 Мб. Затем GeForce2 и ATi Rage получили 32 Мб, а теперь мы стали свидетелями перехода от 64 Мб к 128 Мб. Почему большой объем памяти так важен? Что ж, давайте немножко посчитаем. Предположим, ваша игра будет работать в 32-битном цвете при разрешении 1280x1024 с 32-битным Z-буфером, поскольку вы желаете получить максимальное визуальное качество. Хорошо, тогда у нас выходит 4 байта на пиксель для экрана, плюс 4 байта на пиксель для Z-буфера, поскольку и там и там размер пикселя составляет 32 бита. При разрешении 1280x1024 мы имеем 1 310 720 пикселей. Умножим на 8 (суммарное число байт для каждого пикселя "переднего" буфера и Z-буфера) и получим 10 485 760 байт. Добавим "задний" буфер и мы получаем 1280x1024x12 байт, или 15 728 640 байт, что равно 15 Мбайт. Если бы на нашем ускорителе было 16 Мб памяти, то под текстуры у нас остался бы жалкий 1 Мб. Если сами текстуры тоже 32-битные, что сегодня является общепринятой практикой, то в 1 Мб мы можем хранить 1 Мб / 4 байта = 262 144 пикселя. Это примерно 4 текстуры размером 256x256. Приведенный пример ясно показывает, что старые 16 Мб карты не соответствуют требованиям сегодняшних игр. Нам просто придется перезагружать текстуры для каждого кадра в карту. Именно для этого и была предназначена AGP шина, однако AGP все-таки медленнее кадрового буфера 3D карты, поэтому вы получите ощутимое падение производительности. Очевидно, если вы понизите цветовое разрешение текстур до 16-ти бит, то вы сможете передавать их в два раза быстрее по AGP шине. Также если вы уменьшите и экранное цветовое разрешение, то на вашей карте освободится дополнительное место для кеширования текстур. Но вы никогда не сможете определить, как пользователь настроил свою систему. Если их карта может работать на высоком разрешении и глубине цвета, то, скорее всего, именно они и выставлены. Наведем туманТеперь давайте перейдем к туману, который является визуальным эффектом. Большинство современных движков поддерживают туман, поскольку он бывает очень полезен для сокрытия мира на удалении, так что вы не видите, как модели и география сцены внезапно появляются на горизонте при попадании в зону видимости. Существует также и объемный туман (volumetric fogging). В данном случае он не служит для сокрытия горизонта, а является физическим объектом, который вы можете видеть, проходить сквозь него или обходить стороной. При этом визуальные эффекты от тумана будут меняться. Подумайте о путешествии сквозь облако - тогда вы сразу поймете, что такое объемный туман. Хорошим примером реализации объемного тумана являются несколько уровней Quake III или версия Lucas Arts Rogue Squadron II для Game Cube. Как нам кажется, там используются одни из самых реалистичных туманов.При разговоре о тумане неплохо бы упомянуть про альфа-тестирование и альфа-сопряжение (alpha blending) текстур. Когда визуализатор отображает какой-либо пиксель на экране, при условии прохождения пикселем теста Z-буфера (описано ниже), мы должны осуществить альфа-тестирование. При этом мы можем обнаружить, что пиксель должен быть прозрачным, дабы показать, что за ним скрывается. Тогда мы должны знать значение пикселя, который находится за текущим, и далее нам следует обработать цвета двух пикселей и вывести на экран уже результирующий пиксель. Такая операция проходит по сценарию "чтение-модификация-запись", и она потребляет намного больше времени, чем обычная запись пикселя. Существует несколько алгоритмов сопряжения (смешения) пикселей. Прямое альфа-сопряжение добавляет некоторый процент "теневого" пикселя к оставшимся процентам от нового пикселя. Добавочное альфа-сопряжение берет процент "старого" пикселя и просто добавляет его к новому пикселю (не учитывая процентное соотношение). Последний способ дает более яркие эффекты (к примеру, эффект светового меча Кайла в Jedi Knight II). С каждым новым поколением 3D ускорителей, мы получаем новые и более сложные виды альфа-сопряжения, которые позволяют создавать умопомрачительные эффекты. Ну и конечно, с учетом пиксельных программ (шейдеров) в GF3+4 и последних платах Radeon, пределом здесь может стать только ваша фантазия. Трафаретное затенение и проверка глубиныТрафаретное затенение (stencil shadowing) открывает перед нами новые возможности. Мы не будем вдаваться в детали (данная тема заслуживает отдельной статьи), но суть трафаретного затенения заключается в просчете вида модели с перспективы источника света, а затем в использовании полученного результата для создания полигона с результирующей текстурой на нужном предмете. То есть вы, фактически, создаете объемное освещение, которое "падает" на остальные полигоны. В результате мы получаем реалистичное освещение, которое имеет свою перспективу. Но такое освещение потребляет существенные вычислительные ресурсы, поскольку здесь требуется создавать текстуру "на лету" и делать несколько проходов рендеринга для одной сцены. Вы можете создавать тени множеством способов, и, как это обычно бывает, результирующее качество зависит от задействованных вычислительных ресурсов. Здесь разделяют так называемые "четкие" и "мягкие" тени, причем последние более предпочтительны, поскольку они аккуратнее моделируют способ появления теней в реальном мире. К тому же существует несколько других "достаточно хороших" способов отображения теней, которыми пользуются разработчики игр.Проверка глубиныИтак, мы подошли к проверке глубины, при которой закрытые пиксели будут отбрасываться, чтобы избежать избыточной отрисовки (overdraw). Понятие избыточной отрисовки достаточно просто формулируется - чем больше раз вы выводите один и тот же пиксель в кадре, тем больше избыточная отрисовка. Это число зависит от количества элементов на 3D сцене в измерении по глубине (оси Z). Если избыточная отрисовка происходит слишком часто, например, при создании сияющих эффектов заклинаний, как в Heretic II, то частота кадров будет заметно уменьшаться. Некоторые визуальные эффекты в Heretic II, когда несколько людей на экране начинали творить заклинания друг на друга, приводили к ситуациям, в которых один пиксель мог отрисовываться на экране 40 раз! Тут и к гадалке не ходи - необходимо изменить подобную ситуацию, особенно в программном визуализаторе, который просто не может справиться с такой загрузкой, не превратив игру в слайд-шоу. Проверка глубины - это технология, которая используется для определения перекрытия одних объектов другими в данном положении пикселя, чтобы избежать избыточной отрисовки.Посмотрите на данную сцену и подумайте о том, что вы видите. Другими словами, какие из объектов друг друга перекрывают? На этот вопрос как раз и отвечает проверка глубины. Достаточно просто объяснить, почему проверка глубины увеличивает частоту кадров. Представьте себе детальную сцену, где находится множество полигонов (или пикселей) друг за другом, и пусть до передачи сцены визуализатору не существует быстрого способа отбрасывания перекрытых полигонов. При сортировке непрозрачных полигонов по оси Z, когда ближние к экрану полигоны будут отображены первыми, вы заполняете сцену самыми близкими к вам пикселями. Когда вы начинаете отображать пиксели за существующими (как определяет проверка глубины), их можно легко отбросить, экономя время и ресурсы. Если бы вы отображали объекты на экране наоборот, от самых дальних к самым ближним, то все перекрытые объекты полностью бы отрисовывались, после чего их бы перекрывали другие объекты. Чем сложнее сцена, тем хуже была бы ситуация. Так что от проверки глубины есть реальная польза. СглаживаниеДавайте вкратце поговорим про сглаживание. При отрисовке отдельного полигона, 3D карта проверит уже созданную сцену, и "замажет" границы нового полигона, чтобы вы не увидели на экране характерных "лесенок". Технология реализуется двумя способами. Первый подход - на уровне отдельных полигонов, который требует отображения полигонов в порядке от задних к передним, чтобы каждый полигон смог правильно "смазаться" с теми полигонами, что находятся позади его. При беспорядочном рендеринге вы получаете различные артефакты. Второй подход заключается в рендеринге целого кадра в более высоком разрешении, чем нужно, и затем уменьшении изображения для устранения "лесенок" при масштабировании. Второй подход дает хороший результат, но он сильно сказывается на потреблении памяти и на ее пропускной способности, поскольку карте нужно обработать больше пикселей, чем на итоговом кадре. Большинство новых видеоускорителей хорошо справляются с такой работой, причем вы можете выбрать различные режимы сглаживания по отношению качество/производительность.Вершинные и пиксельные программы (шейдеры)Перед завершением разговора про технологии рендеринга, давайте немного остановимся на вершинных и пиксельных программах, поскольку в последнее время они привлекают достаточно много к себе внимания. Вершинные программы позволяют напрямую задействовать аппаратные возможности карты, без сильного упора на API. К примеру, если карта имеет аппаратный модуль T&L, вы можете написать DirectX или OpenGL код и надеяться, что вершины пройдут через T&L модуль (удостовериться в этом нельзя, поскольку все происходит на уровне драйвера), или вы можете обратиться к железу и использовать вершинную программу-шейдер напрямую. Благодаря вершинным программам вы можете писать код, напрямую использующий функции карты - T&L модуль и другие функции, предлагаемые видеоускорителем. Фактически подобная возможность уже существует в современном поколении карт ATi и nVidia.К сожалению, механизм доступа к вершинным программам у них не одинаков. Вы не можете просто написать код вершинной программы и запускать ее на любой карте, как это осуществлялось с кодом OpenGL и DirectX. Однако, поскольку программа работает напрямую с "железом", вы можете рассчитывать на быстрый рендеринг всевозможных эффектов. (Равно как и создание новых потрясающих эффектов - вы можете делать то, что не позволяет API). Фактически вершинные программы переносят 3D карты обратно в мир приставок, где используется прямой доступ к оборудованию, и разработчики выжимают максимум из системы, а не просто уповают на API. Некоторых программистов такой подход шокирует, но таков прогресс. Вообще, вершинные программы - это процедуры, использующиеся для просчета и реализации вершинных эффектов перед передачей их на карту для рендеринга. У вас есть выбор - вы можете выполнить такие же процедуры программно на центральном процессоре или использовать вершинные программы на карте. Трансформация скелета анимированной модели - это основная задача для вершинных программ. Пиксельные программы (шейдеры) - это процедуры, которые применяются к каждому пикселю при рендеринге текстуры. Вы можете отказаться использовать встроенные режимы сопряжения пикселей и заставить карту применять для этого вашу программу. Благодаря этому вы можете получить новые интересные пиксельные эффекты, типа расфокусировки текстур при удалении, добавлении теплового марева или внутреннего отражения воды. Поскольку ATi и nVidia пришли к соглашению по версиям пиксельных программ (и DX9 вводит новый язык программирования), будет неудивительно, если DirectX и OpenGL пойдут по пути Glide - с него просто начинать, но он отнюдь не является лучшим способом выжимать максимум ресурсов из карты. В любом случае, будет интересно проследить за развитием ситуации. В завершение...Итак, визуализатор - эта та часть игры, за которую программистов сильнее всего ругают. Визуальная привлекательность много значит в игровом бизнесе, так что ее всегда необходимо учитывать. Одним из самых плохих факторов для программистов визуализатора является скорость, с которой развивается индустрия 3D карт. Сегодня вы стараетесь получить картинку с нормально работающей прозрачностью, а завтра nVidia проводит презентацию по вершинному программированию. Все очень быстро меняется, и по большей части тот код, что был написан для 3D карт за последние 4 года, теперь можно выкидывать - он требует полной переработки. Даже Джон Кармак упомянул, что код, написанный им четыре года назад и выжимающий максимум из 3D карты, теперь просто банален - поэтому он решил полностью перерабатывать визуализатор для каждого нового проекта Id. Тим Свини из Epic согласен с Джоном:"Мы потратили целых 9 месяцев на замену кода визуализатора. Первый Unreal опирался на полностью программный рендеринг, далее он был расширен до аппаратного рендеринга. Следующее поколение движка разрабатывается под GeForce и лучшие карты, в нем обрабатывается в 100 раз больше полигонов, чем в Unreal Tournament. Мы полностью заменили визуализатор. К счастью, наш движок модульный и мы смогли не ворошить остальную его часть - редактор, физику, AI, сеть, - хотя мы их, конечно же, тоже улучшаем. API: плохо это или хорошо?Итак, что же такое API? Это прикладной интерфейс программирования, который является прослойкой между программой и драйвером карты. К примеру, почти каждая 3D карта сегодня по-разному реализует трехмерность. Однако все карты предоставляют разработчику единый интерфейс, что позволяет писать одинаковый код для всех карт. По крайней мере, в теории. Почти три года назад это было верно, но сегодня положение на рынке изменилось, и в лидеры вышла nVidia.Что касается ПК, то вы можете создать свой собственный программный растеризатор, который будет использовать центральный процессор для отрисовки спрайтов, полигонов и частиц - и люди до сих пор так и делают. Age of Empires II: Age of Kings - это пример хорошего программного растеризатора, точно так же, как и Unreal. Затем вы можете использовать один из двух возможных графических API, OpenGL или DirectX. OpenGL - это кросс-платформенный API (программы, написанные под него, будут работать под Linux, Windows и MacOS), он существует уже достаточно большой период времени, его хорошо знают и понимают, но и его возраст тоже начинает ставить свои барьеры. Еще несколько лет назад над функциональностью OpenGL драйвера работали все производители карт. Однако, как только функциональность была достигнута, перед разработчиками далее не стояло четкого пути для развития, поэтому каждый стал дополнять драйвер своей функциональностью, используя расширения OpenGL. 3dfx создала T-буфер. nVidia озадачилась аппаратной трансформацией и освещением. Matrox пошла в направлении наложения карт неровностей. И так далее. Как видим, за несколько лет в 3D графике произошли существенные изменения. В любом случае, вторым возможным выбором является DirectX. Он полностью контролируется Microsoft, и по понятным причинам он существует только на ПК с Windows и Xbox. Никаких версий под Apple или Linux. Поскольку Microsoft контролирует DirectX, он встроен во все современные версии Windows. Основное отличие между DirectX и OpenGL заключается в том, что последний является собственностью "сообщества", а первый - Microsoft. Если вы хотите, чтобы DirectX поддерживал новые функции вашей 3D карты, то вам нужно обращаться к Microsoft, надеяться, что компания к вам прислушается и ждать новой версии DirectX. Что касается OpenGL, то поскольку производитель карты поставляет OpenGL драйвер в комплекте, вы можете сразу же получить доступ к функциям карты через OpenGL расширения. Все, конечно, хорошо, но с точки зрения разработчика игры, вы не можете надеяться на распространенность расширений при написании кода. И хотя расширения могут увеличить скорость на 50%, вы не можете потребовать от каждого пользователя установить GeForce3 в свой компьютер. Нет, конечно, можете, но в следующем году вы будете сушить сухари. Мы упустили различные детали, но суть ситуации вы должны представлять себе достаточно четко. С DirectX вы всегда знаете, чего вы получите от карты в данный момент времени, так как если функция аппаратно на карте не реализована, DirectX будет программно ее эмулировать (не всегда эффективно, поскольку в ряде случаев такой подход сильно замедляет игру, но мы сейчас говорим не об этом). С OpenGL вы можете выждать из карты больше, однако вы не будете уверены, присутствуют ли на пользовательской машине нужные вам функции. В следующей части мы поговорим о моделировании персонажей, анимации и уровне детализации. Если Вы заметили ошибку — выделите ее мышью и нажмите CTRL+ENTER.
|