[Перевод] Архитектура первой PlayStation: графика

Начало: центральный процессор

Напомню, что большая часть графического конвейера выполняется GTE. В неё входит преобразование перспективы (проецирование 3D-пространства на 2D-плоскость при помощи вида из камеры) и освещение. Затем обработанные данные передаются собственному GPU Sony для рендеринга.

Упорядочивание содержимого

Система имеет 1 МБ VRAM, который используется для хранения буфера кадров, текстур и других ресурсов, необходимых GPU для рендеринга сцены. ЦП может заполнить эту область при помощи DMA.

Используемый тип чипа (VRAM) имеет двойной порт, как и в Virtual Boy. VRAM использует две 16-битные шины, что обеспечивает параллельный доступ между ЦП/DMA/GPU и кодировщиком видео.

Схема памяти с использованием VRAM

Схема памяти с использованием SGRAM

Однако в последующих версиях консоли Sony перешла на чипы SGRAM (однопортовый вариант, использующий отдельную 32-битную шину данных). Честно говоря, каждый из типов имеет свои плюсы и минусы. Точно одно — из-за разницы в таймингах более новые игры (например, Jet Moto 3) на машинах с VRAM отображались визуальные баги. Если вы хотите знать подробности, то изучите информацию о различии в таймингах и тому подобном в документе Матрина Корта «Nocash PSX Specifications».

Отрисовка сцены

Если вы читали статью про Sega Saturn, то могу сказать, что архитектура GPU консоли PS1 намного проще!

Чтобы показать, как отрисовывается сцена, я в основном буду использовать в качестве примера игру Spyro: Year of the Dragon компании Insomniac. Помните, что внутренyее разрешение этой игры слишком урезано (292×217 пикселей), что не позволит мне чётко проанализировать каждый этап, поэтому ради демонстрации я немного его увеличил.

Если вам любопытно, то вот пример в исходном масштабе.

Команды

Базовый конвейер GPU

Для начала ЦП передаёт геометрические данные (вершины) в GPU, заполняя его внутренний 64-байтный буфер FIFO командами (до трёх команд). По сути, команда сообщает, как и где отрисовывать один примитив.

После получения геометрии применяется усечение, чтобы предотвратить операции над невидимыми полигонами (находящимися за пределами окна видимости камеры).

Местоположение примитива задаётся в системе координат X/Y, указывающей на буфер кадров. GPU консоли PS1 использует целочисленную модель координат, в которой каждая координата соответствует центральной точке пикселя (называемой точкой сэмплирования). Иными словами, дробные координаты отсутствуют.

Проблема видимости

Для обеспечения нужной производительности эта игра использует предварительно упорядоченную геометрию, поэтому камера движется только вперёд или назад. Crash Bandicoot (1996 год)

Как и консоль-конкурент, PS1 не имеет никаких аппаратных функций, разрешающих проблему видимости. Тем не менее, GPU обрабатывает отсортированные полигоны, передавая таблицу упорядочивания: специальную таблицу, каждый элемент которой индексирован значением глубины (также называемым «Z-значением») и содержит адрес, где находится команда GPU.

Сначала ЦП должен вручную отсортировать полигоны, а затем ссылаться на них в нужном порядке в таблице. Далее ЦП приказывает DMA отправить таблицу в GPU. Этот процесс позволит GPU рендерить геометрию в правильном порядке.

Также есть множество функций DMA, помогающих ЦП и GPU в создании и обходе этой таблицы.

Растеризация

Отображение сцены в каркасном виде

После декодирования команд в GPU настаёт время преобразования полученной геометрии (вершин) в пиксели. Это позволит системе применить наложение текстур, эффектов и отобразить всё это на двухмерной панели (телевизоре или мониторе). Для этого GPU выделяет матрицу пикселей, используемую в качестве рабочей области. Она называется буфером кадров. В отличие от более сложной Sega Saturn, здесь GPU требует только один буфер кадров.

Для создания 3D-моделей GPU использует в качестве примитивов треугольники. Так как это единственный доступный примитив, фоны и передний план составляются одинаковым образом (и те, и другие состоят из треугольников). 2D-игры унаследовали ту же структуру: это просто два треугольника, объединённые в четырёхугольник (однако GPU имеет процедуры для автоматического построения спрайтов).

