Что делать когда geometry clipmaps видимая сетка вылазит за область карты высот

Что делать когда geometry clipmaps видимая сетка вылазит за область карты высот

Итак, абстрагируемся от всего что делается в моем проекте, чтобы не было лишних вопросов и предположений.

Допустим, есть карта высот размером 4096х4096 точек. К ней прилагается сетка треугольников, допустим, 512х512, дискретность которой равна дискретности карты высот (т.е. между точками треугольников сетки расстояние такое же, какое между точками на карте высот). Во время перемещения камеры над картой высот мы увеличиваем координаты сетки треугольников в соответствии с положением карты. Допустим, это происходит так - отдает в видеокарту нашу сетку + смещение по осям XY так, чтобы высоты брались от этого смещения. Пока мы двигаемся в пределах карты высот +- 512/2 - все в порядке, так как с карты высот постоянно берутся существующие в наличие высоты. Но как только мы выходим за эти рамки (допустим, камера находится на краю карты высот так, что наша сетка наполовину в карте высот, а наполовину - за ее пределами), то нам нечем заполнять сетку и там рисуется либо плоскость с z=0, либо происходит копирование с начала карты высот (принцип повторения текстуры).

Если это игра, состоящая из одного квадрата 4096*4096, то мы можем просто запретить камере выходить за эти рамки, но что, если карта высот не одна?

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

Сразу на ум лезет мысль, согласно которой мы для каждого квадрата (а квадрат, напомню, есть карта высот) создаем свою сетку, которая перемещается сугубо в регионе, в котором находится этот квадрат. Так как это был куб, но мы его преобразовали в сферу, максимальное количество видимых квадратов = 5 (полюс + 4 опоясывающих по экватору) засчет приобретенной квадратами выпуклости. 5 сеток - не так, по идее, страшно, но что делать, если сетка квадрата обрывается на границе карты высот и, допустим, 278 дискрете а не на 512?

Возможные придуманные варианты: 1) для каждого кадра мы проверяем - не выходит ли сетка за область карты высот и, если выходит, перестраиваем сетку с NxN до (N-dx)*(N-dy), где dx и dy - выходящее за рамки карты. 2) для каждой точки в вершинном шейдере мы проверяем не выходит ли она за рамки карты высот и, если выходит, ставим ее на границе, тем самым собирая "лишние" треугольники в последний или превращая их в вырожденные 3) ?

Хотелось бы послушать имел ли кто-нибудь подобные проблемы, как решал и мнения насчет вариантов 1 и 2. Возможно, найдутся варианты >2.

А как же текстуры?

Alex, не понял к чему ты это =) Разжуй плз.

Есть третий вариант: Все таки мы рисуем всего одну сетку и на ребрах не имеем никаких проблем - часть результирующей карты высот берем (из текстуры высот, да) из одной карты, а часть из другой. Однако, для точек, в которых соединяются три квадрата, нам надо рисовать (если точка соединения находится точно по центру сетки) 3/4 сетки, так как две части сетки будут повторять друг друга с разницей в 90 градусов по текстуре третьего квадрата. Соответственно, часть 3 берет карту высот 1, часть 4 - карту высот 2, часть 2 - карту высот №3, а часть 1 вообще откидывается, так как если их рисовать, получится что мы дважды рисуем одни и те же точки, но с поворотом карты и, соответственно, поворотом расположения треугольников в квадрате - будут видны пересечения двух треугольников. Вычитание 1/4 квадрата как-то меня пугает =/ имхо проче на каждый квадрат ЛОД наметать

Slukad > соответственно, есть места, где в одной точке сходятся три квадрата хочу увидеть скриншоты этих загадочных мест

Slukad > Допустим, есть карта высот размером 4096х4096 точек > К ней прилагается сетка треугольников, допустим, 512х512 они должны быть разными?

посмотрел видео представлял себе это несколько иначе

Slukad > К ней прилагается сетка треугольников, допустим, 512х512 Что ты подразумеваешь под сеткой треугольников. Как ты собираешься "скармливать" ее видеокарте? У тебя будет индексный буфер + буфер вершин или просто треугольники строятся по точкам? Будешь ли ты использовать текстурирование? Что значит, что сетка у тебя "скользит" по карте высот?

Как я бы сделал: Подготовка карты: 1) разбивка твоей гигантской местности на мелкие локации, генерация каждой локации по надыбленным картам высот (массив вершин с координатами, текстурными координатами, цветами и нормалями + массив индексов полосками треугольников). Размер локации таков, чтобы наблюдатель мог увидеть вокруг себя 25 локаций (9, 49, не так важно), а дальше - горизонт. 2) сохранение локаций в файл.

