05 июля 2015 |
|
Точка зрения Alone Coder Не совсем очевидно,но проекция простра─ нства на экран из одной точки ничего не говорит о расстояниях, сколько бы мы ни крутились-вертелись в разные стороны. Поэ─ тому такие проекции строить гораздо легче, чем настоящее 3D,и этим можно пользоваться и в играх ( Myst III: Exileи т.п.). * * * Рассмотрим простейший случай - пусть мы (камера) стоим в одной точке и крутим го─ ловой только в стороны. У нас всего одна степень свободы. Что мы видим? Мы видим то же самое, как если бы мы стояли в середине цилиндра с натянутой на нём текстурой. Или то же самое,как если бы мы стояли в середине куба. Или призмы. Это не имеет значения. Цилиндр проще всего в реализации,потому что он позволяет при любом угле поворота пересчитывать экранные координаты в коор─ динаты в текстуре простым лукапом по таб─ лице (это будет большая таблица - для каж─ дого пикселя). Он также позволяет и другой метод - при любом угле поворота используем одну и ту же таблицу, хранящую смещение в текстуре и масштаб для каждого столбца. (Столбы масштабируем как в Wolfenstein .) Этот второй метод отнимает значительно меньше памяти и реально применим. Сначала предполагалось использовать его для трёх─ мерного квеста Big L, но при его разработ─ ке встал ряд трудностей, и этот код вместе с графикой в конце концов попал в демо New Wave 48K. 48К - это достаточно сильное ограниче─ ние. Размер текстуры пришлось ограничить 512x128 (32 килобайта), потому что для ка─ ждого столбца (путём экспериментов были выбраны столбцы шириной 4 пикселя) надо иметь 4 разных сдвига в текстуре (чтобы иметь шаг в 2 пикселя). Пояснение про размер текстуры: суть в том, что руками сдвигать данные по горизо─ нтали медленно, поэтому надо хранить сдви─ нутые байты.Если сдвигать с шагом в 2 пик─ селя (а иначе как сохранить штриховку?),то будет 4 сдвига. Мы не храним 2 сдвинутых копии в одном байте (их было бы медленно вдвигать и накладывать), а только одну. Поэтому при ширине512 получается (512/8)* *4(сдвигов)*hgt байтов, что при hgt=128 даёт64*4*128=32768. Можно представить эту проекцию на рису─ нке (вид сверху): (где-то вдали - поверхность цилиндра) условный экран камера, она же центр цилиндра Формулы были такие: Для каждого n=-23.5..+23.5 с шагом 1 (это номер столбца) считаемx=n/24 (это номер столбца в пределах-1..+1 ) считаем уголa=arctg x (здесь угол зрения равен 90 градусов,иначе надо другие пределы дляx - лучше меньше,но тогда нужно большее разре─ шение текстуры по горизонтали); считаем масштабk=cos a (можно добавить коэффициент, если хотим сэкономить на вы─ соте текстуры или наоборот сделать тексту─ ру точнее); считаем координату столбца в текстуре xtex=a*128/pi (получается -32..+32 - для ширины 512 с шагом в 2 пикселя). Код использовался такой: ld d,h ld a,(de) exx xor (hl) and d ;#f0 xor (hl) ld (bc),a inc h inc b exx inc d ld a,(de) exx xor (hl) and d ;#f0 xor (hl) ld (bc),a inc b [ld a,c:add a,20:ld c,a...между знакомест] ex af,af' add a,e jr nc,$+3 inc h ex af,af' exx add hl,bc Такое рисование по 2 строчки приемлемо из-за небольшого разброса масштабов. Оно мало того что ускоряет отрисовку, оно ещё и позволяет меньше портить штриховки на картинке. Это был один из этапов борьбы за чисто─ ту картинки. Другой был связан с проблемой растягивания по горизонтали (из-за малень─ кого разрешения текстуры). Если оставить всё как есть, то вертикальные линии будут дублироваться. Чтобы частично скрыть этот дефект на имевшейся прорисованной картинке (от Surfin' Bird ), сдвинутые копии столб─ цов (те самые, которые шириной 4 пикселя) редактировались следующим образом: на левой границе столбца (смотрим полу─ байты попарно): 01?? -> 10?? 01?? -> 01?? на правой границе столбца: ??10 -> ??10 ??10 -> ??01 Можно сделать и наоборот (для других картинок). * * * Теперь выйдем в новое измерение и поду─ маем насчёт подъёма-опускания камеры.Здесь мы опять стоим перед выбором - на какую фигуру натянуть текстуру: цилиндр, куб или другой многогранник, сфера... И выбор тут гораздо труднее. Если мы возьмём многогранник,нам придё─ тся озаботиться насчёт настоящего ЗD-движ─ ка сtexture mapping (tmap), что сводит на нет выигрыш от неподвижной камеры (хотя... модель мира проще). Если цилиндр - то чем затыкать его кон─ цы? Если не затыкать,то нам нужна бесконе─ чная текстура.Или придётся ограничить углы подъёма-опускания камеры (зенит и надир сделать невидимыми). Если сфера - формулы пересчёта на каж─ дый пиксель просто ужасны. Можно рассчитывать только узлы сетки 8x8, а между ними проводить интерполяцию - упрощённый tmap. Этот метод проверен вре─ менем,и с ним можно использовать медленные способы расчёта, такие как: 1.Raymarching - сканирование воксельно─ го объёма с помощью маленьких шагов. Это уже было описано в статье"О летающем сло─ не" в Info Guide #10 (по поводу интры к #5 ). Это очень медленный метод. 2.Настоящий расчёт проекции цилиндра на экран. Для каждой точки считаем арктангенс и всё такое. 3.То же, что п. 2, но избавляемся от арктангенса, делая цилиндр квадратным. Насколько мне известно,такие мудрёности на Спектруме делал только SaiROOs в деме Dogma, и получилось весьма медленно даже для того разрешения. Код не смотрел,но ри─ сковать не стал. В Nedodemo я выбрал самый простой метод, и не зря - оказалось, что даже он едва-едва успевал на тогдашней компо-машине Pentagon 102ЧSL v2.2. Самый простой метод такой - для каждого угла подъёма камеры имеем свою таблицу. Отрисовку на экран производим непосредст─ венно по ней. Более того, генерируем из неё код (ld a,(hl):ld (de),a:inc d с нуж─ нымиinc/dec для h и l ). Проецировать мо─ жем на любую фигуру с осевой симметрией. Я выбрал сферу. Текстуры были рассчитаны на куб (сдела─ ны через ЗD-модель с 6 камерами), я перес─ читал их на сферу с помощью специально на─ писанной утилиты. Вы можете её найти в ис─ ходниках Nedodemo у меня на сайте. Казалось бы, забили 27 страниц памяти - куда так? Но если не генерировать код из таблицы, то можно заметить, что таблицы зеркально симметричны поX и попарно соот─ ветствуют друг другу поY (с отражением). Если бы стояла задача загнать этот эффект в128К, она была бы выполнена. А вот в 48К - нет.48К мир существенно отличается от мира расширенной памяти. Другой вопрос, что делать,чтобы поднять разрешение этого эффекта до приемлемого в играх. К сожалению, ответа пока нет. Что однозначно - текстура должна иметь разре─ шение, превышающее размер экрана не менее чем в 4 раза. В Nedodemo разрешение текс─ туры 256x64 (она немного сплющена по вер─ тикали) при разрешении экрана56x61, и те─ ксели при этом видны. То есть, например, для разрешения экрана256x128 понадобится сферическая текстура порядка1024x256 или куб с текстурами256x256.
Other articles:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Similar articles:
В этот день... 21 November