Войти
ПрограммированиеФорумГрафика

Воксельные миры (4 стр)

Страницы: 1 2 3 4 5 6 Следующая »
#45
(Правка: 18:07) 18:03, 11 июня 2020

> жду ваши воксель-рендерилки на 4k мониторе посоны

Да лехко :) Я несколько лет назад переносил классический Wave Surfing на GPU, там 500+ fps получается на 4k/1070.
2020-06-11_171857 | Воксельные миры
Хотя с ограничениями алгоритма на движение камеры (нет крена, ограничен тангаж) толку от этого немного. Так, побаловаться.


#46
18:24, 11 июня 2020

Сейчас заметил что в Команче (на гифках) есть крен - видимо, они просто поворачивали уже готовую картинку. С тангажом сложнее, прямо вверх или вниз смотреть нельзя. Хотя в Voxlap (который вроде бы происходит от того же Wave Surfing) это как-то решено.

#47
19:45, 11 июня 2020

Misanthrope
Прям 4096 × 2160? А сколько у тебя видеокарт?

#48
(Правка: 19:51) 19:51, 11 июня 2020

Ну все, я зарегистрировал для движка домен http://truevoxel.com
Осталось только логотип нарисовать

#49
(Правка: 13 июня 2020, 2:08) 19:28, 12 июня 2020

Кролики

Изображение

Первоначальный план был в том, чтобы трассировать несколько лучей через octree, получая таким образом облако видимых вокселей, а потом повторно отрисовывать эти воксели и трассировать дополнительные лучи, постепенно получая полноценную картинку. При этом должна была возникнуть положительная обратная связь: чем быстрее отрисовывается кадр, тем меньше следующий кадр отличается от предыдущего, тем меньше незаполненных пикселей будет возникать из-за смещения камеры и тем меньше лучей нужно трассировать, чтобы отрисовать следующий кадр, а, значит, еще быстрее будет отрисовываться следующий кадр…

На вход демка брала воксельную модель в виде 3D массива 512х512х512 вокселей, 0x00 байт означал отсутствие воссела, 0xFF - наличие. Чтобы модель выглядела повеселее, на каждый слой накладывалась текстура (одна и та же) 512х512.

Я очень хотел поскорее проверить идею и сначала написал примитивный трассировщик луча прямо по 3D массиву. Лучи трассировались слишком медленно. Чтобы оценить скорость трассировки через octree и при этом не писать код про octree, я ускорил трассировку при помощи distance field, которое рассчитывалось после запуска (это занимало 2-3 минуты). Заодно добавил ambient occlusion, чтобы стало видно детали геометрии кроликов.

В итоге получился ray marching of distance field, который для заданного пикселя записывал в буфер расстояние до первого видимого вокселя и его цвет.

Изображение


Каждый следующий кадр буфер репроецировался с учетом движения камеры и, не помню точно, но примерно в 1/8 пикселей равномерно распределенных по экрану запускались новые лучи.

Запустить видео по клику - Как делать игрыЗапустить видео по клику - Как делать игры


UnlimitedHorror3d_014.7z

Я попробовал этот подход на настоящем облаке точек, полученном в результате сканирования лазерным сканером, но, так как мне все еще лень было писать octree, я просто постепенно шел по списку точек в облаке точек, а не запускал лучи.

cubes | Воксельные миры

А дальше я решил использовать precomputed visibility чтобы совсем избавиться от трассировки в рантайме и устроить стриминг уровней с сервера. Идея такая: представить весь игровой мир как octree, в каждом из узлов которого записать облако точек, видимых из любой точки в пределах этого узла, но не содержащихся в узлах на пути от корня octree до текущего узла. Дальше чтобы отрендерить изображение сцены из любой точки достаточно пройти от корня к листу инверсного октального дерева, собирая по пути все видимые вокселы.