Визуализация: Так как наблюдатель видит вокруг себя 25 локаций (стоя в центре локации [i,j] видит локации от [i-2, j-2] до [i+2, j+2]), то их и скармливаем видеокарте посредством VBO. Если вышли в локацию правее (то есть [i+1, j]), подгружаем пять локаций справа (грузим их VBO), но не торопимся стирать 5 локаций слева (чистить их VBO), так как наблюдатель может "метаться" слева направо через границу. Похерим мы их (очистим VBO) только когда удостоверимся, что наблюдатель уже далеко от границы (уже в центре новой локации тусуется). И такой алгоритм для всех соседних (а их 8) локаций. Конечно, несколько другой порядок будет там, где у тебя угол твоего "сферо-куба". Но и это не вопрос - при переходе в соседнюю локацию простым перебором определяем ближние 25 (можно и не 25, а больше/меньше) и подгружаем их в VBO.

В видеокарту я отдаю сетку с, грубо говоря, текстурными координатами вместо вершинных. Нафиг не нужны индексы, так как у меня и вертексов чуть больше чем треугольников (GL_TRIANGLE_STRIP). Видеокарте также отдается (пока) две текстуры - флоатовая с координатами XYZ и обычная с текстурой + смещение. Шейдеры лопатят координаты и текстуру на эту сетку. Получается картинка.

Итог - я кидаю в видеокарту 2 текстуры + сетку, а шейдеры (которые вообще скоростные ребята) все накладывают. Возни с буферами индексов, нормалей и цветов нет. Для нормалей тоже, скорее всего, будет выделена текстура, только 16F.

Кажется, первый вариант, который я написал, самое оно =/

Алекс, твой способ. не знаю. Ну прикинь, я летаю вокруг земли, локации грузятся, все круто, а потом я резко ухожу в космос, поворачиваюсь к земле и. привет, ФПС! Либо делать локации ЛОДами. Локации - те же квадраты, так что при просмотре земли из космоса мы опять же придем к тому от чего ушли =)

ОК, вспомним ромбододекаэдр - тоже есть точки где сходятся по три грани. В любом случае гексагонов не избежать. Есть технология Spherical Clipmaps, но она адовая и имеет кучу недостатков в скорости и бешеную препроцессинговую подготовку.

Ссылку ту я уже читал. Прохладная история в моем случае.

Ну, скажем так, если головой подумать, то мой и твой способы отличаются лишь: 1) в моем алгоритме все считается заранее в редакторе, а в проге грузится готовый меш-локация, 2) у тебя в видюху грузится все тоже самое, только по-отдельности: z-координата сетки через текстуру высот, нормали грузятся (или будут грузиться) - тоже через текстуру, цвет - опять-таки через текстуру и текстурные координаты - через массив. И считается все это на шейдерах.

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

Если в космос будешь летать, то да, по моему способу без ЛОД-ов никуда. А как твой способ без ЛОД-ов справиться?

Slukad > Локации - те же квадраты, так что при просмотре земли из космоса мы опять же придем к тому от чего ушли =) Самый простой ЛОД четырехугольной локации - 2 треугольника. Пусть ты Землю разбил на 10000 локаций. Тогда из космоса Земля будет рисоваться примерно 10000 треугольниками - не нагрузка для видеокарты.

Не Z-координата, а все три координаты через текстуру GL_RGB32F_ARB =) ЛОДы будут по типу мегатекстуры. Ты точно понял Geometry clipmaps? =)

>А как твой способ без ЛОД-ов справиться? Это я не подумавши ляпнул ( Slukad > Ты точно понял Geometry clipmaps? =) :) ну так, слегка представляю, вот тут уже обсуждали http://www.gamedev.ru/code/forum/?id=93948 Хочу добавить, что для моего способа (он не "мой", конечно) строить ЛОД-ы тоже не сложно - так как сетка локации регулярная, пересчитываешь индексный буфер для треугольников с вдвое большими ребрами и все, вертексные буферы не трогаешь вообще. Операция линейная, быстро работает на лету. Таким образом, рисуешь ближние локации с более высоким ЛОД-ом, для дальних ЛОД-ы понижаешь. Получаешь ту же технологию клипмапс. Я же говорю, разница между твоим и моим подходами только в представлении геометрии и в том, как она рассчитывается.

Да я и не говорю, что мой способ лучше. Просто если делать как у меня, не возникает проблем, описанных в посте #0