Растеризатор — это блок, занимающийся преобразованием векторов в треугольники, а затем в пиксели. Процесс выглядит так:

  1. Растеризатор получает каждую вершину из трёх точек и вычисляет её края. Так образуется треугольник.
  2. Анализирует площадь треугольника, чтобы определить, какие пиксели буфера кадров они занимают. Каждая часть треугольника, накладывающаяся на точку сэмплирования, превращается в пиксель.

Сгенерированные пиксели не записываются сразу в буфер кадров. Вместо этого они передаются на следующие этапы конвейера для дальнейшей обработки, которую мы рассмотрим в последующих разделах.

Шейдеры

Затенение по Гуро в действии

Для наложения эффектов освещения на эти полигоны GPU использует два алгоритма:

  • Плоское затенение: каждый примитив имеет постоянный уровень освещения.
  • Затенение по Гуро: вершина каждого примитива имеет собственный уровень освещения, а яркость между каждой из точек автоматически интерполируется.
    • Как можно представить, результат более реалистичен. С другой стороны, этот алгоритм нельзя использовать для спрайтов.

Причина наличия такого выбора заключается в том, что плоское затенение заполняет примерно в 2,5 раз больше полигонов, чем Гуро, поэтому необходимо оптимизировать, какие из полигонов требуют более реалистичного освещения, чем другие.

Текстуры

Наложенные текстуры

Далее затенённые поверхности смешиваются с текстурами (двухмерными битовыми картами), создавая окончательный результат.

GPU выполняет обратное наложение текстур, при котором он обходит каждый растеризованный пиксель и ищет соответствующий ему пиксель (называемый текселом) в текстурной карте. Текселы вычисляются линейной интерполяцией текстурной карты (находящейся во VRAM), чтобы соответствовать форме полигона. Используемая для интерполяции процедура называется аффинным наложением текстур (Affine Texture Mapping), эта методика оперирует только с 2D-координатами (значениями X/Y), отбрасывая третью координату (Z/глубину), используемую для перспективы.

Так как текстурные карты редко имеют точный размер растеризированного полигона, могут возникнуть искажения (неверные результаты). Они проявляются в виде нежелательных деформаций, например, отсутствующих или увеличенных текселов. Чтобы устранить эту проблему, сложные GPU применяют фильтрацию текстур, слаживающую (интерполирующую) резкие изменения цветов. GPU консоли PS1 не использует никакого фильтра, поэтому полагается на алгоритм под названием nearest neighbour («ближайший сосед»), исправляющий масштаб, но не сглаживающий результаты. Этот алгоритм очень быстр (и малозатратен), но из-за него текстурированные модели могут выглядеть «угловатыми».

Этот блок также содержит следующие эффекты, которые можно применять:

  • Полупрозрачность: имитирует освещение, проходящее через несколько текстур.
  • Дизеринг: сглаживает резкие изменения цвета с сохранением той же цветовой палитры.

Стоит упомянуть, что PS1 превосходно справлялась с этими эффектами!

Завершив все эти операции, GPU записывает пиксели в область буфера кадров во VRAM, которая, в свою очередь, считывается кодировщиком видео и передаётся на экран.

Модели

Давайте отдохнём от всей этой теории и рассмотрим примеры игровых персонажей, с нуля спроектированных для 3D-игр. [В оригинале статьи модели интерактивны.]

Каркасный вид

Поверхности

Текстурированный вид

Эксперименты с VRAM

Имея целый 1 мегабайт VRAM, можно выделить огромный буфер кадров размером 1024×512 пикселей с 16-битными цветами или реалистичный буфер размером 960×512 пикселей с 24-битными цветами, что позволит отрисовать самые красивые кадры для игры. Звучит впечатляющей, правда? Ну, на деле здесь возникает пара проблем, например:

  • Размеры этих буферов нужно будет уменьшить в соответствии со стандартным разрешением (например, 480 NTSC, 576 PAL), чтобы кодировщик видео мог транслировать их на домашний телевизор.
  • Как GPU сможет отрисовать что-нибудь красивое, если для остальных материалов не останется места (т. е. для текстур, таблиц цветов и т. п.)?
  • GPU консоли PS1 может отрисовывать буферы кадров размером до 640×480 пикселей с 16-битными цветами.

