PDA

Просмотр полной версии : "Новый" алгоритм быстрой 3D графики



Destr
18.02.2014, 18:41
Он описан в zx-power.
Тут (http://zxpress.ru/article.php?id=8042) и дополнения (http://zxpress.ru/article.php?id=8105).
В дополнениях написано что "способ очень похож на предложенный в SPECTRUM EXPERT#2 метод средней точки (http://zxpress.ru/article.php?id=11766)".
Я пытался с этим всем разобратся, но почти ничего не понял (ибо описано всё очень сумбурно и нет полных исходников).
Пробовал-ли кто-нибудь ковырять всё это дело?
Или может кто сумеет разъяснить суть?
Или есть желающие вместе разобратся?

denpopov
18.02.2014, 19:00
в 3D Lame быстрая графика вроде бы:
http://opensourcezx.untergrund.net/b_demo-3d_lame_src.html

все, что разобрался, там закраска треугольников и поворот фигур.

Titus
18.02.2014, 20:14
Он описан в zx-power.
Тут (http://zxpress.ru/article.php?id=8042) и дополнения (http://zxpress.ru/article.php?id=8105).
В дополнениях написано что "способ очень похож на предложенный в SPECTRUM EXPERT#2 метод средней точки (http://zxpress.ru/article.php?id=11766)".
Я пытался с этим всем разобратся, но почти ничего не понял (ибо описано всё очень сумбурно и нет полных исходников).
Пробовал-ли кто-нибудь ковырять всё это дело?
Или может кто сумеет разъяснить суть?
Или есть желающие вместе разобратся?

Бегло посмотрел. Это два не одинаковых способа, но похожих.

1) На каждой оси X, Y, Z по 64 зарубки (опорные точки). Оси поворачиваются, вычисляются новые координаты всех опорных точек, и уже по опорным точкам легко найти x,y-координаты точки на экране (простая геометрия). Вертеть такую систему лего - просчитал только 3 точки вершин координатных осей (или 4, если нулевая точка тоже вертится, а не стоит на месте), потом простой интеполяцией находятся по 64 опорные точки на каждой оси. Т.е. математика с умножениями нужна только для 3-х или 4-х точек.

2) Почти тоже самое, вычисляются координаты вершин искомого куба, представляющего из себя оси координат, а потом простой геометрией внутри находятся координаты нужных точек. Разница в том, что приходится делать больше вычислений, если точки расположены не в 'простых' местах куба, которые можно получить деля стороны на 2, 4 и т.д. Т.е. простыми действиями. Нарисовать сферу или подобный обьект будет вряд ли быстрее, чем считать все точки по-честному.
Первым способом это будет сделать намного быстрее, но при 64 опорных точках в системе координат, сфера будет угловатенькая. Но будет)

Destr
18.02.2014, 22:35
Titus, ну ты вообще ничего нового не сказал!
Это всё изложено в статьях, а всё равно непонятно (расплывчато).
Ну примерно как на вопрос от какого-нибудь инопланетянина к любому человеку:
- Объясните, как Вы дышите?
Ты ответил как-бы:
- Ну вдыхаю и выдыхаю, и всё!
Вместо конкретного ответа:
- Осцилляторная связка головного мозга даёт сигналы центру распределения импульсов которая в свою очередь отправляет синапсные сигналы мышцам диафрагмы, растягивающие и сжимающие лёгочные полости.

Ответ этот тоже не абсолютно точен, но больше приближён к пониманию процесса.

P.S. За внимание и ответ - благодарен, конечно, но уж если не трудно разъясни попонятней.
Ну для деревенщины уж постарайся, браза!


простой интеполяцией
Само слово "интерполяция" ввергает в ужас (ибо ещё никто не смог мне доступно объяснить что это за зверь), а уж приставка "простая" - вообще убивает (ведь получается есть и "непростая"!!!).
Мрак.

Titus
18.02.2014, 23:09
Само слово "интерполяция" ввергает в ужас (ибо ещё никто не смог мне доступно объяснить что это за зверь), а уж приставка "простая" - вообще убивает (ведь получается есть и "непростая"!!!).
Мрак.

Тогда спроси поточнее, чего тебе не понятно)

На счет интерполяции.

Приведу пример на одномерной системе координат.

Алгоритм очень похож на алгоритм рисования линии.

