Графика в играх: DirectX 10 и дальше
Выход на рынок консолей нового поколения, с одной стороны, и DirectX 10 – с другой, поднял волну – нет, не волну, а настоящее цунами интереса к вопросам графики в играх. Люди под микроскопом сравнивают скриншоты с PC, Xbox 360 и PS3 или с DX9/DX10, стараясь найти там 10 отличий и понять, в чем же все-таки сила.
Не пытаясь объять необъятное, сегодня мы сконцентрируемся на вопросе, почему DirectX 10 – это хорошо, почему DirectX 11 – это еще лучше, и что ждет PC-игроков в ближайшие (а владельцев консолей – в несколько более отдаленные) годы.
gfx-01.jpg
Поскольку никакая статья о DirectX 10 невозможна без скришнотов из Crysis…
gfx-02.jpg
…пожалуйста, вот они – скриншоты из Crysis
Немного истории
Протирая взглядом до дыр скриншоты, снятые с DX10-игр, фанаты обычно надеются найти там что-нибудь сверкающее, переливающееся или другим способом ласкающее взгляд. В принципе, нельзя сказать, чтобы эта надежда была совсем беспочвенной. Новый API действительно содержит ряд нововведений такого плана: например, улучшилась реализация антиалиасинга, да и шейдеры и тени теперь могут быть еще более реалистичными благодаря повышенной точности, расширившимся возможностям GPU и фантастическим 128 текстурам на пиксель, – однако различия между качеством статических изображений в DX9 и DX10 нельзя назвать поражающими воображение.
Фокус в том, что DX10 позволяет рисовать не столько «лучше», сколько «больше, быстрее и разнообразнее». Чтобы понять смысл этой загадочной фразы в стиле гегелевской диалектики, нам нужно сделать небольшой экскурс в архитектуру современных графических API.
Десять лет назад, когда пиксели были большими, зарплаты маленькими, а графические ускорители только-только стали появляться на рынке, хороший графический движок можно было очень легко отличить от плохого. Хороший движок – это тот, который умел эффективно отбрасывать невидимую геометрию и рисовать только те полигоны, которые действительно попадают в поле зрения и не заслоняются другими объектами. Все стадии графического конвейера: преобразование координат, расчет освещения, растеризация – выполнялись на центральном процессоре и поэтому были очень-очень «дорогими». Так что практически любая оптимизация, сокращавшая количество графических операций с вертексами, пикселями и текселями, была оправданна. Именно поэтому большая часть литературы по оптимизации движков в то время была посвящена выбору наиболее подходящего алгоритма удаления скрытых поверхностей (Hidden Surface Removal – HSR), а в оставшейся части обсуждалось, как лучше адаптировать алгоритмы текстурной выборки к особенностям CPU. Первое поколение графических акселераторов не слишком изменило ситуацию: центральный процессор освободили от жутко трудоемкой растеризации, но операции по расчету освещения, преобразованию треугольников, отсечению невидимых граней по-прежнему остались на нем, хотя и были теперь уже скрыты от программистов в недрах glide, OpenGL или Direct3D.
Справка:
Что это вообще такое – DirectX 10?
Спойлер
Продолжая рассуждать философски, можно сказать, что DirectX имеет дуалистическую природу. С одной стороны, это графический API (Application Program Interface) – набор функций, позволяющих программистам выводить на экран движущиеся картинки. С другой стороны, это набор спецификаций, которым должно соответствовать графическое «железо», чтобы программисты могли использовать для работы с ним этот API.
В нашем обзоре мы практически не станем касаться DX10 как API, но будем говорить о возможностях DX10-железа. Нужно отметить, что эти возможности можно использовать не только через DirectX как таковой. Windows Vista поддерживает и конкурирующий API OpenGL (он родом из Unix). И под OpenGL программистам через специальный набор расширений будут доступны практически все те же возможности, что и программистам DX10 – но только при наличии соответствующей видеокарты.
С другой стороны, не существует никакой возможности запускать DX10-приложения на DX9-видеокартах (даже под Vista), потому что эти продукты просто не поддерживают необходимые функции на аппаратном уровне. Так что не стоит питать надежды, что кто-то когда-нибудь напишет утилиту, позволяющую это делать.
Переломным моментом стало появление GPU c аппаратной поддержкой расчетов освещения и преобразования координат (Transform & Lighting – TnL). Уже самые ранние и примитивные по сегодняшним меркам модели GeForce в несколько раз превосходили процессоры 1999-2000 года по количеству треугольников, которые они могли обрабатывать в единицу времени. Сложность моделей персонажей и уровней стала расти намного быстрее, чем раньше.
Достаточно скоро выяснилось, что главным ограничивающим фактором в повышении качества игровой графики является уже не недостаток производительности GPU, а неэффективная структура движков, построенных на старых принципах.
Как работал типичный игровой движок прошлого? CPU определял, какие элементы окружения видимы, производил над ними разнообразные трансформации и «скармливал» треугольники растеризаторам видеокарты, затем анимировал (то есть изменял по определенным алгоритмам координаты вершин в моделях) персонажей и все, что должно двигаться, трансформировал в нужную систему координат и тоже отправлял видеокарте. Помимо очевидных неприятностей, связанных с тем, что по шине между системой и видеокартой в каждом кадре приходилось перегонять очень много данных, проявила себя «во весь рост» и не слишком очевидная раньше проблема – высокие «накладные расходы» при каждом вызове драйвера, который должен передать информацию или команды графическому процессору.
В результате получалось, что видеопроцессоры потенциально могли обрабатывать уже великое множество треугольников и пикселей, но на практике большую часть времени простаивали, ожидая, пока CPU подготовит для них новую порцию данных или выполнит все положенные «церемонии» по передаче через драйвер новых указаний, необходимых для правильного изображения сцены.
Справка:
DirectX и консоли
Спойлер
Существует определенная путаница, когда речь заходит о том, «какая версия DirectX на консолях». Помимо PC, DirectX используется как API (то есть средство взаимодействия игры с графическим «железом») в приставках Microsoft: Xbox и Xbox 360. Версия DirectX в первой Xbox примерно соответствовала DX8 – в качестве видеочипа там использовался аналог GeForce 3/4, соответствующий спецификациям этого API. В Xbox 360 применяется специальная версия DirectX, которая по архитектуре и возможностям занимает промежуточное положение между DX9 и DX10, – можно сказать, что при разработке DX10 инженеры Microsoft активно использовали опыт Xbox 360. Соответственно, и «железо» этой консоли поддерживает промежуточную шейдерную модель 3.5 (в DX9 была 3.0 максимум), в которой много от DX10 и SM 4.0, но нет геометрических шейдеров.
С консолями Sony все сложнее. В PS2 графическая подсистема была разработана самим производителем и никаким сторонним стандартам и спецификациям не соответствовала. В PS3 Sony была вынуждена использовать PC-чип Nvidia G70 (GeForce 7800/7900), изначально созданный для соответствия требованиям DirectX 9.0c и SM 3.0. Таким образом, можно сказать, что «железо» PS3 находится на уровне DX9, хотя сам этот API в консоли Sony по понятным причинам не применяется – вместо этого там используется модифицированная версия OpenGL.
gfx-03.jpg
Разработчики Call of Juarez любезно предоставили владельцам DX10-видеокарт зрелищный бенчмарк для оценки производительности
gfx-04.jpg
Пока что этот бенчмарк способен заставить загрустить любую, даже самую мощную видеокарту