Перейти к содержимому


Свернуть чат Чат Открыть чат во всплывающем окне

lz : (2 недель назад) Оно там просто всё вместе лежит.
Folgen : (2 недель назад) Даже сам Товарищ Майор не нашел бы.
Folgen : (2 недель назад) Ого, ребусы.
lz : (2 недель назад) Я там постоянно.
lz : (2 недель назад) Можно початиться в реалтайме в телеге - https://t.me/joincha...j5MKUrxakTyCPwQ
lz : (2 недель назад) Тулзы качаются программой bootstrap_tools из бутстраппера (как скачать - у меня в подписи). Если хочется самим собирать, отпишитесь ещё, я инструкции по сборке допишу.
PA3UJIb : (3 недель назад) по ходу это из LLVM
PA3UJIb : (3 недель назад) cmake скрипты недописаны. А заголовочники сначала подумал, что из boost, но и там такого не нашел
Folgen : (3 недель назад) У меня вообще фигня с СиМэйк. Я уж подумал ну его. А там хедеры нужны от Полигона4.
Folgen : (3 недель назад) Вот-вот!
PA3UJIb : (3 недель назад) Не знаю, я не смог его "tools" собрать - многих заголовочных нету и хз где их брать.
Гость : (3 недель назад) У кого-нибудь есть полный пак инструментария от lz?
Yakim (Watco... : (14 Июль 2018 - 00:06) :D
Yakim (Watco... : (14 Июль 2018 - 00:06) nope
Yandersen : (13 Июль 2018 - 22:07) Айаяй. Поди Якимко заспамил чат стикерами. :)
Yandersen : (13 Июль 2018 - 22:06) Да лан, тут каждый день кто-нить из админов заглядывает. Как пропустили?
Nextovoy : (13 Июль 2018 - 01:04) Я писал
Гость : (10 Июль 2018 - 22:42) Сорьки, что так у нас. Чего три года так и не попытался в чат писнуть? :)
Nextovoy : (06 Июль 2018 - 16:15) Спасибо
lz : (04 Июль 2018 - 19:44) Активировал.
Гость : (03 Июль 2018 - 16:30) Активируйте его.
Гость : (03 Июль 2018 - 16:30) Мой профиль - Nextovoy
Гость : (03 Июль 2018 - 16:25) Написать в чат. Профиль в ручную админы активируют.
Гость : (03 Июль 2018 - 15:47) Ох уж эта дурацкая привычка писать всё раздельно засоряя чат. Это всё классно, конечно, но ребята, одменестраторы, так называемые. Третий год пытаюсь зарегистрироваться (буквально, третий) на этом форуме, но ПИСЬМО С ПОДТВЕРЖДЕНИЕМ НА ПОЧТУ ТАК И НЕ ПРИХОДИТ. Что делать?
Гость : (03 Июль 2018 - 15:46) Перешёл я всё же по ссылке Redoctor'a...
Гость : (03 Июль 2018 - 15:41) Пора уже M4
Гость : (29 Июнь 2018 - 00:18) итак м3
lz : (28 Июнь 2018 - 16:01) Мы тебе и тут передадим.
Гость : (28 Июнь 2018 - 13:13) Зачем в телеграмме делать?!Я вот например не могу зайти,написать в чат,подписаться и не только у меня это.
Redoctor : (24 Июнь 2018 - 19:35) https://vk.com/away....0_23001&cc_key=
Redoctor : (24 Июнь 2018 - 19:34) Тогда в телеграмме в поисковике набери Механоиды 3
Гость : (24 Июнь 2018 - 19:05) Не открывается.
Redoctor : (24 Июнь 2018 - 18:00) https://t.me/mechanoids3 Для тех кто в танке.
Yakim (Watco... : (15 Июнь 2018 - 01:33) КРУЗИИИС!!!11

Изображение
lz : (15 Июнь 2018 - 00:09) КРУЗИС!
lz : (15 Июнь 2018 - 00:09) ЗИС
lz : (15 Июнь 2018 - 00:09) КРУ
Yakim (Watco... : (14 Июнь 2018 - 14:50) Крузис и Королева тоже не в моем вкусе, а проигрывать нечего =D
lz : (14 Июнь 2018 - 13:55) Конечно, полюбить - так королеву, проиграть - так миллион, сделать - так крузис.
smt005 : (14 Июнь 2018 - 00:22) И от третьего лица тоже можно сделать простенькую игру. Простая игра это лучше чем ничего.
smt005 : (14 Июнь 2018 - 00:21) А, ты хочеш что-бы хит был, с "Crysis" графоном и контентом на 100500 часов игры?
Yakim (Watco... : (14 Июнь 2018 - 00:18) Ни топдовншутеры, ни стратежки)
Yakim (Watco... : (14 Июнь 2018 - 00:15) Не, спасибо, не в моем вкусе=)
smt005 : (13 Июнь 2018 - 23:13) Помнится за пару недель от скуки сделал. Делал по вечерам.
smt005 : (13 Июнь 2018 - 23:13)

Фотография
- - - - -

Terraforming Engine

terraforming OpenGL height map

  • Авторизуйтесь для ответа в теме
Сообщений в теме: 15

#1 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 06 Июль 2014 - 19:57

Пишу на С++ движок для редактирования ландшафта в реальном времени. Обрабатывает карты высот прямо на видеокарте средствами OpenGL, позволяя вносить модификации "на лету". Пользуюсь бесплатной Visual Studio 2010. Все файлы периодически обновляю на своём Google Drive.
Terrain Engine.jpg
 
Я - сторонник идеалогии написания М3 с нуля. К сожалению, только такой подход мне лично интересен. Я очень дружу с графикой (ОпенГЛ), геометрией, ассемблером и инглишем (что помогает разбираться в буржуйских документациях), но нет опыта и интереса к аудио.

 

Для меня написание движка начинается с ландшафта. Я хочу от М3 огромных открытых территорий, эпических радующих глаз ландшафтов и возможности терраформинга. Это и есть цели проекта Terraforming Engine, являющегося одной из сторон самописного движка М3.

 

На данный момент получена дальность видимости в несколько десятков километров, неограниченных размеров карта, перемещение по которой происходит без "загрузок", а также возможность плюхать на карте горы в реал-тайме (изменения сохраняются). Разумеется, можно плюхать не только гору - добавить можно какие угодно модификаторы рельефа, но на данный момент так. Терраформинг есть, короче.

 

Карта высот состоит из кусочков, каждый размером 1024х1024 вершины. На каждую вершину приходится 8 байт данных (float+char[4]), хранящих высоту вершины и аттрибуты (первые два пока что несут индексы горизонтальной и вертикальной текстур). Карта состоит из 10-ти слоёв - кусочки каждого последующего слоя хоть и содержат то же количество вершин, но считаются в 2 раза большего размера. Таким образом реализованы уровни детализации. Менеджер ландшафта держит определённую часть кусочков карты в видеопамяти под видом текстур - подгружает требуемые и выгружает (сохраняет на диск) неиспользуемые. Модификации над кусками карты производятся прямо на видеокарте. При рендере из кусков карты всех уровней детализации вырезаются куски, из которых составляется слоёная текстура - выборочный кусок карты вокруг наблюдателя. Квадратная сетка рендерится 10 раз (для 10-ти уровней детализации), и вершинный шейдер выдирает из "пирожков" значения высот и аттрибутов каждой требуемой вершины, автоматом вычисляет нормали, тангенты и битангенты, а пиксельный шейдер накладывает текстуры. Получается мультитекстурный ландшафт (пока что текстур ландшафта с бамп-мапами у меня нет - буду рад, если кто скинет).

 

Пока что реализовано всё не оптимально и очень упрощённо. Ещё много интересной работы и моей любимой "оптимизации кода"...  :)



#2 OFFLINE   SHW

SHW

    Разработчик

  • Создатель
  • 32 сообщений
  • Откуда:Самара
  • Настоящее имя:Слава

Отправлено 08 Июль 2014 - 18:49

Карта высот, конечно, очень удобна, но воксельные движки универсальнее. Там тебе и гроты, и ущелья с отрицательными уклонами, и пещеры, и арки и вообще что угодно. Наверняка вы уже видели блог крутого чувака, который пилит воксельный движок с процедурной генерацией, L-системами и динамическим изменением.


Your mind is software. Program it.
Your body is a shell. Change it.
Death is a disease. Cure it.

#3 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 08 Июль 2014 - 22:46

Разумеется, я подобное не потяну. Вопрос ещё и в том, а нужны ли в М3 пещеры и закрытые локации? У меня от подземки в М1 до сих пор кошмары - глайд не приспособлен для закрытых пространств. Если мехоцивилизация выходит в девственный В.М., там по определению закрытых комплексов не может быть. Ну, пещеры как бы да, возможны, но учитывая редкость их нахождения в природе, можно ими и не заморачиваться. Мне в Мехах наоборот больше всего свобода открытого пространства доставляла. Ну а на крайняк никто ж не запрещает патчить ландшафт модельными элементами.



#4 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 13 Июль 2014 - 01:27

Публика, мой ландшафтный движок хочет поиграть с Вами! Но потребует от видюхи поддержки OpenGL 4.3.

Кнопок много:

ENTER - вход/выход в режим управления камерой;

нажатие на колёсико мыши - вход/выход в полноэкранный режим;

подкручиванием колёсика мыши регулируется скорость перемещения;

WSAD - вперёд/назад/влево/вправо;

C, SPACE - вниз/вверх;

Q,E - крен бочкой;

R переключает режим рендера: сетка/обычный;

+/- увеличивают/уменьшаю дальность видимости (т.е. размер рендеримой карты, а вместе с тем и дистанцию тумана);

Левая кнопка мыши плюхает на карту кратер ровненько под камерой;

правая кнопка мыши плюхает на карту рядом с камерой гору в рандомной ориентации.

 

Учтите, чем больше по карте летать, тем больше фрагментов карты будет сохранено на диск в папку Data//Map//. Все сделанные изменения таким образом сохраняются.

Прикрепленные файлы



#5 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 16 Июль 2014 - 01:02

Вот скачало 24 человека (у нас тут стока юзеров ещё нет даже) а нихто даж не откомментился, тихони! Сам откомментюсь.  :)

Вот что меня насторожило: если уткнуться носом в землю, рендер идёт быстрее, чем если смотреть вдаль - не замечали, как по тормозам вдаривает, когда камера поднимается?

 

И я задумался, отчего так. Ну, я в теме же, так что озарение в конце концов нашло мой моск и просочилось туда. Дело, как мне кажется, в способе обращения к текстурам и трилинейной фильтрации, которая у меня применяется. Ведь при трилинейной фильтрации цвет пиксела вычисляется на основе текселей из двух соседних мипмапов, поэтому при обращении к текстуре шейдер читает цвета из обоих. Но вот беда в том, что все текстуры ландшафта у меня хранятся в виде GL_TEXTURE_2D_ARRAY (чтобы по значению аттрибута вершины выбирать индекс нужной картинки), а это значит, что данные текстуры хранятся так: сначала идут вряд мипмапы нулевого уровня, за ними - мипмпапы уровня 1 и т.д. Соответственно, чем больше текстур (у меня 13 горизонтальных текстур), тем больше расстояние в байтах между мипмапой нулевого уровня и первого. Очевидно, что вся текстура целиком (13МБ) в кэш текстурного юнита не укладывается, поэтому после обращения к мипмапе нулевого уровня мипмапа первого уровня в кэши не может находиться, и последующее обращение к ней заставляет текстурный юнит ждать, пока данные подкачаются из VRAM, где вся текстура собсно и валяется.

 

Что это значит? Что хреново я мультитекстуринг организовал, низзя мипмапы юзать в текстурах типа GL_TEXTURE_2D_ARRAY с большим количеством слоёв.

 

Первая же альтернатива, пришедшая в мой моск - это не паковать все текстуры в одну слоёную, а раздать разным текстурным юнитам каждому свою. Ну а в шейдере, соответственно, объявить массив из самплеров

uniform sampler2D Textures[...];

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

 

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

 

Я счёл второй вариант более оптимальным. Но без мипмапов, при билинейной фильтрации получится, что текстуры вдали превратяться в искрящееся переливающееся всеми цветами гафно. А это не желательно. Как быть?..

 

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

 

Ололо, какая гениальная мысль, такую мысль надо было сразу думать! Вот только создавать каждую такую текстуру будет муторотень ещё та...

 

Немного времени спустя...

 

Пипец... Спасибо моей лени, что не позволила мне всё менять, ибо то, что я обнаружил, херит всю волшебную идею на корню. А обнаружил я, что выставление простейшей линейной фильтрации (GL_LINEAR) для фильтра минификации текстуры тормозит похлеще чем при трилинейной фильтрации (GL_LINEAR_MIPMAP_LINEAR).

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

 Ах, депрессия и безысходность...  :(



#6 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 17 Июль 2014 - 01:42

Зато кой-чё интересное обнаружил в процессе депрессивного ковыряния. Оказалось, что несколько обращений к разным частям одной и той же текстуры в одном и том же текстурном юните тоже немного тормозов добавляет. Ну, вертикальная текстура ведь два раза накладывается на один и тот же пиксель. А вот если одну и ту же вертикальную текстуру прицепить к двум разным текстурным юнитам одновременно, то тормозов уже нет. Ох уж эта потаённая кутерьма с кэшами - походу, всё дело в том, что у каждого текстурного юнита просто своё кэш индивидуальный, так что каждый пиксел рисуя, нужно, чтоб каждое обращение к текстурам шло через свой индивидуальный текстурный юнит - так максимально оптимально кэш будет использоваться. Значит тормоза с фильтром минификации GL_LINEAR могут иметь ту же природу - при растягивании текстуры ведь куче соседних пикселов нужны лишь несколько недалеко расположенных текселов текстуры, а вот при сжатии без мипмапов получается, что соседние пикселы обращаются к далеко расположенным текселям, так что кэш дрочится постоянно. Надо запомнить сие познание...



#7 OFFLINE   PA3UJIb

PA3UJIb

    Серый

  • Создатель
  • 171 сообщений

Отправлено 24 Июль 2014 - 19:22

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


 


#8 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 06 Август 2014 - 13:50

С Бампом всё круче! :D

Normal+Displacement+Demo1.gif

 

Добавил бамп, улучшил смешение текстур - использовал для этого Displacement-текстуру.

По просьбам публики сделал выравнивание камеры по горизонту. Коллизий с ландшафтом пока нет, так что можно сквозь рельеф пролетать. Сорьки.

 Управление всё то же - WASD, мышь для движения, Нажатие на среднюю кнопку мыши - вход в полноэкранный режим с управлением камерой. Переключение рендера в режим вайрфрейма н а кнопку R, кнопки +- увеличивают (уменьшают) дальность видимости в 2 раза (изначально она 30 км). Левая кнока мыши плюхает под камерой кратер, правая кнопка плюхает гору. Тут ничё нового.

Но блин, смешение текстур такое божественное, что просто ппц, я в оргазме. Поплюхайте горы с кратерами и пронаблюдайте сами! B)

