Высадка на планету в 3D
3D-движок, опубликованный в прошлом но─
мере, существенно улучшен, и к нему сделан
совершенно фантастический (по меркам 8-
битных машин) пример! Предоставляем слово
автору этого примера - Dragons' Lord'у:
1. Исходный 3D Engine
Чтобы не запутаться во множестве моди─
фикаций движка, с некоторых пор я стал да─
вать условные цифровые значения версиям.
Моя классификация:
- 3D engine 0.01 - изначальный прототип
2016 года
- 3D engine 0.02 - введение кренов
- 3D engine 0.03 - исправлены некоторые
глюки переполнения
- 3D engine 0.04 - введены автоопределе─
ние мыши и прыжок
- 3D engine 0.05 - промежуточная "no─
interlace1к", как её назвал сам автор
- 3D engine 0.06 - "fixinterlace", заве─
ршена дописка режима "solid state screen"
без интерлейса
- 3D engine 0.07 - введена возможность
цветного видеовывода на компьютере АТМ
- 3D engine 0.08 - написана функция "pa─
norama 360°", печатающая растровую графику
на задник
- 3D engine 0.09 - добавлена окраска не─
ба, продолжающая рисунок панорамы.
Версией "3D engine 1.00" я буду считать
полностью 3-мерный вариант, подходящий для
реализации "Elite". Сейчас движок обсчиты─
вает пространство по упрощённым формулам,и
реализация полноценного 3D не представляе─
тся возможной. Текущая версия отлично под─
ходит для шутеров от первого лица и реали─
зации maze а-ля Wolfenstein 3D или Doom.
То есть 2-мерные уровни.Хотя имитация кре─
на и прыжки присутствуют.
2. Моя модификация
Отмечу, что модификации подвергалась
версия оригинального движка "3D engine
0.06", но потом результат был объединён с
версией 0.09. Крены для данной задачи вык─
лючены.
Во первых, нужно понять,зачем модифика─
ция вообще нужна.Исходный движок имеет ряд
моментов, путающих юзера.
Формат осей,используемых при проектиро─
вании самих объектов (вертексов): ось X -
от нас,ось Y - вправо,ось Z - вниз. Формат
пространства, в которое вы помещаете эти
объекты в основном модуле кода: ось X - на
нас, ось Y - влево, ось Z - вниз. Формат
пространства, в котором перемещается сам
персонаж (т. е. камера): ось X - от нас,
ось Y - вправо, ось Z - вверх. Как заметит
внимательный читатель,пространства не бью─
тся никак. И если инверсию первого логично
объяснить, так всегда бывает, что после
преобразования камеры объекты инвертируют
свои оси, то несовпадение последних двух
мерностей приводит к полной невозможности
программировать адекватные перемещения
объектов в мерности перемещений камеры. В
исходном движке этот момент не решён.
Второе серьёзное ограничение применимо─
сти движка заключается в размерностях его
сцены. Хотя для координат и используются
регистровые пары, т.е. 16 битные значения,
но движок способен адекватно обсчитывать
только мерность -1023...0...+1023 по всем
осям. Далее идёт повторение объектов сце─
ны. То есть если вы поставите столбик в
координаты 0,0,0 и побежите в любую сторо─
ну, то через 2048 внутренних единиц прост─
ранства вы снова прибежите к данному стол─
бику, но уже с другой стороны, и так мно─
гократно через каждые 2048. Причём ввиду
упрощёнки обсчёта положения объектов, о
которой я уже упоминал, вы уже не сможете
взаимодействовать с этим объектом адекват─
но - при любом повороте камеры объект бу─
дет хаотично скакать по сцене. Адекватная
работа с углами будет только в пределах
нулевого квадранта.
Модификация логики отображения объек─
тов в мерности сцены призвана решить обе
проблемы разом.
Как это сделано: в модуле управления
"script.asm" вывод рассчитанных значений
mcamx и mcamy перехватываются,и вывод идёт
не в них, а в новые ячейки памяти camX,
camY, оставляя mcamx и mcamy в нулях.Таким
образом, камера завешивается в нулевых ко─
ординатах мерности сцены и висит там всег─
да.Теперь если нажимать на кнопки - ничего
не будет происходить, мы никуда не бежим.
Логика отображения мира меняется на инвер─
сную: раньше объекты были неподвижны,а пе─
ремещали мы камеру, теперь камера неподви─
жна, и мы перемещаем вокруг неё весь мир.
Все объекты в основном коде имеют в начале
блока приращение на разницу между их "из─
начальными координатами" и мнимым положе─
нием камеры,т.е.координатами, размещаемыми
в camX, camY.
Всё, теперь и камера всегда в нулевом
квадранте, и оси перемещений объектов про─
инвертировались, войдя в синергию с теми
осями, которые показывает камера ( Z ось в
данном релизе не затрагивается, потому что
это не имеет смысла). Теперь можно объекты
адекватно перемещать динамически: если вы
дали приращение +100 по оси X, то именно
это и произойдёт визуально.
Также введён модификатор рэйнджа. Все
объекты предлагаемого уровня поделены на
условные конгломераты (пространство приме─
рно 128х128х128 внутренних единиц),у кото─
рых проверяется дальность от мнимой камеры
до координат ключевого объекта этого конг─
ломерата. Если дальность больше заданной -
конгломерат обходится по jp и не исполняе─
тся, а объекты конгломерата исчезают со
сцены.
Данный механизм (аналог стриминг конте─
йнеров,который несколько лет разрабатывали
разработчики "Star Citizen" и которым без─
условно гордятся) позволяет решить одно─
временно три проблемы.
Во-первых, рэйндж можно настраивать и
таким образом разгружать сцену под машину
с любыми тактами процессора. Меньше даль─
ность, меньше объектов в кадре, выше fps.
Настройка в самом начале модуля
"my_lunohod.asm" и выглядит так:
- dalnost=%11111111: 256 единиц простра─
нства - для машин с частотой процессора
3.5 МГц;
- dalnost=%11111110: 512 единиц простра─
нства - для режима турбо 7.0 МГц;
- dalnost=%11111100: 1024 единиц прост─
ранства - для режима Evolution 14 МГц, но
не рекомендуется к использованию,либо нуж─
но переключить range самого движка с 4 на
3 (дело в том,что максимально большой воз─
можный объект диаметром 64 исчезает визу─
ально с установленным range=4 примерно на
дистанции 1040, то есть его будет видно у
самой кромки горизонта как хаотично репи─
тующая копия).
Во-вторых, новый встроенный рэйндж поз─
воляет превозмочь главное ограничение ис─
ходного движка и набирать сцену из сколь
угодно большого количества объектов, кото─
рые размещаются в сцено-образующем коде
все одновременно (сейчас на сцене 200 не─
зависимых объектов).
И в-третих, что очевидно,вам становится
доступной для застройки и путеществий вся
16-битная мерность пространства по всем
осям. Причём без страха встретить повтор─
ное появление объектов из другого квадран─
та.Теперь вы можете строить город на карте
0..65535 размера. На экран выводятся ваши
координаты в формате XXXXX_YYYYY_ZZZZZ - и
вы можете наблюдать своё положение на кар─
те (можете отключить, 9000 тактов лишними
не будут).
3. Уровень
Когда основные технические моменты ре─
шены,можно перейти непосредственно к твор─
честву - к застройке. В качестве образца
для оценки возможностей движка я выбрал
модуль посадки на планету из игры "Elite
Dangerous". Строить будем руины стражей,
общий план застройки приведён на скрине
"elite_0_05_alpha_Исходные руины стражей
из игры Elite Dangerous.jpg". Застроил
только всю центральную часть - внешние
маленькие застройки по углам доделывать не
стал. Почему? Потому что совокупность фай─
лов уровня сейчас как раз в пределах одной
страницы памяти Спектрума, т. е. вмещается
в 16384 и может при необходимости успешно
храниться в банке верхней памяти 128K, как
один из уровней игры. Файлы моего уровня -
это конкретно:
"rotmodel.asm"
"3dmodel.asm"
"my_lunohod.asm"
Сейчас они размещаются в памяти следую─
щим образом:
> >>> ORG - start my level 33831
> ---------- rotmodel vertex --- size 6180
> ---------- model poly -------- size 881
> ---------- lunohod code ------ size 8416
> -----------RESULT (all my level): 15477
> >>> ORG - end my level 49308
Достроить уровень при необходимости,ко─
нечно,можно - для этого нужно убрать рису─
нок панорамы и задать в настройках движка
endfree=#10000, что даст 8K дополнительной
памяти в верхней странице.
Пару слов касательно формфактора реали─
зованных построек. В уровне присутствует
симуляция правильного освещения,хотя в ис─
ходном движке освещения нет. Все постройки
окрашены так, как будто свет падает с од─
ной стороны. Для этого пришлось хранить в
памяти копии некоторых осе-несимметричных
объектов с разной окраской. Это, конечно,
плохо. Память у Спектрума не резиновая.
Если убрать эти объекты и забить на свет,
высвободится примерно 1,5 .. 2 килобайта.
Но будет не так фотореалистично. Также,
кроме шейдеров вращения и синусоидального
перемещения динамических объектов на вра─
щающиеся объекты накинут шейдер,симулирую─
щий динамическое правильное освещение,а-ля
Flat. Делается подмена цветов на гранях (в
модуле POLY ) при определённых диапазонах
угла вращения объекта.
4. Выводы
Проект делался с целью получить компле─
ксное правдивое представление о:
- Какова будет скорость отрисовки сцены
а-ля "город". Можно отметить, что скорости
на машинах со стандартными тактами
(70000) действительно не хватает. Получен
результат на грани критического значения
min fps=8. И это в режиме интерлейса, т.е.
с черезстрочным выводом. Заключаем, что
демонстрируемый уровень - это максимально
возможная плотная застройка. Необходимо
увеличивать дистанцию между отдельными ко─
нгломератами (по сути "домами" на будущих
картах).Также на предложенном примере вид─
но, что в "близоруком" режиме с рэйнджем
256 затруднено ориентирование в пространс─
тве, особенно у человека, который никогда
ранее не видел этот уровень. Введение кар─
ты в любом виде, с обозначение игрока и
строений, - обязательное условие.
- Каково будет визуальное восприятие ра─
зличных объектов. Можно отметить одну, как
ни странно, но техническую проблему. Мак─
симально возможный размер одного элемента
= 64. Чтобы изобразить что-то фундамента─
льно большое, необходимо уменьшить "рост",
а по сути приращение по +z в файле
"script.asm" с дефолтного #020 до #010.
Тогда двухуровневые строения "с крышей"
воспринимаются максимально адекватно. Но
при этом обратной стороной медали, вступа─
ющей в противоречие с первой, является от─
рисовка плоской плитки под ногами, которой
кое-где рекомендуется мостить мостовую
(значительно облегчает ориентирование в
"сферическом вакууме"). Плитка не может
адекватно отрисовываться с высоты такого
малого роста из за фейковости отрисовки
объектов в движке,- плитку начинает бить
в неадекватных конвульсиях. Приходится вы─
бирать некий компромис, ухудшающий указан─
ные параметры на некоторое значение. А
увеличивать этажность застройки вы не мо─
жете, потому что не хватит быстродействия
для отрисовки столь многокомпонентных кон─
гломератов. Если вернуться к восприятию
объектов, то показано, что сложные много─
компонентные "дома" из нестандартных ароч─
ных конструкций уменьшеной толшины смотря─
тся отлично. В то же время отдельно стоя─
щие простые геометрические формы выглядят
отвратительно и не воспринимаются мозгом,
как некие "постройки". Даже в случаях, ко─
гда таких мелких отдельно стоящих объектов
много в кадре. При строительстве стоит
придерживаться правила "редко, но метко".
Мозг хочет, чтобы строение было с "кры─
шей", под которую можно зайти.
- Каковы будут размеры занимаемой памя─
ти. Память расходуется быстрее, чем ожида─
лось.Я уже описывал структуру уровня выше,
здесь можно отметить, что создание подоб─
ных уровней вполне возможно, если держать
свои хотелки в некоторых рамках. Демка по─
казывает строго статическую картину строе─
ний. Геймплея нет. Динамических объектов
(дронов стражей) нет. Взаимодействия с
объектами нет. Интерактивного изменения
построек нет. Процедурной генерации высо─
топеременной почвы и случайных RND объек─
тов вне зоны руин нет. Всё это планирова─
лось и может быть написано без проблем.
Нет этого по причине желания не засорять
код демо уровня. Для новичка необходимо
постепенное знакомство с 3d engine. Вот
чего наверняка не будет никогда - это фи─
зики. Я говорю о запрете игроку ходить
сквозь стены. Для уровня с произвольной
застройкой в рамках 3.5 МГц это нерешаемая
задача, и предлагается оставить, как есть.
Полагаясь на фантазию игрока. В проектах
аля "Вольфенштейн", с регулярной картой,
физика реализуется весьма просто.
5. Заключение
Я не нашёл предела количеству одновре─
менно отрисовываемым объектам, хотя прове─
рял где-то до количества 60 штук. Это оз─
начает, что у вас скорее fps устремится к
нулю,чем вы сможете навыводить кучу объек─
тов в попытках завесить систему.Это прият─
но. Никакой буфер не будет переполнен.Осо─
бенно это греет душу, когда вспоминаешь
ограничения в стандартной Спектрумской
"Elite" - не более 6 динамических объектов
одновременно + станция. Здесь же можно вы─
водить сколько угодно,если это вписывается
в выделенную память: 52016..52992(_tables)
free for object list 976 (один выводимый
объект занимает 16 байт).
По скорости отрисовки: если представить
стандартную "Elite" и взять нормальные вы─
пуклые объёмные объекты, то можно смело
отрисовывать 4 таких объекта в кадре одно─
временно ( ~60 полигонов). fps не упадёт
ниже 10 при любых приближениях. Это вполне
юзабельно. 5 объектов одновременно ( ~75
полигонов) - fps не упадёт ниже 8. Это
критически, но допустимо. Естественно, я
имею в виду режим интерлейса. Так что
"Элиту" с залитыми гранями реализовать те─
хнически возможно, если допилить расчёты
внутри движка до полноценного 3D.
Очень понравился выдеовывод. Скорость
заливки и вывода видеобуфера на экран за─
предельная. Это единственный движок,где вы
практически ничего не теряете, задавая об─
ласть отрисовки на весь экран Спектрума.
Отрисовка занимает лишь малую часть общего
времени расчётов. Максимально нагружает
систему обсчёт вертексов, поэтому примите
правило не плодить лишних вершин без кри─
тической на то необходимости.
Благодарю Alone Coder'а за великолепную
работу и надеюсь на полную 3D реализацию.
С уважением, Dragons' Lord.
Other articles: