Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Мультимедия, OpenGL/DirectX > Как _быстро_ отрендерить heightmap?


Автор: nickless 29.8.2005, 06:04
Несколько дней назад начал делать ландшафт с оптимизацией, принцип такой: загружаю heightmap размера x*y, делаю VertexBuffer с x*y 3д-пунктиками.
Потом делю map на кусочки 4*4 (квадрата = 2 треугольника) и оптимирую их по одному алгоритму чтоб уменьшить кол-во треугольников и делаю IndexBuffer-ы с triangle fan-ами.

Вопрос: Можно ли отрендерить все n (около x*y/4) fan-ов (например по 8 треугольников / 10 индексов) за один вызов DrawIndexedPrimitive(), т.е. указать кол-во fan-ов и длинну fan-a как с треугольниками в triangle list??? А то уж очень медленно получается smile
Или может по-другому как-то можно (я сейчас 2 вложенных for() использую и каждый fan отдельно рисую, по смещению в буффере)?
Всю DirectX SDK облазил, ничего не нашел... smile

Автор: empter 31.8.2005, 13:17
Цитата(nickless @ 29.8.2005, 06:04)
Потом делю map на кусочки 4*4 (квадрата = 2 треугольника) и оптимирую их по одному алгоритму чтоб уменьшить кол-во треугольников и делаю IndexBuffer-ы с triangle fan-ами.

Не совсем понял, как конкретно ты делаешь, ну да ладно.

Во первых тормоза из за trangle fans, их использовать не рекомендуется, самый быстрый вариант - D3DPT_TRIANGLELIST.
Во вторых например я делаю так:

Создаю VertexBuffer размером X на Y, причем X = Y, то - есть 256x256, 512x512 и так далее.
Разбиваю на патчи размером 17x17, они перекрываются, и получается 16х16.
Для каждого патча, в карте 256х256 их 256, 512х512 их 1024, создаю по 5 IndexBuffer
разной детализации.
При максимальной детализации все 16х16 вершин патча задействованы,
следующий уровень рисует полигоны через 1 вершину, следующий через 2 и т.д, последний,
представляет из себя патч из 2 треугольников.

Минус - много вызовов DrawIndexedPrimitive(), но эффект заметен даже на карте 256х256.
Технология называется Geomipmapping, хорошо описана в книге Premier - Focus On 3D Terrain Programming, правда под OpenGL.

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

Автор: nickless 1.9.2005, 01:57
Спасибо за ответ, а то я уж думал совсем плохи мои дела...

Цитата
Не совсем понял, как конкретно ты делаешь, ну да ладно.

Приаттачил картинку, как это дело примерно выглядит.

Цитата
Во первых тормоза из за trangle fans,  их использовать не рекомендуется, самый быстрый вариант - D3DPT_TRIANGLELIST.

Fans взял, потому что это все же лучше, чем triangle list (fps столько же, но памяти меньше надо), а triangle strips не получаются, потому что надо тогда каждый раз после оптимизации еще и strips искать.

Цитата
Для каждого патча, в карте 256х256 их 256, 512х512 их 1024, создаю по 5 IndexBuffer
разной детализации.

У меня карта должна быть не меньше 1024*1024 , а тогда даже индехбуфферы память жрут здорово... вон на 2048*2048 каждый всреднем мегабайт под 20 будет...

Цитата
Минус - много вызовов  DrawIndexedPrimitive(), но эффект заметен даже на карте 256х256.

Вот и у меня тоже много вызовов, а как бы их кол-во уменьшить? Может попробовать mesh сделать?


Автор: Mad 6.9.2005, 00:31
Вообщето и это не выход из полодения, для рендеринга ландшафтов (по hightmap) поищи в сети описание на ROAM алгоритм.
Он будет тебе сам (динамически) определять необходимую степень детализации в зависимости от растояния до камеры.

Автор: empter 20.9.2005, 18:26
Много мучился над ROAM под DirectX, имхо организовать его (под DirectX трудно, если вообще возможно),

Цитата(nickless @ 1.9.2005, 01:57)
Вот и у меня тоже много вызовов, а как бы их кол-во уменьшить? Может попробовать mesh сделать?



Так еще хуже.



Цитата(nickless @ 1.9.2005, 01:57)
У меня карта должна быть не меньше 1024*1024 , а тогда даже индехбуфферы память жрут здорово... вон на 2048*2048 каждый всреднем мегабайт под 20 будет...

Можно попробовать динамически подгружать и выгружать блоки карты, т.е карта 1024Х1024 состоит из 4х блоков 512Х512.


Автор: nickless 21.9.2005, 19:02
Цитата
Вообщето и это не выход из полодения, для рендеринга ландшафтов (по hightmap) поищи в сети описание на ROAM алгоритм.
Он будет тебе сам (динамически) определять необходимую степень детализации в зависимости от растояния до камеры.
Алгоритм у меня типа ROAM есть, из книжки, дело не в нем.

Цитата
Так еще хуже.
Ну и ладно, начал было mesh делать, но как-то не пошло, лучше баферы оставлю, так проще.

Цитата
Можно попробовать динамически подгружать и выгружать блоки карты, т.е карта 1024Х1024 состоит из 4х блоков 512Х512.
Я так уже начал делать, но все равно, если много видно, то и треугольников соответственно куча.

Я так понял, в DirectX единственный способ добавить fps, это понаделать как можно меньше (штук) как можно бОльших (кол-во треугольников) trianglestrips?
Интересно, как heightmap в FarCry организован, там ведь мап огромная, и видимость тоже...

Автор: empter 22.9.2005, 17:42
Цитата(nickless @ 21.9.2005, 19:02)
Я так понял, в DirectX единственный способ добавить fps, это понаделать как можно меньше (штук) как можно бОльших (кол-во треугольников) trianglestrips?

А пробовал frustum culling - отсечетие обьектов, которые не попадают в камеру.
Т.е патчи, которые не попадают в камеру вообще не рендерятся smile
На больших картах дает серьезный прирост производительности.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)