Прикрепленный файл  Terrain Engine.rar   20,55МБ   35 - Раз(а) скачано

З.Ы.: папка проекта на Гугл-драйве обновлена.

 

---

 

Вот щас размышляю над оптимизацией. Пока что рендерится вся карта - вне зависимости от того, куда наблюдатель смотрит. А ведь нет смысла рендерить карту позади камеры, к примеру. Расколупывание меховских ММР карт вдохновило меня рендерить карту кусками. :)

 

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

Плюс хочется сделать возможным нестандартизованную модель карты. Ну вот сейчас каждый слой имеет дефолтный размер что-то около 125х125 точек (у внешних слоёв центр вырезан). А имеет смысл же сделать базовый слой бОльшим по размеру, а внешние слои с упрощёнными лодами - поменьше базового. Обосновано это тем, что высота отдельной точки на разных слоях в большинстве случаев немного различается, поэтому объекты, рендеримые на дальних лодах карты могут "висеть" в воздухе или "проваливаться" сквозь землю. Посему корректно отображать ландшафтные объекты можно лишь в пределах базового лода (иначе придётся проверять, на каком лоде карты объект находится, и в зависимости от этого корректировать высоту объекта, что породит артефакт прыганья).

 

Цель всего этого, напомню - реал-тайм терраформинг, мультитекстурный ландшафт и многокилометровая дальность видимости.



