SineDots




Впервые я увидел подобный эффект на демо DeesertDream/Kefrens и был очарован красотой, я всегда пытался понять, как это работает?


Позже я узнал о происхождении эффекта, алгоритм оказался неприменим к ZX Spectrum.

Другая вариация точек используется часто, я использовал другой вариант в Prepare, it will be loud и потом в других демо.

На создание давнего эффекта меня толкнул спор на чятике #Z80 «Какое построение точек быстрее?». К тому же примененный мной алгоритм удаления нарисованных точек меня не устроил. Поэтому я решился поэкспериментировать с возникшей идеей.

Рассуждения были простыми: строится 256 точек, достаточно 512 байт для хранения адресов.
После синхронизации старые точки стираются, затем рисуются заново.

Стираются так:

; SP указывает на старую таблицу адресов точек,A=0
pop hl
ld (hl),a
..
pop hl
ld (hl),a; действия повторяются 256 раз


Рисование новых точек:

;SP=указатель на новые адреса
pop hl
set N,(hl)
.. те же действия 256 раз.
pop hl
set N,(hl)


Гм… спросит читатель… А в чем соль?
Нет никакой соли, координаты точек можно рассчитывать и модифицировать процедуру на ходу.

Для построения точек задействована следующая таблица:
$8000: таблица синуса
#8100: код операции set N,(hl) для построения точки (координата Х)
#8200: X/8 для адресов
$8300: мл. байт адреса Y-координата
$8400: ст. байт адреса Y-координата

Все задуманное и описанное звучит легко и гладко, но на практике вышло совсем не так — после подготовки таблицы для построения точек тест отработал, но рисовалось не пойми что. Мне понадобился час, чтобы понять, в чем причина.

Теперь еще один шаг: таблица адресов расположена по адресу #8000, занимает 512 байт. Для следующего кадра отводится адреса $8400-$8600, нужно подумать и поменять необходимые адреса. С этой задачей я справился.

Сам по себе эффект никакой, я добавил интерактив: клавиши QWER/ASDF меняют параметры, 0 — сбрасывает значения по дефолту. Можно было бы расширить вариации, поменяв начальные значения.

Теперь загляну на время исполнения в Unreal:

Есть ли резерв? Наверное да, если поразмыслить над алгоритмом и поэкспериментировать, или развернуть цикл процедуры.

Сюда было бы неплохо добавить музычку, хватит ли времени? Я поступил старым индейским способом: выгрузил .PSG и приклеил еле вместившуюся в память музыку к программе.

Жизнь — боль, разработка боль тоже — музыка не играет! Причина найдена быстро: часть .PSG дампа занята непонятной таблицей. Устранено, заиграло. На упаковку дамп меня не хватило.

Скачать программу +исходники.

А как же это работает? в архиве есть программы для Windows с исходниками PureBasic, которые помогут разобраться. Trail — тот вариант, который был смоделирован для 256б.

Все, похвастался, показал, осталось остановиться на одном нюансе — о построении таблиц. Я вписал точки в область размером 192х192, при желании можно сделать полноэкранный эффект.


Посмотрите на график синуса, значения изменяются от -1 до 1. Мне необходимы значения 0-192, поэтому считается так:


