Newton & Nostalgina
Newton Newton
Я тут вот размышлял, как они вообще на тех первых консолях движение реализовали, с таким железом. Может, вместе попробуем разобраться, какая математика за этим стояла? Как они эти пиксельные миры такими реалистичными сделали?
Nostalgina Nostalgina
Слушай, эти старые системы вообще не делали сложной физики. Они работали на паре уловок, которые умещались в несколько сотен байт кода. Сначала картинка строилась строка за строкой, и электронный луч телевизора двигался вниз по экрану построчно. Консоль могла изменять горизонтальное и вертикальное положение спрайта для каждой строки, создавая иллюзию плавного движения, хотя процессор просто посылал несколько новых координат. Потом был ещё так называемый трюк с "масштабированием спрайтов". Аппаратное обеспечение повторяло один пиксельный блок по множеству пикселей, создавая низкокачественный квадрат, который мог увеличиваться или уменьшаться в размере просто меняя количество повторений. Это создавало иллюзию объекта, удаляющегося или приближающегося к зрителю. Вся математика была целой, без долей и чисел с плавающей точкой – только умножение на степени двойки или на размер блока. Параллакс-скроллинг был ещё одним важным приемом: слои фона двигались с разной скоростью. Поскольку телевизор отрисовывал экран построчно, консоль могла заставлять фон "прыгать" на несколько пикселей каждый кадр, а передний план двигался быстрее, создавая ощущение глубины. В итоге всё сводилось к умелому использованию пропускной способности памяти, сдвигам битов и обновлениям построчно. Никакой настоящей физики, только математика, которая идеально синхронизировалась с оборудованием дисплея. Это такая элегантная, сделанная вручную конструкция, которая ощущается более удовлетворительной, чем сегодняшние GPU-растеризаторы.
Newton Newton
Это невероятно интересный пример того, как ограничения могут подтолкнуть к креативу. Я бы с удовольствием посмотрел на этот трюк со сдвигом битов, который ты упомянул – сколько бит использовалось для управления этой горизонтальной масштабировкой, и менялось ли это в разных системах?
Nostalgina Nostalgina
Конечно. В принципе, все сводилось к повторению блока пикселей определенное количество раз, и это количество хранилось в небольшом битовом поле. В Atari 2600 регистр горизонтального размера спрайта был всего 4 бита, поэтому можно было выбрать масштаб от 1 до 16 пикселей. Поэтому спрайты выглядят такими блочными – все решение о масштабировании сводилось к одному 4-битному значению, которое аппаратная часть просто умножала на исходную ширину пикселя. В NES сделали нечто похожее, но дали немного больше свободы: регистр размера спрайта был 5 бит, поэтому можно было масштабировать горизонтально от 1 до 32 пикселя. Этот дополнительный бит позволил разработчикам добавить немного больше "плавности" в персонажей, хотя по-прежнему ты получаешь только целые значения ширины пикселя, без подпиксельного перемещения. В других ранних системах, таких как Commodore 64 или MSX, были свои собственные крошечные поля – обычно 3 или 4 бита для горизонтального масштабирования и 2 бита для вертикального. Это варьировалось, но общее правило было таким: каждый бит удваивал количество повторений пикселей, поэтому математика оставалась простой для процессора. Именно такая простота позволяла этим старым консолям поддерживать низкую пропускную способность памяти и освобождать процессор для других задач.
Newton Newton
Вот наглядный пример того, как один бит может определять чёткость картинки – простой множитель, который при этом процессор не напрягает. Заставляет задуматься, используют ли современные движки для пиксельной графики всё ещё целочисленное масштабирование ради того же ощущения чистоты и эффективности.
Nostalgina Nostalgina
Слышала, многих инди-разработчиков до сих пор привлекает эта четкость и пиксельность. Даже в Unity или Godot можно включить камеру с идеальной точностью пикселей, и в большинстве этих движков можно установить масштаб целым числом, чтобы пиксели оставались резкими. Некоторые новые фреймворки даже фиксируют разрешение целевого рендеринга, а потом просто увеличивают изображение с использованием фильтрации ближайшего соседа. Это по сути тот же прием с целыми числами, только обернутый в более удобный API. Если хочешь добиться этой ретро-атмосферы, просто убедись, что разрешение – это кратное размеру твоих спрайтов, и все будет отлично.
Newton Newton
Звучит как неплохой ход – просто заблокируй целевой рендер и увеличивай кратно целому числу пикселей. Так и детали останутся чёткими, а вычисления будут простые. Попробую поэкспериментировать с этим, посмотрю, смогу ли добиться такого же ощущения старины, не потеряв при этом производительность.
Nostalgina Nostalgina
Похоже, ты двигаешься в верном направлении. Только не забудь, чтобы коэффициент масштабирования был целым числом, иначе получишь неприятные артефакты. Если что-то пойдёт не так, просто дай знать. Помогу разобраться с любым глюком.
Newton Newton
Спасибо, буду использовать целые пиксели. Если что-то странное с прорисовкой вылезет, дам знать.
Nostalgina Nostalgina
Рада, что всё у тебя в порядке! Пиши, если что-то покажется странным – лучше не найти, чем потом жалеть. Удачи с поиском пикселей!
Newton Newton
Я ценю предложение – если тест на линии покажет что-то неожиданное, обязательно проверю выравнивание и масштабирование. Спасибо, что предупредил.
Nostalgina Nostalgina
Отлично, помни только старое правило: следи за тем, чтобы всё выравнивалось по целым пикселям, и линии сканирования совпадут идеально. Расскажи потом, как получилось!