#9 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 17 Август 2014 - 20:29

Теперь вот стало ясно, что совпадающие по вертикали вершины одного слоя чуть-чуть рознятся по высоте с вершинами следующего слоя. Т.к. новый упрощённый алгоритм рисовки карты использует вершины лишь одного слоя, то получается просвечивание на границах клипмапов. Так что теперь нужно работать над алгоритмами терраформера и заставить его при генереньи нижнего слоя из верхнего тупо фетчить общие вершины напрямую, обходя интерполяционную функцию, из-за погрешностей вычисления которой совпадающие вершины соответствуют друг другу не на 100%.

 

---

 

Ы, подождёт сий баг, ещё идея посетила меня.

Учитывая, что сетка регулярная, можно ведь вообще обойтись без координат, генеря их прямо в шейдере, основываясь на значении gl_VertexID. Надо бы это попробовать...

 

Upd: ухаха, саксэс! Вершинный буффер ушёл в нибытие и координаты вершин вычисляются на основе gl_VertexID и униформы MapWidth. Никаких по-вершинных аттрибутов шейдеры больше не кушают, а значит оптимизации вершинного буфера не требуются. Круто, я вапще молодец.  :)

 

---

 

Надо бы отписаться о процессе - а вдруг кому интересно, что я тут втихаря кодю?..  :)

 

Последнюю неделю ломал моск над тем, как избавиться от плавания вершин. А вызвано оно было тем, что рисуемые вершины верхних слоёв не попадали чётко в узлы сетки, поэтому высоты брались из промежуточных значений. Ну вот например для десятого ЛОДа расстояние между вершинами 512 м, так что если юзер сместится на 100м, скажем, и вся карта сместится вместе с ним, то вот так и получалось несовпадение вершин верхних ЛОДов.

 

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

 

В результате при перемещении камеры каждый клипмап дискретно прыгает с места на место независимо от других клипмапов. Чем выше номер ЛОДа, тем реже он перепрыгивает, т.к. для смещения необходимо, чтобы привязка камеры сместилась на большое расстояние.

 

Визуально так намного лучше. Но вот технически это был геморрррр... Ведь независимо двигающиеся друг относительно друга клипмапы опасны дырами на стыках.

 

Решение, которое я применил - это частичное перекрывание граничных зон: каждая клипмапа имеет по краю один ряд дополнительных клеточек, половина которых накладывается на внутренний ряд клеточек вышележащей клипамы. Причём клипмапа обязательно должна иметь количество вершин, равное 4*n+3 (int n>=3). Вот как выглядит клипмапа минимальной ширины (15 вершин):

GridModel (Width=15, origin=bottom_left!).png

По краю виден ряд крупных клеток, идентичных клеткам вышележащей клипмапы.

 

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

GridModelOuterRing (Width=15).png

Разными цветами отмечены разные полигоны.

 

InnerRing - это основная часть клипмапы, рендеримая стрипсами. Для клипмапы минимального размера ширина этого кольца всего 1 клетка:

GridModelInnerRing (Width=15).png

Стрипсы идут справа налево для правой части и слева направо для левой части. Плюс ряды стрипсов прогрессируют вверх для верхней половины и вниз для нижней половины. Таким образом получается, что треуги рендерятся в направлении от камеры вдаль, что способствует эффективному Z-culling'у закрытых пикселов.

 

Ну и центральная часть рисуется стрипсами отдельно:

GridModelCenter (Width=15).png

Опять же, кутерьма с направлениями стрипсов та же, что и для InnerRing.

 

Вот такие пироги.  :)



#10 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 19 Август 2014 - 05:54

Ну вот, собсно, можно и продемонстрировать, как сие работает на практике:

Прикрепленный файл  Terrain Engine (Aug18).rar   20,56МБ   51 - Раз(а) скачано