Вот у тебя есть две крайние точки оси с координатами 20 и 209 соответственно.

Тебе надо надо найти 64 точки (что равно 63 интервалам), равномерно лежащие на этой оси. Как ты это будешь делать?

Вычисляем сперва длину оси. 209 - 20 = 189. Это длина оси. Теперь эту ось надо разделить на 63 отрезка.

Примерно это будет так:
Начинаем размечать точки с координаты 20. Заносим ее координату в X[0]
20: 189 - 63 = 126. Есть перенос? Нет, значит, идем далее
21: 126 - 63 = 63. Есть перенос? Нет, значит, идем далее
22: 63 - 63 = 0. Есть перенос? Нет, значит идем далее
23: 0 - 63 = -63. Есть перенос? Да, значит прибавляем 189 (-63 + 189 = 126) и заносим координату 23 в X[1]
24: 126 - 63 = 63. Есть перенос? Нет, значит, идем далее
25: 63 - 63 = 0. Есть перенос? Нет, значит идем далее
26: 0 - 63 = -63. Есть перенос? Да, значит прибавляем 189 (-63 + 189 = 126) и заносим координату 26 в X[2]
и т.д.

Таким образом ты расставишь координаты всех 64 точек лежащих на заданной оси. Быстро и сердито.

Для трехмерной системы координат надо расставить не три набора точек x, y и z для каждой из 3-х осей.

Destr
18.02.2014, 23:20
Titus, спасибо дружище!
Так уже гораздо ясней!
То-же самое на днях описывал неварту (только не знал что это и есть интерполяция).

А теперь вопрос по сабжу: в "дополнениях" сказано: "Проблему перспективы проще всего решить перспективно спроектиравав 3D систему координат."

Как???

P.S. Не, ну я понимаю как повернуть любую точку и спроецировать её.
(умножения на поворот по всем трём осям + умножения и деления на проекцию, но чтоб всю плоскость да за малотактов - это что-то нереально. а ведь автор грит что как об асфальт)

P.S.S. А, да, забыл: Пока всё это в пределах экрана (-127...+127) - это ещё куда ни шло. А ежели +-12 бит?
Получится ли такой финт или опять мне приснилось что в сказку попал?

Titus
18.02.2014, 23:33
А теперь вопрос по сабжу: в "дополнениях" сказано: "Проблему перспективы проще всего решить перспективно спроектиравав 3D систему координат."

P.S.S. А, да, забыл: Пока всё это в пределах экрана (-127...+127) - это ещё куда ни шло. А ежели +-12 бит?
Получится ли такой финт или опять мне приснилось что в сказку попал?

Где написано про перспективную систему 3д координат? Я бегло читал, не заметил.

Не знаю, как можно это сделать, ведь в перспективе частота следования точек по оси уменьшается приближаясь к нулю координатной системы.

да хоть сколько бит, но придется применять 16-битную арифметику, а это уже гораздо медленнее) Это только если для игры, для демки обычно бывает не нужно.
Кроме того, где 16 бит, там обычно 64 точками не обойдешься. Зачем 16 бит, если само поле 64x64x64?

Destr
19.02.2014, 00:04
Где написано про перспективную систему 3д координат? Я бегло читал, не заметил.
Я ведь процитировал.
Собственно это последний абзац из "дополнений"


Это только если для игры
Для игры (демок я не мастак да и не любитель)


Зачем 16 бит, если само поле 64x64x64?
Я не ограничивал поле 64, это в статье оно так заточено.
Конечная цель - развернуть алгоритм так чтоб было актуально больше 64 точек (ну хотя-бы бит 12, для круглости)

Titus
19.02.2014, 00:54
Я не ограничивал поле 64, это в статье оно так заточено.
Конечная цель - развернуть алгоритм так чтоб было актуально больше 64 точек (ну хотя-бы бит 12, для круглости)

Тогда подобный аглоритм скорее не подойдет.
Очень огромные получатся оси (с большим числом опорных точек), будет контр-продуктивно таким методом считать.

