Энтузиаст написал 3D-рендерер с нуля для консоли Playdate с 1-битным экраном

Энтузиаст написал 3D-рендерер с нуля для консоли Playdate с 1-битным экраном

Автор девлога на itch.io описал, как создавал программный 3D-движок для игровой консоли Playdate, маленького портативного устройства с 1-битным (чёрно-белым, без градаций серого) экраном и без выделенного графического процессора: вся геометрия, проекция, отсечение и растеризация считаются на CPU. Начал он с теста-рейкастера на основе старого кода Кена Сильвермана, чтобы оценить производительность устройства по числам с плавающей точкой, векторной математике и записи в буфер кадра. Первые результаты оказались хуже ожидаемых: по мощности Playdate уступает ранним 3D-ускорителям вроде 3dfx Voodoo и оригинальной PlayStation, но автор решил, что по ощущениям от картинки можно приблизиться к эпохе консолей 3DO и Sega Saturn.

Для карт уровней он взял формат BSP (binary space partitioning) из Quake: это позволило использовать готовые инструменты редактирования и компиляции уровней, редактор TrenchBroom и утилиты ericw-tools, вместо написания своих. BSP заранее разбивает пространство уровня на выпуклые ячейки и просчитывает потенциально видимые множества (PVS) для каждой из них, поэтому во время игры рендерер отбрасывает большую часть невидимой геометрии ещё до растеризации. Плата за это, уровни должны быть статичными и спроектированы с учётом видимости: например, прямой коридор между двумя большими комнатами показывает слишком много геометрии сразу, а Г-образный коридор перекрывает линию обзора и даёт PVS больше возможностей отсечь лишнее.

После экспериментов без z-буфера (классический алгоритм художника, отрисовка от дальнего к ближнему), который не дал прироста производительности, автор добавил 16-битный z-буфер с обратной (реципрокной) глубиной: он даёт больше точности рядом с камерой, где ошибки глубины заметнее всего, и работает лучше, чем опробованный ранее 8-битный вариант. Тот же буфер упростил отрисовку динамических объектов и текстур с прозрачностью (двери, решётки, вода, спрайты).

Для текстур автор выбрал перспективно-корректное наложение вместо более дешёвого аффинного (которое искажает текстуры на неплоских поверхностях, как в оригинальной PlayStation): рендерер интерполирует 1/z, u/z и v/z и восстанавливает координаты текстуры делением на каждый пиксель. Поскольку деление дорого для процессора Playdate, точное значение пересчитывается не на каждом пикселе, а раз в несколько пикселей, а между ними используется быстрая аппроксимация, визуально разница незаметна, а скорость выигрывает заметно.

Освещение на экране без цвета и градаций серого автор реализовал через дизеринг: предрасчитанные карты освещения из формата Quake BSP конвертируются в вершинное освещение, а яркость каждого пикселя сравнивается с порогом из матрицы Байера 8×8, если яркость выше порога, пиксель становится белым, иначе чёрным. На расстоянии и в движении глаз воспринимает такой узор как оттенки серого. Полностью текстурированная и освещённая сцена при этом легко превращается в визуальный шум, поэтому автор ориентировался на визуальный стиль игр Return of the Obra Dinn и Jet Set Radio, с выраженными контурами, простыми текстурами и подходом в духе 1-битного cel-shading.

Ключевые факты

  • Автор пишет с нуля программный 3D-рендерер для консоли Playdate, устройства без GPU и с 1-битным (чёрно-белым) экраном, вся отрисовка идёт на CPU
  • Карты уровней берутся из формата Quake BSP (редактор TrenchBroom, компилятор ericw-tools), это даёт готовое разбиение пространства и расчёт видимости (PVS), но требует статичных уровней
  • Добавлен 16-битный z-буфер с обратной глубиной вместо алгоритма художника, упростил отрисовку прозрачных текстур и динамических объектов
  • Для текстур используется перспективно-корректное наложение с аппроксимацией деления через пиксель ради производительности на слабом CPU
  • Освещение на чёрно-белом экране реализовано через дизеринг матрицей Байера 8×8; визуальный стиль ориентирован на Return of the Obra Dinn и Jet Set Radio

Почему это важно

Материал показывает, как классические техники 3D-графики конца 1990-х, BSP-карты, z-буфер, перспективно-корректные текстуры, дизеринг вместо цвета, переносятся на современное маломощное устройство без графического ускорителя. Это наглядная демонстрация инженерных компромиссов, которые приходится делать при разработке 3D-графики без GPU, актуальная для игровой инди-разработки и ретро-программирования.

Кому это важно

Материал интересен инди-разработчикам игр, владельцам консоли Playdate, программистам, занимающимся софтверным (без GPU) рендерингом, и энтузиастам ретро-графики, которые изучают, как устроены классические 3D-движки вроде Quake.

Как это применить

Автор описывает конкретный набор приёмов: использовать готовый формат карт Quake BSP и инструменты TrenchBroom/ericw-tools вместо своего редактора уровней; проектировать коридоры Г-образными для лучшего отсечения невидимой геометрии; применять 16-битный z-буфер с обратной глубиной вместо алгоритма художника; экономить на делении при перспективно-корректном текстурировании, пересчитывая точное значение раз в несколько пикселей; заменять цвет и градации серого дизерингом по матрице Байера на 1-битном экране.

Можно ли доверять

Это личный отчёт разработчика о собственном проекте, опубликованный им самим в девлоге на itch.io; технические детали (форматы, алгоритмы, конкретные параметры вроде 16-битного буфера и матрицы 8×8) изложены последовательно и проверяемы по описанию, но независимого подтверждения результатов (скриншотов производительности, замеров FPS) в тексте нет, материал стоит читать как рассказ автора о своём опыте, а не как независимо проверенный бенчмарк.

Риски и подводные камни

Подход завязан на статичные уровни: BSP с предрасчитанной видимостью плохо подходит для динамически меняющихся сцен. Перспективно-корректное текстурирование требует деления на пиксель, что дорого для слабого процессора Playdate, поэтому точность приносится в жертву скорости через аппроксимацию. Дизеринг на 1-битном экране легко превращается в визуальный шум при насыщенной сцене, из-за чего автору пришлось намеренно упрощать текстуры и освещение ради читаемости картинки.

«Даже ZX Spectrum может рисовать 3D, если дать ему достаточно времени. Настоящий вопрос, сможет ли устройство делать это достаточно быстро, чтобы в это можно было играть в реальном времени.»

— автор девлога о проекте на itch.io