[фолдер на гугл-драйве обновлён].

 

Что думаете о таком дискретном способе отображения лодов как альтернативе "плавающих вершин"?

 

Напомню кнопки:

режим сетки и обратно - на кнопку R;

кнопки +- меняют дальность видимости;

нажатие на колёсико мыши - вход / выход в полноэкранный режим (управлять камерой можно только в полноэкранке);

клавиши мыши плюхают гору / кратер;

WASD, C, Space - движение.



#11 OFFLINE   PA3UJIb

PA3UJIb

    Серый

  • Создатель
  • 171 сообщений

Отправлено 19 Август 2014 - 15:40

Ну, вроде вершины дальних гор (пусть они и покрыты туманом) не дергаются больше


 


#12 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 19 Август 2014 - 22:23

Ну так да же. При приближении просто добавляются новые вершины в промежутках между базовыми.

 

Я тут узнал, что Early Z-Cull не работает, если фрагментный шейдер пишет значение глубины. Вот щас думаю над тем, как и поиметь линейный буффер глубины, и при этом не писать глубину в шейдере самому.

 

Для тех кто в танке: Early Z-Cull - это такая фича современных карт, когда тест глубины рисуемого фрагмента производится перед тем, как фрагментный шейдер (который зачастую громоздок) будет исполнен. И если тест глубины проваливается, то фрагмент не рисуется. Вот у меня фрагментные шейдеры к текстурам обращаются аж 24 раза - неплохо было бы закрытые участки не перерисовывать. Учитывая, что карта у меня рисуется от близи в даль, бОльшая часть фрагментов отбрасывается. Отбрасывать их не исполняя громоздкий шейдер - большой плюс к производительности.  :)

 

Апдэйт: фигушки, линеаризовать буффер глубины без насильственного писания gl_FragDepth во фрагментном шейдере невозможно, походу.

 

Я вот что попробовал. Учитывая, что x,y,z координаты делятся на w, а деление координаты z нежелательно, я попробовал предомножить ентую z координату на w, ожидая, что после неизбежного деления на w получится снова z, как будто её и не делили. Ну, ещё на константу zMax поделил, чтобы результат получился в диапазоне [0...1]. Финт ушами, да?

А, ну ещё и gl_ClipDistance[0] использовал, чтобы отсечь геометрию, что за камерой.

 

На первый взгляд всё ништяк. Однако когда я уткнул камеру в поверхность, внезапно начали просвечиваться поверхности, что чуть дальше находятся. Думал много, проверил всё на свете. Эго отвисло до плинтуса, я чуть в отчаяние не впал. Задолбался перечитывать описание преобразований в оконные координаты и клиппинга, всё никак вкурить не мог, где ж там собака порылась.

 

Ну и наконец дошло. Деление на w ведь производится после клиппинга. А при клиппинге полигон сечётся - в него вставляются новые вершины, координаты которых линейно интерполируются из иходного полигона. Учитывая то, что  z*w/zMax на этом этапе ещё не разделен на w, результат линейной интерполяции уквадраченной координаты получается некорректным для усечённых полигонов, т.е. тех, что пересекают плоскость "экрана". Ну т.е. x,y правильные выходят, а вот z получается неправильная, из-за чего значение интерполированной уквадраченной глубины фрагмента после деления на w уже не даёт ожидаемое мною значение z/zMax - оно немного другое получается и в некоторых случаях оказывается бОльшим, чем у полигонов, что в реале находятся дальше, и те нагло "просвечивают".

 