For i=0 To 255
  a.a=Int( 48+47*Sin(i*#PI/128) )
Next i

получается, что значения в таблице могут меняться от 0 до 96. сумма синусов даст значения 0-192, этого достаточно.
Для другой координаты можно применить подобные рассуждения и построив еще одну таблицу. Конструктор есть у вас, желаю удачи.

12 комментариев

avatar
Похожий эффект есть в «Insult» от Codebusters. Не такой же как в DesertDream/Kefrens, но похожий.
Оригинальный эффект, скорее всего, построен на том что точки просто колеблются по sin-подобным таблицам по одной оси. Более там ничего нет. Но возникает иллюзия что эта фигура вращается. Эффект я считаю супер, так как этот не просто программирование, а реальный обман =)

Таблицы представляют собой не чистый sin, но более сложную функцию, ее начало и конец замкнуты неразрывно в цикл. Каждый переход к соседней точке образован во-первых смещением по экрану, а во-вторых шагом индекса в таблицах, так что на экране фигура получается неразрывной.
Возникает иллюзия вращения или сложного движения, но на деле это всего лишь смещение точек по одной оси.
На Amiga точки колышутся по таблицам, кажется, по x, в insult явно по y.

В insult точек ставится больше за счет того что впереди по индексу таблицы одна точка ставится по set n, (ix+nn), сзади стирается по res n, (ix+nn) при этом между ними есть промежуток в несколько выставленных на экран точек, он визуально формирует фигуру.

Ну вот и всё Шыни! Спасибо за статью, это было увлекательно.
avatar
у Insult была другая таблица.
avatar
Raider, спасибо за комментарий! Тебе бы статьи писать об эффектах, настолько ёмко и информативно ты описал эффект, плюс еще и проанализировал реализации на спектруме и Амиге! Я за такие статьи, когда с пониманием, по сути и без воды. Сразу захотелось пересмотреть демы и поискать похожие эффекты, а может быть даже и придумать новые вариации.
avatar
diver4d, постараюсь быть полезным. На деле я только «вылез» после долгих лет паузы с программированием эффектов.
avatar
Ты знаешь, мне кажется, что ты немного усложнил. Представь себе, что у нас есть 3D фигура из точек (неважно, как мы её получили), и мы хотим её вращать. Если вращение как у Kefrens, вокруг вертикальной оси, выходит что координата Y y каждой точки постоянна. Координата Z ни на что не влияет (там явно нет перспективы), так что остаётся только координата X. Но если задать каждую точку в плоскости (X,Z) в полярной системе координат, то выходит что точка задаётся радиусом до оси вращения R, плюс углом beta. Координата X каждой точки — просто R*cos(beta). Меняем угол у каждой точки с постоянным шагом — получаем вращение всей целиком фигуры.

Т.е., я о чём, там не иллюзия вращения, там вполне себе честное вращение.

А вот в Insult там какая-то каша. Видимо там таблица как-то не вполне следует описанному выше алгоритму. Это и даёт более сложное движение. Сделать сдвиг по фазе чтобы линии стали толстыми, как в Insult, в алгоритме Kefrens можно, а вот как сделать наоборот мне, если честно, непонятно.
avatar
Фантазер) Работает алгоритм примерно вот так:
rgho.st/7W7W4gjdG
avatar
introspec
Почти во всем соглашусь с тобой. Ты всё верно пишешь, только лишь в терминологии более сложной. Твое выражение:
Меняем угол у каждой точки с постоянным шагом — получаем вращение всей целиком фигуры.

Это и есть сдвиг по индексу sin-таблицы. Также с тобой можно согласиться, что движение по sin-таблице это и есть, фактически, поворот в полярной системе координат.
Выше мои слова «иллюзия что вращается» относились не к конкретной точке, а ко всей фигуре. Но если быть математически точным, как ты того и хочешь, то наверное нельзя не согласиться, что если вращается каждая точка, то вращается и вся фигура. Я лишь попытался перейти на необходимый для кодерского понимания еще более высокий уровень абстракции, написав что «ничего кроме того что точки движутся вверх-вниз» там нет. По x точки «прибиты» на местах.

Есть там еще один аспект, на который нужно еще раз сделать акцент: точки живут в этом эффекте не «каждая сама по себе». Каждая следующая точка — в аккурат ставится по следующему индексу sin-таблицы, образуя тем самым непрерывную фигуру. Это легко понять из того, что все точки ставятся через
pop ix
set n, (ix+dd)
pop ix
set n, (ix+dd)
pop ix
set n, (ix+dd)

На что тут надо обратить внимание. На то что в sin-таблице мы идем непрерывно приращивая как бы «индекс» в sin-таблице pop ix...pop ix...pop ix...pop ix… и это важный момент в этом эффекте. Почему я и пишу что каждая точка не живет сама по себе, все они представляют собой непрерывную «вереницу» выборки из таблицы.
avatar
Raider, с чем связан выбор регистра ix в данном случае?
с «горизонтальной» мобильностью?
avatar
Быстрее же.
avatar
в смещении +dd и в команде (номер бита n) намертво зашита x-координата точки.
ну а то что стеком достается — это y-координата.

по x все точки намертво «прибиты». они смещаются только по y.
avatar
Случайно наткнулся на нечто аналогичное. VIRTUAL DREAMS 1992 ABSOLUTE INEBRIATION (A500) на 8 min 53 sec
avatar
Ждем еще фантазий по поводу природы эффекта(:
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.