+7 (495) 229-0436   shopadmin@itshop.ru 119334, г. Москва, ул. Бардина, д. 4, корп. 3
 
 
Вход
 
 
Каталог
 
 
Подписка на новости
Новости ITShop
Windows 7 и Office: Новости и советы
Обучение и сертификация Microsoft
Вопросы и ответы по MSSQLServer
Delphi - проблемы и решения
Adobe Photoshop: алхимия дизайна
 
Ваш отзыв
Оцените качество магазина ITShop.ru на Яндекс.Маркете. Если вам нравится наш магазин - скажите об этом Google!
 
 
Способы оплаты
 
Курс расчета
 
 1 у.е. = 91.69 руб.
 
 Цены показывать:
 
 
 
 
  
Новости, статьи, акции
 

Создание процедурных ландшафтов

26.02.2013 17:42
risenow

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

Вступление

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

Карты высот (Height Map)

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

Пример кода:

float heightmap[width][lenght]; for (int i = 0; j < width; j++) { for (int j = 0; j < length; j++) { heightmap[i] [j]=CurHeight; } }

Итак, у нас есть построенная карта высот. Что это нам дает? Да все. Далее нужно просто разбить все это дело на треугольники. 

vector Vertexes[width*length*2*3]; for (int i = 0; j < width; j++) { for (int j = 0; j < length; j++) { //first triangle Vertexes[c].x=i; Vertexes[c].y=heightmap[i] [j]; Vertexes[c].z=j; Vertexes[c+1].x=i+1; Vertexes[c+1].y=heightmap[i+1] [j+1]; Vertexes[c+1].z=j+1; Vertexes[c+2].x=i+1; Vertexes[c+2].y=heightmap[i+1] [j]; Vertexes[c+2].z=j; //second tr Vertexes[c+3].x=i; Vertexes[c+4].y=heightmap[i] [j]; Vertexes[c+5].z=j; Vertexes[c+6].x=i+1; Vertexes[c+7].y=heightmap[i+1] [j+1]; Vertexes[c+8].z=j+1; Vertexes[c+9].x=i; Vertexes[c+10].y=heightmap[i] [j+1]; Vertexes[c+11].z=j+1; } }

Где width будет шириной ландшафта (по оси х), length - длинной (по оси z), CurHeight значение высоты для данного узла.
Карта высот:

Карта высот, разбитая на треугольники:

Построение карты высот на основе алгоритма шумов Перлина

Очень часто, люди которые поняли смысл и логику логику карты высот, бегут реализовывать ее и заполнять полностью случайными значениями(random(100)).И получают в результате вот что:

Для ландшафта простого рандома недостаточно. Ведь ландшафт должен иметь последовательность, плавность и некую зависимость между узлами в карте высот. И с такой задачей идеально справляются шумы Перлина. Шум Перлина - математический алгоритм по генерированию процедурной n-мерной текстуры псевдо-случайным методом.Внимательный читатель наверняка удивился двум словам в определении: "текстуры" и " псевдо-случайным". Поясню. Текстура, созданная с помощью этого алгоритма имеет 2 цвета - белый и черный. Соответственно, цвет можно использовать, как значение высоты. А псевдо-случайность развеивается коэффициентом сдвига, рассчитываемым всего один раз перед построением самой "текстуры". Этот коэффициент должен быть полностью случайным. Так как сам алгоритм хорошо расписан на хабре, да и вообще в интернете, я не буду приводить самой его реализации, скажу лишь об устранении этой самой псевдо-случайности и о возможных оптимизациях. Только в отличие от генерации текстур, нужно считать интерполированный (можно использовать разную: линейную, косинусную, кубическую и другие) шум.
Текстура, сгенерированная по алгоритму Перлина:

Устраняем псевдо-случайность

Делается это довольно просто. Код:

fac=Random(1000); for (i=0 ,i<width,i++) //x { for (j=0 , i<length,i++) //z { heights[i][j]=PerlinNoisef(i,j,fac); } }

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

То есть сама функция должна выглядить примерно вот так:

for (int i=0 , i<= 12, i++) do begin total :=total+ CompleteNoise(x*freq, y*freq) * ampl; ampl := ampl*pres; freq:=freq*2; end; total:=(total)*2; Result:=total;

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

Оптимизация отображения ландшафта

Ландшафты 1 000 х 1 000 и больше, будут состоять из 2 000 000 + треугольников, что представляет собой довольно большую нагрузку на растеризатор. Поэтому минимум, что нужно использовать - это VBO, то есть хранить информацию о вершинах на видеокарте. Но это не спасет от лагов, например при ландшафте 10 000 х 10 000. Так что, кроме этого требуется делать Frustum Culling (по Oct Tree) и Occlusion Culling. Так же есть такая вещь, как GeoMipMap, но это отдельная тема.Скажу лишь, что для больших ландшафтов она обязательна, и открывает большие просторы для оптимизации (например LOD'ы). 

Дополнительные фичи

Для придания реалистичности ландшафту, следует использовать per-pixel lighting (для ландшафта хватит и простой апромиксации Фонга), parallax mapping и сплатинг. Если первые две вещи у человека, знакомого с 3D графикой, обычно не вызывают вопросов, то что такое сплатинг ландшафта многие изначально не знают. Так вот, сплатинг ландшафта служит для того, что бы имитировать такой природный процесс, как эрозия. Вы замечали, что на резких склонах гор поверхность покрыта не травой, как на равнине, а песком / землей. Для реализации всего этого дела нужны две текстуры. Одна - для равнинной поверхности ландшафта, другая - для поверхности склонов. Теперь, если мы примем равнинную текстуру за T1, а текстуру склона за T2, то формула будет выглядеть примерно так:

C = mix(T1,T2,dot(normal,vec3(0,1,0))

Где С - итоговый цвет, normal - нормаль к треугольнику, mix - функция линейной интерполяции.
dot(normal,vec3(0,1,0) - возвращает нам косинус угла отклонения от оси Y.Это можно упростить примерно так:

dot(norma,vec3(0,10) )= normal.x*0+normal.y*1+normal.z*0 = normal.y

А значит итоговая формула цвета будет такой:

C = mix(T1,T2,normal.y)

Все это хорошо реализовывается с помощью шейдеров. Приведу пример на GLSL.
Вершинный шейдер:

varying vec3 normal; varying vec2 tc0; varying vec3 pos; void main(void) { pos = vec3(gl_ModelViewMatrix* gl_Vertex); normal =normalize(gl_Normal); gl_Position = ftransform(); tc0 = gl_MultiTexCoord0.xy; }

Фрагментальный шейдер:

uniform sampler2D diffuseMap; uniform sampler2D splatMap; uniform float splatCoef; varying vec3 normal; varying vec2 tc0; varying vec3 pos; void main(void) { vec3 n =( normal ); vec3 newDiff = mix(texture2D(diffuseMap,tc0),texture2D(splatMap,tc0),n2.y*splatCoef); gl_FragColor =diffuse;//vec4(newDiff,1); //ambient + diffuse;// + specular; }

Заключение

Вот, вообщем то и все, что я хотел сказать. Я рассказал только основы, кто заинтересовался, советую копать в сторону GeoMipMap и GeoClipMap, без них действительно огромные ландшафты просто невозможны.

Ссылки по теме

  
Помощь
Задать вопрос
 программы
 обучение
 экзамены
 компьютеры
Бесплатный звонок
ICQ-консультанты
Skype-консультанты

Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 
Бестселлеры
Курсы обучения "Atlassian JIRA - система управления проектами и задачами на предприятии"
Microsoft Windows 10 Профессиональная 32-bit/64-bit. Все языки. Электронный ключ
Microsoft Office для Дома и Учебы 2019. Все языки. Электронный ключ
Курс "Oracle. Программирование на SQL и PL/SQL"
Курс "Основы TOGAF® 9"
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год. Электронный ключ
Курс "Нотация BPMN 2.0. Ее использование для моделирования бизнес-процессов и их регламентации"
 

О нас
Интернет-магазин ITShop.ru предлагает широкий спектр услуг информационных технологий и ПО.

На протяжении многих лет интернет-магазин предлагает товары и услуги, ориентированные на бизнес-пользователей и специалистов по информационным технологиям.

Хорошие отзывы постоянных клиентов и высокий уровень специалистов позволяет получить наивысший результат при совместной работе.

В нашем магазине вы можете приобрести лицензионное ПО выбрав необходимое из широкого спектра и ассортимента по самым доступным ценам. Наши менеджеры любезно помогут определиться с выбором ПО, которое необходимо именно вам. Также мы проводим учебные курсы. Мы приглашаем к сотрудничеству учебные центры, организаторов семинаров и бизнес-тренингов, преподавателей. Сфера сотрудничества - продвижение бизнес-тренингов и курсов обучения по информационным технологиям.



 

О нас

 
Главная
Каталог
Новинки
Акции
Вакансии
 

Помощь

 
Общая справка
Как оформить заказ
Тарифы доставки
Способы оплаты
Прайс-лист
Карта сайта
 

Способы оплаты

 

Проекты Interface Ltd.

 
Interface.ru   ITShop.ru   Interface.ru/training   Olap.ru   ITnews.ru  
 

119334, г. Москва, ул. Бардина, д. 4, корп. 3
+7 (495) 229-0436   shopadmin@itshop.ru
Проверить аттестат
© ООО "Interface Ltd."
Продаем программное обеспечение с 1990 года