Ну ладно, пусть у нас будет 16-битный буфер размером 640×480, то есть на материалы остаётся 424 КБ VRAM. Вроде бы неплохо? Ну, такое разрешение подошло бы для ЭЛТ-мониторов, но было бы не особо заметным на стандартных телевизорах 90-х годов. Есть ли тогда какой-нибудь способ оптимизации буфера кадров? На сцене появляются настраиваемые буферы кадров.

Визуализация VRAM в отладчике NO$PSX. Вы можете увидеть двойные буферы кадров вместе с текстурами (можно преобразовать их при помощи таблицы поиска цветов).

По сути, вместо того, чтобы тратить ценную VRAM на «излишние» разрешения, GPU консоли позволяет уменьшать размер буфера кадров, чтобы увеличить объём, доступный другим ресурсам. В «Gears Episode 2» (см. раздел «Источники») Halkun демонстрирует схему, в которой буфер кадров 640×480 разделяется на два по 320×480, а затем применяется методика под названием page-flipping для рендеринга нескольких сцен одновременно.

Page-flipping заключается в переключении местоположения кадра для отображения между двумя доступными, когда это требуется игре. Это позволяет игре рендерить одну сцену, пока отображается другая. Благодаря этому исчезает эффект мерцания и снижается время загрузки (а это очень полезно для игрока!).

Суммарно схема Halkun занимает только 600 КБ VRAM. Остальное (424 КБ) можно использовать для хранения таблиц поиска цветов и текстур, что в сочетании с кэшем текстур на 2 КБ создаёт очень удобную и эффективную структуру.

Наконец, стоит упомянуть о том, что во VRAM одновременно можно использовать разную глубину цвета, то есть программисты могут выделить буфер кадров с 16-битными цветами (16 bpp) рядом с битовыми картами на 24 bpp (например, используемыми для кадров FMV ). Это ещё одна особенность, упрощающая дальнейшую оптимизацию использования пространства.

Секреты и ограничения

Хотя PS1 имела простую и удобную архитектуру, проблемы всё равно возникали. Как ни удивительно, но некоторые проблемы можно было решить хитрыми трюками!

Деформированные модели/текстуры

При движении текстуры немного колеблются. Final Fantasy VIII компании Square Soft (1999 год)

Процедуры, используемые для обработки геометрии и наложения текстур, имеют неточности.

Во-первых, растеризатор работает только с единичными пикселями: хотя координаты вершин являются целочисленными, вычисленные края треугольников могут занимать только часть пикселя. Однако растеризатор отрисовывает пиксель, если площадь треугольника покрывает точку сэмплирования пикселя, что не учитывает занятую часть пикселя. Это вызывает следующие проблемы:

  • Внешние края моделей даже при небольших перемещениях могут делать резкие скачки.
  • Входящие в меш треугольники (имеющие общие вершины и края) будут конфликтовать за возможность отрисовки в одном и том же пикселе. Пользуясь таблицей упорядочивания, GPU отрисовывает картинку по принципу «самый последний обрабатывается первым», что может привести к мерцанию или наложению пересечений треугольников при незначительных перемещениях.

Обычно эти проблемы решаются реализацией субпиксельного разрешения, из которого растеризатор отслеживает долю пикселей, занятую площадью каждого треугольника. Следовательно, далее можно использовать техники сглаживания, смягчающие изломанные края или резкую смену цвета.

Таблица упорядочивания перекладывает обязанность отображения геометрии в правильном порядке на разработчика/программу. В некоторых случаях для достижения нужной производительности реализуемые вычисления используют слишком много аппроксимаций. Это может привести к мерцанию или перекрытию поверхностей, которые должны были отображаться.

Кроме того, уменьшение разрешения буфера кадров может усугубить все эти проблемы с искажениями.

И, наконец, как мы знаем, аффинные преобразования не обладают знаниями о глубине, что может сбивать с толку восприятие игрока, когда камера находится рядом с моделью и расположена перпендикулярно к зрителю. Этот эффект также называется искажением текстур (texture warping). Для уменьшения искажений в некоторых играх используется тесселяция (разбиение большого полигона на несколько маленьких), в других текстуры заменяют на сплошные цвета. В общем случае, GPU решает эту проблему перспективной коррекцией, которая интерполирует текстуры при помощи значения глубины.