Мне было снова лень делать octree и я опробовал идею на софтрендере 1000 кубов, записав не облака точек в узлы octree, а битовую маску видимых полигонов в клетки кубической решетки. Видимость полигонов определялась так: камера помещалась в центр ячейки кубической решетки и отрисовывала полигоны, записывая вместо цвета номер полигона на экран. После этого в цикле пробегал по всему экрану и выставлял в маске биты для видимых полигонов в 1. После этого процесс повторялся для рандомных точек в которых могла оказаться камера. Чем дольше шел предрасчет, тем меньше оставалось артефактов.

https://drive.google.com/file/d/0B1I9KAOJKOmHMVJxdHlKaThWX3M/view?usp=sharing

#50
(Правка: 20:20) 20:07, 12 июня 2020

Вий
> А дальше я решил использовать precomputed visibility чтобы совсем избавиться от
> трассировки в рантайме и устроить стриминг уровней с сервера. Идея такая:
> представить весь игровой мир как octree, в каждом из узлов которого записать
> облако точек, видимых из любой точки в пределах этого узла, но не содержащихся
> в узлах на пути от корня octree до текущего узла. Дальше чтобы отрендерить
> изображение сцены из любой точки достаточно пройти от корня к листу инверсного
> октального дерева, собирая по пути все видимые вокселы.
интересная идея. но ведь так получится, что некоторые точки будут содержаться сразу в нескольких узлах? насколько получается большой оверхед?

> я ускорил трассировку при помощи distance field
ну блин, это чит, потому что distance field ты для геометрии нормального размера не посчитаешь. ты фактически пользовался тем фактом, что геометрия размножена. то есть неповторяющуюся геометрию такого же масштаба ты не смог так рендерить.

тем временем я написал самую мерзкую часть — синхронизацию памяти при стриминге данных и одновременной их отрисовке. ещё погонял сколько-то тестов. за адекватное время рисуется как раз около 10 миллионов точек (11мс). то есть что бы мы ни придумывали, алгоритм должен отправить видюхе в итоге рендерить не больше точек, чем вот столько.

#51
(Правка: 20:19) 20:19, 12 июня 2020

Octree даёт примерно такой же прирост производительности, по сравнению с массивом, как и distance field. А ещё по octree для далеких объектов не нужно идти до листьев, так что уже второй или третий кролик получили бы от этого дополнительное ускорение.

#52
20:26, 12 июня 2020

ещё немного данных по поводу скорости работы с памятью. я тестировал скорость отрисовки 10 миллонов точек, если все они видимы, если все они невидимы (за камерой), если они хранятся в device local памяти и если они хранятся в host cached/host coherent (как выяснилось, между ними разницы нет на моей машине) памяти. вот данные:
все точки видимы, host coherent: 30ms
все точки за камерой и невидимы, host coherent: 24ms
все точки видимы, device local: 12ms
все точки за камерой и невидимы, device local: 1.2ms

точки используются из 12 float'ов (нормаль, позиция, цвет), 10 миллионов точек за 30ms обозначают, что на видюху пересылается примерно 15GB информации, что удивительно точно согласуется с пропускной способностью x16 PCI-e в 15.75GB/s, то есть это значит, что шину можно загрузить по полной, просто читая данные таким образом из host coherent буфера. также это обозначает, что в случае с device local памятью производительность упирается не в скорость чтения памяти, а в скорость записи в рендертаргет, то есть в филлрейт.

#53
20:31, 12 июня 2020

ещё гениальная идея, которую я давно вынашивал, вдруг кому-то понадобится: если организовывать octree из точек, то координаты точек в узлах можно хранить не в мировых координатах во float32, а в системе координат внутри, собственно, узла, в uint8 — это сэкономит на памяти в 4 раза, а вне узла точки всё равно находиться не могут + точность выше 256 fixed point градаций всё равно не нужна (более высокая точность может быть достигнута в потомках узла).

#54
(Правка: 21:03) 21:02, 12 июня 2020