Destr
19.02.2014, 09:45
Тогда подобный аглоритм скорее не подойдет.
Очень огромные получатся оси (с большим числом опорных точек), будет контр-продуктивно таким методом считать.
Я в общем-то об этом думал.
Но вспомнил одну фразу алонкодера (из текста где он описывал свой вольф-движок) в которой признался что по честнаку считать долго и поэтому лучи трассируются через один, а пропущеные интерполируются.
У меня мелькнула мысль не получится ли что-либо подобное провернуть и с этим алгоритмом.
Или вообще - может быть можно что-то сделать с поворотами/проекциями без всяких умножений.
Ну например - таблицами (даже гигантскими - по сути в zx128 можно смело пожертвовать под это дело пару-другую страниц).
Вот только как к этому подступится - пока слабо представляю.

Titus
19.02.2014, 13:35
Тогда надо спрашивать у Алоны, может у него есть решение.

Памяти у Спектрума на таблицы очень мало. Добавил лишний бит к разрядности, таблицы выросли вдвое. Добавил еще бит, уже вчетверо.

alone
19.02.2014, 14:10
Я использовал две вращалки - от JtN (куда я добавил правильное округление) и описанный алгоритм с 64 засечками. Второй вариант быстрее и меньше кушает, точность примерно одинаковая. Оба варианта есть в исходниках The Board, переключаются флажком.

Titus
19.02.2014, 14:22
Я использовал две вращалки - от JtN (куда я добавил правильное округление) и описанный алгоритм с 64 засечками. Второй вариант быстрее и меньше кушает, точность примерно одинаковая. Оба варианта есть в исходниках The Board, переключаются флажком.

Не все знают, что такое JtN)
Что за правильное округление?

---------- Post added at 14:22 ---------- Previous post was at 14:20 ----------

Если ты использовал вариант с 64 засечками, значит у тебя карта весьма мала.

Destr
19.02.2014, 19:21
Не все знают, что такое JtN)
Я тоже искал - ничего не нашел.
Что это за зверь интересно?
alone, колись, не томи :)

nyuk
19.02.2014, 19:43
Я тоже искал - ничего не нашел.
Ты не поверишь! http://speccy.info/JtN
:-)

Titus
19.02.2014, 19:46
Ты не поверишь! http://speccy.info/JtN
:-)

Но это еще не описание алгоритма)

Destr
19.02.2014, 19:53
Ты не поверишь! http://speccy.info/JtN
Ни фига себе!
Я вообще думал что это демка какая-то :)
А это реальный мэн (да ещё выдумавший какую-то неведомую хренотень).
И вопрос про вращалки/алгоритмы опять неприятно повис в воздухе.
Ну что за жизнь!

alone
19.02.2014, 20:33
Вращалка от JtN'а основана на таблице умножения всего на всё и наборе процедур перекрёстного умножения с разными знаками (для вращения по 3 углам надо 3 перекрёстных умножения). Занимает целую страничку.

Правильное округление - это типа inc de:sra d:rr e. Неправильное - без inc. В данном случае просто таблица умножения изначально была построена с округлением вниз, я исправил на правильное.

---------- Post added at 20:33 ---------- Previous post was at 20:30 ----------

Исходный вариант вращалки JtN'а был в ACNews #54 (январь 2009).

Destr
19.02.2014, 21:59
Правильное округление - это типа inc de:sra d:rr e.
Я если честно не понял.
Это смахивает на DE=(DE+1)/2
А почему округление?

denpopov
19.02.2014, 22:11
Я если честно не понял.
Это смахивает на DE=(DE+1)/2
А почему округление?

да, мне тоже неясно

psb
19.02.2014, 22:47
DE=int (DE/2.0+0.5) - так понятнее?

Titus
20.02.2014, 01:34
Вращалка от JtN'а основана на таблице умножения всего на всё и наборе процедур перекрёстного умножения с разными знаками (для вращения по 3 углам надо 3 перекрёстных умножения). Занимает целую страничку.

Ну, так это обычный стандартный подход.
Одна большая таблица умножения 8-битных чисел, и три умножения на координату.

Destr
20.02.2014, 08:41
DE=int (DE/2.0+0.5) - так понятнее?
Неа.
На фига на 2 делить?
В DE число 15.1 бит, так что-ли получается?

Andrew771
20.02.2014, 09:38
de = int((de+1)/2)*2

---------- Post added at 09:38 ---------- Previous post was at 09:36 ----------


А почему округление?
чтобы равномернее точки по экрану распределялись, ближе к реальным координатам, а не жались влево/вверх

Destr
20.02.2014, 11:55
de = int((de+1)/2)*2
Если так - то понятно.