Противоречивые утверждения

При изучении технических каналов или форумов вы найдёте множество разных объяснений эффектов колебаний/искажений/деформаций на PS1. Некоторые из них совпадают с написанным мной, другие выглядят иначе, поэтому я выражу собственное мнение о том, почему следующие утверждения не являются точными:

Модели/текстуры колеблются из-за отсутствия FPU

FPU не определяет, может ли компьютер работать с дробными числам. PS1, как и любой другой компьютер без FPU, может выполнять вычисления с фиксированной запятой. Более того, при помощи программной эмуляции можно вычислять и числа с плавающей запятой (только медленнее). Подведём итог: FPU — это просто ускорители, не стоит путать их с ALU (важнейшей частью CPU, выполняющей арифметические вычисления) или с десятичными числами.

Модели/текстуры колеблются из-за целочисленной системы координат GPU

Использование целочисленных координат — распространённый способ снижения затратности вычислений в GPU. На самом деле, проблема становится визуальной из-за отсутствия субпиксельного разрешения. Подведём итог: сглаживание можно применять для смягчения резкой смены цветов, если растеризатор отслеживает долю пикселя, занятую треугольником.

Текстуры деформируются из-за отсутствия mip-текстурирования

GPU, реализующие обратное наложение текстур, подвержены погрешности измерений, называемой «undersampling» (один пиксель соотносится с несколькими текселами). Поэтому это создаёт искажения (ошибочные результаты). Такое поведение заметно при рендеринге далёкой от камеры геометрии. Чтобы устранить эту проблему, современные алгоритмы наложения текстур применяют «трилинейную фильтрацию», смягчающую текселы, использующие одну и ту же текстуру, хранящуюся с разным масштабами (mip-текстуры) и выполняет между ними интерполяцию. Подведём итог: mip-текстурирование — это методика устранения артефактов наложений. На PS1 проблема возникает из-за аффинного наложения текстур (и отсутствия перспективной коррекции), которое интерполирует текстуры на трёхточечных поверхностях, не учитывая глубину. Отсюда и эффект «деформации».

Модели/текстуры мерцают из-за отсутствия Z-буферизации

GPU с Z-буфером решает задачу определения видимых поверхностей на аппаратном уровне. В PS1 используется таблица упорядочивания, то есть определять, порядок расположения геометрии должны сами разработчики. Подведём итог: проблема мерцающих треугольников на любой модели вызвана процедурами сортировки (программными), поэтому устраняется тоже программно.

Заранее отрендеренная графика

Сцена с заранее отрендеренным фоном. Модели взаимодействуют и перемещаются так, чтобы обмануть восприятие игрока. Final Fantasy VII компании Square Soft (1997 год)

Ради разнообразия стоит упомянуть и «положительную» сторону…

Если игре нужна была более реалистичная графика, чем это мог позволить GPU, один из возможных вариантов заключался в том, чтобы использовать Motion Decoder для передачи на него заранее отрендеренных кадров. FMV-видео может занимать много места, но, к счастью, CD-ROM был к этому готов.

В некоторых играх эта особенность использовалась для создания фонов, и, честно говоря, на ЭЛТ-экранах они выглядели достаточно реалистично. Очевидно, что в современных эмуляторах с функциями увеличения масштаба такие фоны достаточно легко распознать.

Видеовыходы

В первой версии консоли есть удивительное количество видеосигналов:

  • RFU DC: от него избавились довольно быстро, он должен был подключаться к радиочастотному преобразователю видеосигнала (RF modulator).
  • RCA: обеспечивает композитный видеосигнал.
  • S-Video: обеспечивает Luma + Sync (совместно) и Chroma.
  • AV Multi Out: обеспечивает все перечисленные выше сигналы, за исключением RFU, плюс RGB и линию на 5+ В.

В последующих версиях консоли эти порты постепенно исчезали и в конечном итоге остался только «AV Multi Out».

Источники

Общая информация

Графика

 

Источник

Читайте также