Короче говоря. Ждём, когда OpenGL разрешит нам указывать, какие координаты делить на какие (а не тупо всех разом на w) или введёт расширение "ГЛ_НЕ_ДЕЛИТЬ_ЗЕД", ну а до тех пор линеаризуем буффер глубины вручную во фрагментном шейдере.  :(

З.Ы.: рисовать сцену много раз с разными камерами, как Юнити делает - это маразм, ИМХО.



#13 OFFLINE   Taugeshtu

Taugeshtu
  • Создатель
  • 36 сообщений

Отправлено 20 Август 2014 - 11:58


рисовать сцену много раз с разными камерами, как Юнити делает - это маразм, ИМХО.

Линейный буфер глубины, ещё и усилиями фрагментного шейдера - это маразм, ИМХО.


, наверное...


#14 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 20 Август 2014 - 13:23

О как консервативно? А как насчёт подумать?

 

При максимальной дистанции отрисовки 100 километров (!) и разрядности буффера глубины 32 бита мы получаем линейный z-буффер, способный различать поверхности с разницей расстояния в 23 микрометра (!). И эту прецизионную точность мы имеем на протяжении всей дистанции прорисовки! Этого более чем достаточно даже вблизи камеры.

 

А как насчёт отрисовки теней? А ещё лучше. Можно задать константный оффсет всего в 1 мм и забыть об артефакте самозатенения, т.к. константный оффсет будет одинаково хорошо работать на любых дистанциях.

 

Ну что, маразм ли этот линейный z-buffer? ;)



#15 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 21 Август 2014 - 22:49

Выставив дальность видимости в 240 км уткнул камеру как можно ближе к поверхности. Ибо не верят люди на OpenGL, что имея 24 бита под буффер глубины можно без артефактов рисовать такие дистанции при ближней плоскости отсечения всего 1 мм.

240kmViewDistance.jpg



#16 OFFLINE   Yandersen

Yandersen

    Диванный теоретик

  • Админ
  • 454 сообщений
  • Откуда:Canada
  • Настоящее имя:Ян

Отправлено 28 Август 2014 - 13:46

...Продолжаю спамить и надоедать. Пока что всем поф.  :(

 

...А тем временем почитываю документацию на ГЛСЛ 4.5.

 

Вот вдохновилсо разобраться с GEOMETRY шейдерами. С их помощью уменьшил количество обращений к текстурам - теперь пиксельные шейдеры получают 3 аттрибута вершин своего треугольника от шейдера геометрии. А раньше пиксельные шейдеры сами лезли в текстуру аттрибутов (которая хранит, напомню, идентификаторы текстур) и вытаскивали 4 значения оттуда. Папку проекта обновил, а вот конкретно шейдер рисования карты с шейдерами геометрии.

 

Тоисть вот как оно работает. Сначала вершинный шейдер вычисляет горизонтальные координаты точки, основываясь на индексе вершины, т.к. рендер регулярной сетки позволяет обойтись без повершинных аттрибутов - одних индексов и ширины карты достаточно, чтоб определить, где вершина находится. Затем вершинный шейдер лезет в карту аттрибутов и вытаскивает оттуда индекс(ы) текстур (uvec4), а из карты высот вытягивает высоту точки (float). Ну ещё плюс 4 вершинки близлежащих тоже хапает, чтоб нормальку вычислить. Однако если напрямую выводить аттрибут в растеризатор, то пиксельный шейдер получит интерполированное значение аттрибута от трёх вершин (или если flat использовать - то неинтерполированный аттрибут одной из вершин). А ведь это неверно: у каждого треуга три вершины, значит разных текстур на треуге может быть смешано три. Получается, пиксельному шейдеру нужно передавать все три аттрибута отдельно.

 

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

 

А без шейдера геометрии приходилось пиксельному шейдеру передавать координату точки, чтоб он сам текстурные индексы выковыривал. А поскольку вершин всегда меньше чем фрагментов, то количество обращений к текстуре аттрибутов стало много меньшим. Это должно быть хорошо, как я понимаю.  :)

 

Кстати, FileGLSL.hpp обновил - теперь линии кода корректно отображает при дебаггинге, комменты в конце строчек кода переваривает и о директивы препроцессора не спотыкается. Просто я изначально думал, что каждая строчка кода должна заканчиваться нулём и код нужно передавать как лист нуль-терминатед стрингов, а как документацию почитал, понял, что символ новой строки можно юзать, т.е. весь код из файла можно в неизменном виде передавать функции glShaderSource.







Темы с аналогичным тегами terraforming, OpenGL, height map

Количество пользователей, читающих эту тему: 1

0 пользователей, 1 гостей, 0 анонимных