Исходный вариант вращалки JtN'а был в ACNews #54 (январь 2009).
Исходник есть, но компилироватся не хочет :(

psb
20.02.2014, 13:07
de = int((de+1)/2)*2
зачем сначала делить на 2, а потом умножать на 2?? в приведенном коде такого не было.

Titus
20.02.2014, 15:14
Все эти засечки и округления вот ЗДЕСЬ (http://zx.pk.ru/showthread.php?t=11661&page=4) уже обсуждались (начиная с 4-й страницы).

Andrew771
20.02.2014, 17:58
зачем сначала делить на 2, а потом умножать на 2??
чтобы округлить до 2.

psb
20.02.2014, 18:11
зачем округлять до 2х?

Andrew771
21.02.2014, 15:53
да, чё-т я переборщил. Это просто деление на 2 с округлением. Правильнее вот так:
de = int((de+1)/2)

А уж зачем там деление на 2, расскажет Алоний :)

---------- Post added at 15:53 ---------- Previous post was at 15:50 ----------

Впрочем, чё ему рассказывать - это деление отрезка пополам, пока на 64 части не разобьешь :)

alone
23.02.2014, 18:46
Нет, последовательно применять округление нехорошо. Надо делить на 64 один раз с правильным округлением. Я дал просто пример.

Школьное правило округления для десятичных чисел - если следующая цифра меньше 5, то просто отбрасываем, иначе отбрасываем и прибавляем 1. Аналогично для двоичных чисел - если следующая цифра 0, то просто отбрасываем, иначе отбрасываем и прибавляем 1.

Ещё, пример - если мы пишем умножение A*BC с результатом в HL, где L отбрасывается, то для правильного округления можно инициализировать HL=#0080 вместо HL=#0000.

Titus
25.02.2014, 13:41
Алоне, а какие ты знаешь алгоритмы быстрого вычисления перспективы?

alone
25.02.2014, 14:40
Я вычисляю перспективу по таблице размером в страничку.

Titus
25.02.2014, 14:52
Я вычисляю перспективу по таблице размером в страничку.

Это неинформативно)
Что у тебя в ней? Преобразование 1/x? Какая разрядность? Сколько чисел? Чего и как?

Andrew771
25.02.2014, 16:25
Во, накопал своё же раннее:


Перед применением формул перспективы нужно найти новые после поворота x,y,z для каждой точки от начальных x0,y0,z0; a=угол.

Поворот вокруг оси X:
x=x0
y=y0*cos(a)
z=z0*sin(a)

Поворот вокруг оси Y:
x=x0*cos(a)
y=y0
z=z0*sin(a)

Поворот вокруг оси Z:
x=x0*cos(a)
y=y0*sin(a)
z=z0

Формулы для перспективной проекции одной точки:

x'=0.5*ширина_экрана+N*x/z
y'=0.5*высота_экрана+N*y/z

N - глубина по оси z до горизонта, экспериментально подобрать.

Вот и думай, как это отабличить :)

denpopov
25.02.2014, 16:36
Алоне, а какие ты знаешь алгоритмы быстрого вычисления перспективы?

А зачем вообще нужна перспектива?

Andrew771
25.02.2014, 16:37
А зачем вообще нужна перспектива?
3D-шутер - мечта поколения Пепси :)

Titus
25.02.2014, 17:17
Вот и думай, как это отабличить :)

Ключевое слово - 'быстрые' алгоритмы)

---------- Post added at 17:17 ---------- Previous post was at 17:17 ----------


А зачем вообще нужна перспектива?

Для перспективной 3D графики)

Hacker VBI
25.02.2014, 17:22
Titus, а что у нас в перспективе? ;)

Titus
25.02.2014, 17:29
Titus, а что у нас в перспективе? ;)
Перспективная графика)

---------- Post added at 17:29 ---------- Previous post was at 17:25 ----------


Во, накопал своё же раннее:

Поворот вокруг оси X:
x=x0
y=y0*cos(a)
z=z0*sin(a)

А почему не:
y = y0*cos(a) + z0*sin(a)
z = z0*cos(a) - y0*sin(a)
?

denpopov
25.02.2014, 17:31
Для перспективной 3D графики)

Перспективная графика)

с тобой разговор выйдет несерьезный.


3D-шутер - мечта поколения Пепси
да ладно, с доступными движками можно и замутить подобное.

