Простите, но вот уж не могу не похвастаться:
Дальность видимости 20км (дымка дальше не позволяет видеть, в реале 30км).
Освоил, наконец, мультитекстуринг. Реализовал с помощью двух общих палитр картинок: 13 горизонтальных (травко-песочко-камешки разные) и 9 вертикальных (скалы), запакованых в две текстуры типа GL_TEXTURE_2D_ARRAY - т.е. массив текстур.
Какие текстуры применимы к каждой отдельной вершине, указано с помощью 4хбайтного аттрибута, в котором первое значение - индекс горизонтальной текстуры, второй байт несёт индекс вертикальной текстуры, а 3-й и 4-й я пока не придумал под что отвести, так что про запас пока.
Так что все 4 соседних вершины могут нести разные индексы текстур. Пока что выглядит убого-зеброобразно, т.к. при плюхании горы на карту индексы текстур выставляются тупо из рассчёта высоты вершины. Т.е. без артистического вмешательства и Святого Рандома. Пока что. Ну и интерполяция текстур между вершинами пока что как в Мехах - тупо-линейная. Зато вот с вертикальными текстурами лучше получилось - нет "линий" у подножий гор и растянутостей текстур. Это потому, что фрагментный шейдер, основываясь на значении вектора нормали в точке, выбирает, какую текстуру и в какой пропорции применить - горизонтальную или вертикальную (вертикальных две, кстати). Если нормаль смотрит вверх (у-компонента много больше x и z), будет преобладать горизонтальная текстура, если в бок - вертикальная текстура.
Получается, что на каждый пиксел фрагментный шейдер выковыривает из текстур разные цвета аж 12 раз, смешивая цвет от 4-х вершин, каждый из которых является результатом смешения цветов горизонтальной и вертикальной(х2) текстур. Такой шейдинг, разумеется, ресурсозатратен: крася всё зелёным цветом можно было позволить 60км дальность видимости при том же фпс, что и с мультитекстурингом и 30км (в 4 раза меньше треугольников).
Каждый фрагмент карты размером 1024х1024 вершины содержит в себе 2 массива: карту высот и карту аттрибутов. Таким образом на каждую вершину приходится 8 байт данных {float,char[4]} и общий размер каждого фрагмента карты получается 8МБ. При этом количество уровней детализации - 10, т.е. сегмент карты нулевого уровня имеет размер 1024х1024 метра, 1-го уровня - 2048х2048 метров, 2-го - 4096х4096 метров и т.д., несмотря на то, что количество вершин во всех сегментах одинаково. При модификации карты обновляются затронутые сегменты всех вышестоящих уровней детализации. Т.к. рассчёт шёл на реал-таймовый терраформинг (аччивка успешно достигнута, кстати), то в видюхе постоянно ошивается определённое количество кусков карты. При терраформинге, проходящем на видюхе, эти куски модифицируются, необходимые подгружаются с диска, замещая отработавшие, которые сохраняются на диск.
Отсутствующие сегменты создаются на основе имеющихся сегментов вышележащего слоя путём "увеличительной проекции". Пока что тут косяк: растягивая верхний слой для проекции на нижний, получается, что четверть вершин нижнего слоя чётко копирует данные вершин из верхнего слоя, но вот все остальные попадают в промежутки между ними. Т.е. их значения являются результатом линейной интерполяции. Таким образом самый нижний слой, полученный в результате послойного растягивания верхнего слоя выглядит как полотно огромных квадратов. Вот думаю щас, как с этим бороться. Либо рандомчег призвать на помощь, либо что-нить как-нить со сплайнами замутить чтоле, чтоб кругленько было. ХЗ пока, думаю вот.
Для рисовки карты из всех 10-ти слоёв собирается стопка вырезанных кусков, и 2 полученных слоёных текстуры (высОты и аттрибуты) юзаются вершинным шейдером, который вытягивает из них высоту и аттрибут для каждой вершины во время рисовки по стандартной сетке. Слоёные пирожки заново составляются каждый раз после того, как карта была изменена или камера переместилась достаточно далеко. К счастью, это не ресурсозатратно, так что может происходить покадрово, при условии, что все требуемые куски карты находятся в видеопамяти. Иначе придётся сперва произвести их тусовку, чтобы собрать все фрагменты, требующиеся для составления пирожков.
Рисуются пирожки так: сначала рисуется полный квадрат нулевого уровня детализации, затем рисуются все остальные слои, каждый в 2 раза больше, но с вырезаной центральной частью. Получается, что треуги каждого последующего слоя в 2 раза больше по размеру, но из-за перспективы, на экране все треуги занимают примерно одинаковую площадь. Геморрно было, разумеется, сопоставлять без щелей и расхождений внешние края одного слоя с внутренними границами следующего слоя, т.к. край внутреннего слоя имеет в 2 раза больше вершин. Решил я, что лучшее решение - считать внешний край внутреннего слоя как будто принадлежащим следующему слою - т.е. брать значение высоты не из своего слоя, а из следующего. Получилось идеально.
Ну в общем вот, в неравном бою с ордами собственнокриворучно созданных багов, ковыряю ландшафтег, попутно зубря ОпенГЛ, и изредка спотыкаясь о баги даже в драйверах нВидии.
Был бы благодарен, если бы кто дал кучку ландшафтно-тематичных текстурок с бамп-мапами и оффсет мапами, чтобы добавить кульного бампа в мой картонный ландшафт и реалистично смешивать текстуры вместо этой убогой линейной полупрозрачной интерполяции.