Я бы целился примерно в 3 млн точек в поле зрения. Это 1,5 overdraw для 1920x1080, причём из host coherent их можно будет рисовать за 9 мс. Остаётся вопрос: как подготовить за 7 мс 135 мб данных. На самом деле примерно никак, можно отдельно готовить для близких и далеких объектов (далекие можно реже обновлять) и нужно существенно уменьшать размер данных, нормаль в 3 float это явный перебор. И цвет тоже.

#55
21:13, 12 июня 2020

Вий
> Остаётся вопрос: как подготовить за 7 мс 135 мб данных
сделать шину =135/7 =20
Mb/ms=Mb*1000/s
шина данных типа 20 Гигабайт в секунду скорость шины

#56
(Правка: 21:48) 21:43, 12 июня 2020

12 float на воксел (48 байт) - слишком много.

Если замапить 6 буферов, соответствующих сторонам куба, на который проецируется картинка на этапе подготовки данных, в память как 6 квадратных областей большой текстуры, положение точки на текстуре  позволит однозначно определить направление от камеры к вокселу, останется только записать расстояние до точки (его сложно считать на cpu, вместо него легче передать координату вдоль линии взгляда камеры). Нормаль отлично кодируется в 2 байта. Цвет - еще в 3. Итого в 9 байт отлично все можно запаковать, но, наверняка придется выравнивать данные и поэтому пусть будет 16 байт на воксел, это в 3 раза меньше исходных 48.

Подготовить за 7 мс 45 МБ данных на CPU кажется уже более-менее выполнимой задачей.

Но, так как упирались мы в шину, вместо 9 мс передавать и рисовать точки нужно будет около 4 мс. На подготовку 45 МБ у нас будет не 7 а целых 12 мс. Вполне реалистично.

#57
0:02, 13 июня 2020

Вий
>При этом должна была возникнуть положительная обратная связь: чем быстрее отрисовывается кадр, тем меньше следующий кадр отличается от предыдущего, тем меньше незаполненных пикселей будет возникать из-за смещения камеры и тем меньше лучей нужно трассировать, чтобы отрисовать следующий кадр, а, значит, еще быстрее будет отрисовываться следующий кадр…
Вообще-то это работает и в обратную сторону, не успел за 1 кадр следующий ещё дольше.

Цвет можно ужать и до 2 байт, если красится воксель, то ему и этого хватит.

Странная зебра выходит.
artif | Воксельные миры

>На подготовку 45 МБ у нас будет не 7 а целых 12 мс.
Да хоть 16 на 16 ядрах. Каким таким образм можно получить массив точек к отрисовке? Вот есть у меня сжатая хорошо модель мне, я её распаковал и получил массив x*y*z вокселей с цветом и нормалью, но толку то мне от них, на рендер надо подать точки, но как их можно получить?

Предположим есть несколько лодов объекта с точками и его надо подавать на рендер.
если передать их всех, то этоже теряет всякий смысл, рисовать треугольниками и всё.
если отсекать часть то как?

может стоит идти по пути ускорения raytrace, а не создании множества точек на цпу?

#58
1:24, 13 июня 2020

samrrr
> может стоит идти по пути ускорения raytrace, а не создании множества точек на
> цпу?
У тебя есть идеи, как можно ускорить raytrace?

#59
6:04, 13 июня 2020

Вий
> причём из host coherent их можно будет рисовать за 9 мс
я думаю, что host coherent память лучше использовать как промежуточный массив, который строится, чтобы отправить данные на видюху в device local массив, который, собственно, рендерится. таким образом, если камера не двигается, то все точки уже сидят в device local массиве, не меняясь между кадрами, это отрисовывается очень быстро. рисовать из host coherent памяти — так себе затея, я считаю.

> 12 float на воксел (48 байт) - слишком много.
это ясное дело. это можно очень сильно пожать, как минимум раза в 4 без потери точности.

Страницы: 1 2 3 4 5 6 Следующая »
ПрограммированиеФорумГрафика