Titus
25.02.2014, 17:32
с тобой разговор выйдет несерьезный.
Каков вопрос, таков и ответ)

denpopov
25.02.2014, 17:47
Каков вопрос, таков и ответ)
то есть объяснить ты не можешь?

Titus
25.02.2014, 18:52
то есть объяснить ты не можешь?
Я тебе обьяснил.

Если человек спрашивает, скажем: зачем нужна еда.
Ему ответят - чтобы есть.

---------- Post added at 18:52 ---------- Previous post was at 17:52 ----------

Если вопрос к тому, собираюсь ли я делать 3д-игры, то ответ - нет, не собираюсь)

Смысл в том, что повороты в 3D можно сделать весьма быстро, если использовать таблицы умножения. Тогда как с перспективой сложнее, ввиду того, что это штука нелинейная и такими же простыми таблицами умножения тут не обойдешься.

denpopov
26.02.2014, 07:48
Я тебе обьяснил.

Если человек спрашивает, скажем: зачем нужна еда.
Ему ответят - чтобы есть.

зануда ты, дядя Андрей. я в демах не особо заметил перспективной проекции, наверное кодеры не особо себя утруждали.

alone
26.02.2014, 08:43
>Что у тебя в ней? Преобразование 1/x? Какая разрядность? Сколько чисел? Чего и как?
В ней k*L/H. В H подставляется Z (6 бит), в L подставляется X или Y (8 бит).

Andrew771
26.02.2014, 10:05
А почему не:
y = y0*cos(a) + z0*sin(a)
z = z0*cos(a) - y0*sin(a)
?
Видимо, то было для кубов.

Titus
26.02.2014, 13:23
>Что у тебя в ней? Преобразование 1/x? Какая разрядность? Сколько чисел? Чего и как?
В ней k*L/H. В H подставляется Z (6 бит), в L подставляется X или Y (8 бит).

Понятно. 64 точки для Z - это очень маленькое пространство.
Т.е. быстрых алгоритмов для Z в диапзаонах, скажем 1024 точки или хотя бы 512 никто не применял.

---------- Post added at 13:22 ---------- Previous post was at 13:22 ----------


зануда ты, дядя Андрей. я в демах не особо заметил перспективной проекции, наверное кодеры не особо себя утруждали.

Сложнее это, вот и не делали.

---------- Post added at 13:23 ---------- Previous post was at 13:22 ----------


Видимо, то было для кубов.

Каких кубов? Поясни.

Andrew771
26.02.2014, 17:46
Каких кубов? Поясни.
Построение кубов в перспективе в кросс-программе 3D-View (http://zx.pk.ru/showpost.php?p=379799&postcount=4)

Destr
27.02.2014, 23:40
Ну вы даёте, ребята.
Ещё начните тут "политика в Украине"!
Хорош флеймить уже!
Давайте что-ли про 3d преобразования и вычисления.
Убогими формулами можно не бросатся больше, спек считать быстро не могёт.
Или разворачиваем тему табличек, или молчим, лады?

---------- Post added at 22:40 ---------- Previous post was at 22:35 ----------

Вообще надежды на Алонкодера и Титуса.
Andrew771, тоже внушает лёгкую уверенность в то что всё будет гут :)
А вот некоторые товарищи (я пальцем тыкать не стану, сам поймёшь наверное?) любят темы засорять.
Не делай так.
Не надо.

Andrew771
28.02.2014, 10:46
Или разворачиваем тему табличек, или молчим, лады?
Придумай, как их эффективно отабличить.
Таблицы синусов и косинусов понадобятся. И таблица k*A/B. Вот от максимальных значений A и B зависит размер таблицы и разрешение 3D-сцен.
Можно A и B брать с шагом, промежуточные значения интерполяцией получать. Интерполяцию можно тоже по формулам вычислять, превратив в таблицы. Обычно формула для интерполяции представляет из себя многочлен: a+b*x+c*x^2+d*x^3+... Чем больше членов, тем точнее.

alone
01.03.2014, 12:33
В Wolf 48K коррекция перспективы делалась через перевод Z (12-разрядного) в логарифм по табличке (с предварительным сдвигом на эн бит, пока Z не влезет в разрядность таблички, а потом прибавлением к числу из таблички константы, соответствующей этому сдвигу).