Slukad > Нафиг не нужны индексы Здесь описан клипмапс, в котором человек не гнушается использовать и вертексные буферы и индексы: "Вершины должны быть проиндексированы, чтобы определить треугольники", что ты об этом думаешь? http://iandreev.wordpress.com/2011/05/31/%D0%BB%D0%B0%D0%BD%D0%B4… %D0%B0%D1%81/

Я думаю, что в том случае вершины индексируются чтобы T-junkles закрывать.

Вообще у меня сейчас, после твоего поста (спасибо, кстати, порой, мне просто надо чтобы кто-то со мной говорил, предлагая, порой, бредовые идеи), возникла еще одна идея. Причем, почему возникла. Вот я хочу определить в какой точке сейчас находится камера. Ну, или, между какими точками моего куба, трансформированного в сферу (и это адъ). Допустим, возьмем верхний куб, который у полюса. Мы имеем Theta и Phi камеры (ну и высоту, конечно). Все это в полярной системе. Попробуй теперь перевести из полярной в, хотя бы, координаты на грани куба =) Треш ужасный.

Так вот, какая идея - допустим, мы бьем квадраты обычным квадом, т.е. строим для каждого квадрата квадродерево, для него записываем наши текстуры и, вроде, все ок, но два минуса: 1) хрен его знает сколько текстур придется грузить, если отходить от идеального варианта, когда один элемент квада имеет одну текстуру. Это надо обкатывать и проверять 2) Возможны возникновения проблем с границами.

Второе решается принудительным пробегом внутрь дерева и проверкой видимости (на самом деле, не так там все ужасно) Первое - зависит от того, как реализовывать. Моя текущая идея - попробовать замутить что-то вроде буфера в видеокарте. Т.е. мы знаем что один лист квадродерева держит текстуру 256*256. Нам при отрисовке и перемещении, возможно, придется старые текстуры выгружать, а новые подгружать, но есть определенная гарантия, что мы не увидим в одно время на экране больше N квадратов разной детализации.

Создаем в видеопамяти текстуру размером, скажем, 10*10*256*256=2560*2560 (для самой страшной текстуры с вершинами это 8192*8192*4*3=75 Мб). Это - буфер. Каждый узел дерева хранит в себе оффсеты для этой мультитекстуры (термин мегатекстура занят как и MIP), с помощью которых шейдер грузит именно то, что надо. Итого мы можем обеспечить текстурами 100 узлов деревьев. Если при этом мы будем внимательно следить за хранилищем, то новые текстуры при подгрузке будут вставать не куда попало, а в те места, которые либо свободны, либо не используются некоторое количество времени (допустим, применив счетчик кадров для каждой текстуры, который будет отнимать 1 при неотрисовке и добавлять 1 при отрисовке текстуры. Какой профит мы получаем? Во-первых, шейдер всегда работает с одной текстурой и грузим мы только одну текстуру и однажды, а потом просто обновляем данные. Во-вторых, очистка памяти у нас вызывается неявно и совпадает с загрузкой новой текстуры (на самом деле это реально круто) В-третьих, проверку отрисовки можно делать основываясь на мировых координатах, сохраняя в листе дерева информацию об описывающем кусок ландшафта паралеллепипеде - это, на самом деле, вкупе с деревом, хороший клиппинг. В-третьих (хотя это черевато), мы можем значительно сократить размер всей карты на HDD, если составим нерегулярное квадродерево, заставляя прекращать проход вглубь до требуемого, допустим, 9 уровня, если карта высот в этом квадрате без перепадов (равнины, океан). Это действительно ОЧЕНЬ сильно сократит размер карты, но проблема в том, что могут получиться не очень хорошие переходы, не кратные двум. Хотя, это, опять же, надо проверять.

Какие возможные минусы: 1) Я не знаю как сильно будет напрягаться видеокарта при работе с текстурой такого размера - возможно, у нее там кровь потечет из кулера 2) Я совершенно не представляю себе хватит ли этой сотни текстур

Итог - будет понедельник, придем на работу и засядем пробовать. А пока покричим, что хотим бету дьяблы и пойдем играть в лол =) Всем хороших выходных.

Slukad > Я думаю, что в том случае вершины индексируются чтобы T-junkles закрывать Ты имеешь ввиду дырки на границах уровней закрывать? Нет, не для этого. Slukad > предлагая, порой, бредовые идеи Всегда пожалуйста Ж))))))))))))

📎📎📎📎📎📎📎📎📎📎