Мега-пост

Приставка “Мега-” нынче очень популярна, особенно у нас на проекте. Это какая-то массовая истерия, мегадеревья, мегаАИ, мегаТрава, мегаРедактор, пиздец! А началось конечно с мегаТекстуры.

Понимаю, я всех заёб этой темой, но первый мой пост может быть только про ЭТО :)

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

А что дальше?

Немного о теории…

Пусть вся геометрия “развёрнута” на очень большой текстуре, размером MxM, и если эта текстура влазит в видео память – мы можем отрисовать всю геометрию за один вызов (это неэффективно с точки зрения отсечения видимости, но это возможно). Очевидно, этот случай нам не интересен, потому как всё работает.

А что если текстура не влазит в видео память? В 99% случаях так и будет.

Корни этой проблемы уходят далеко в историю, сводится всё к текстурному менеджеру, существуют миллионы алгоритмов различных менеджеров текстур. Алгоритм мегатекстуры был известен еще в 98-ом году, его представили на SIGRAPH’е Michael E. Goss и Kei Yuasa, правда они не подозревали что он так называется :)

ИМХО, на самом деле это обычный текстурный менеджер, только оперируем не цельными текстурами, а кусочками (тайлами) очень большой текстуры. Отталкиваемся от идеи что в видеопамяти нам нужны только те куски текстуры (тайлы), которые мы видим на экране, остальное нас не волнует.

Получается что в идеале нужна одна текстура размером с экран (ну хорошо не одна, а по одной на диффуз, нормали, спекуляр и т.д.). Понятно что этого не добиться, есть много факторов – back faces, occlusion, движение камеры и т.д. Которые можно побороть до приемлемой формы. Назовём эту текстуру кешем видимых тайлов.

Из этого еще и вытекает такая вещь как лоды (мипы) текстуры: Чем дальше от камеры тайлы, тем меньшего разрешения (в текселях) тайлы необходимы. Например, это значит что можно объединить 4 соседних тайла на определённом расстоянии от камеры (там где уже 1-й лод) в один тайл такого же разрешения – как и на близком расстоянии (на нулевом лоде). Этим можно воспользоваться для достижения однородности кеша.

Т.е. в кеше мы храним тайлы размером NxN текселей, которые на геометрии в мировом пространстве имеют различную площадь. К примеру если тайл нулевого лода имеет площадь 1метр Х 1метр, то тайлы лода lod будет иметь площадь (2^lod) метров Х (2^lod) метров.

Так же необходима еще одна текстура, которая покрывает всю геометрию как и основная текстура, indirectional texture, её еще называют текстура индексов, которая несёт информацию о расположении тайлов в кеше и их лод. Эта текстура имеет разрешение (M/N) x (M/N), т.е. каждый пиксель это один тайл. Доступ к этой текстуре осуществляется по текстурным координатам геометрии.

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

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

Подробнее о паковке можно почитать в статье: Real-Time Texture Streaming & Decompression, November 11th 2006 J.M.P. van Waveren, (c) 2006, Id Software, Inc.

http://softwarecommunity.intel.com/UserFiles/en-us/Image/1221/Real-Time%20Texture%20Streaming%20&%20Decompression.pdf

Это всё и называется мегатекстура :) точнее так называет этот алгоритм Кармак, но мне понравилось название.

А вобще это мне кажется развитие алгоритма Clipmaps для более сложной геометрии.

И так, задача разбивается на две подзадачи:

1. Определить видимые тайлы и лоды тайлов (с помощью GPU это стало возможным в реалтайме)

2. Обновить кеш-текстуру, обновить текстуру индексов (Шина позволяет взять из видео памяти информацию о видимости и обновить кеш)

Подробнее, и даже всё очень подробно описывается в статье: Unified Texture Management for Arbitrary Meshes, Sylvain Lefebvre, Jérome Darbon, Fabrice Neyret

http://www.inria.fr/rrrt/rr-5210.html

Видео к статье: http://www-evasion.imag.fr/Membres/Sylvain.Lefebvre/texprod/video-hgh-res-2.mp4

Хотел всю статью тут набить по-русски, но чего то большой пост получается.

А теперь о грустном:

- Я не смог повторить алгоритм вычисления лодов, который описан в этой статье. Он не работает даже на листочке бумаги, или я чего-то до сих пор не понял. Сейчас я считаю лоды как “расстояние от камеры”*константа, которое является ddx, ddy при чтении из текстуры лодов. Приемлимо, но хотелось бы как в статье.

- Не реализовал алгоритм сжатия и распаковки тайлов (в процессе)

Вот такой получился мегапост. С нетерпением жду обсуждения, кому эта тема еще не надоела :)

  • binstream

    Гг, у нас буквально в прошлом месяце Frustum сделал террейн с клипмапами: http://unigine.com/devlog/24/
    Модный тренд налицо =)

  • http://games.1c.ru CybeRUS

    Clipmap’ы хороши для ландшафта да, просто и со вкусом.
    Мегатекстура для любой геометрии подходит

  • DigiMind

    А мегатулсет под мегатекстуру сделал? :)

  • http://games.1c.ru CybeRUS

    мегатулсет это пиздец работы на пол года!
    пока что фотошопом

  • DigiMind

    > пока что фотошопом

    Художники тебя уже прокляли поди? :)

  • http://games.1c.ru CybeRUS

    художники хотят что бы было красиво, они радуются, теперь им свобода действий.
    Правда очень мечтают о мегатулсете – ведь у каждого должна быть своя мечта! :)

  • Sergei_am

    А видимость как определяеш? Чисто как видимость, или просто LOD во все сторонъ от камеръ?
    Т.е. когда повернемся назад, оно будет подгружать текстуру?

  • binstream

    > мегатулсет это пиздец работы на пол года!
    > пока что фотошопом

    Фотошоп не умеет работать с сильно большими файлами, подсунуть ему хотя бы 32769×32769 – умрет в конвульсиях :(. У нас редактор террейна умеет сам редактировать все слои (но он не очень удобный и фичастый, фотошоп-то всяко лучше), плюс можно экспортнуть любой кусочек, отредактировать в любимом 2D редакторе и импортировать обратно.

  • http://games.1c.ru CybeRUS

    > А видимость как определяеш? Чисто как видимость, или просто LOD во все сторонъ от камеръ?
    > Т.е. когда повернемся назад, оно будет подгружать текстуру?
    Видимость определяется рендером в текстуру в пространстве текстурных координат, делаю frustum culling, back face culling, получается рисуем только видимые пиксели в текущий момент. Рисую с текстурой LOD (каждый мип уровень имеет свой цвет/значение) – получается LOD считает видео карта. Только у меня не получилось как в статье описано. Если делать как в статье, то у меня наоборот вдали нулевой лод, а в близи последний, это логично если на бумажке расписать всё. Никак не могу понять почему в статье это написано.
    Потом эту текстуру забираю в системку и строю по ней текстуру индексов, обновляю кеш. Каждый кадр это делается.
    Если повернуть камеру, то будут видны новые тайлы, а старые помечаются как ненужные. И обновляется кеш.

  • http://games.1c.ru CybeRUS

    > Фотошоп не умеет работать с сильно большими файлами, подсунуть ему хотя бы 32769×32769 – умрет в конвульсиях :(. У
    > нас редактор террейна умеет сам редактировать все слои (но он не очень удобный и фичастый, фотошоп-то всяко лучше),
    > плюс можно экспортнуть любой кусочек, отредактировать в любимом 2D редакторе и импортировать обратно.

    Фотошоп да, не умеет, максимум удобно работать с 16Кх16К.
    Но у меня задача была сделать сам принцип алгоритма, а уже художники делают как им удобно.
    Конечно в будущем надо делать тулсет, но у времени пока нет.
    У вас крутые тулзы :) завидую

  • alexey

    > Видимость определяется рендером в текстуру в пространстве текстурных координат

    С тайлингом проблемы не возникнут?

  • http://games.1c.ru CybeRUS

    > > Видимость определяется рендером в текстуру в пространстве текстурных координат
    > С тайлингом проблемы не возникнут?
    Не вознукнут, если текстурные координаты находятся в диапазоне 0..1

  • lordmaze

    Всуну свои 2 копейки. В общем сей подход которым я “болел” некоторое время назад упирается в тулзу для художников. Те вот если террейн – то просто в тулзу, Если произвольный меш с произвольным количетсво исходных текстур и произвольным же маппингом – те еще в препроцессор/конвертер этого heap в меш с анврапленными UV и сгенеренной “мега текстурой”.

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

    Ну а тулзу писать в общем не неделю и не две :)

  • http://games.1c.ru CybeRUS

    2lordmaze: Согласен насчёт тулзы, это бОльшая часть работы. Но я себе поставил задачу повторить “мега-текстуру”, что в принципе получилось и работает отлично (остались проблемы с лодами, но я думаю решу). Сам принцип меня привлекает. Закинуть все объекты на виртуальную текстуру и не думать о том, что видео память кончится.

  • lordmaze

    > Закинуть все объекты на виртуальную текстуру и не думать о том, что видео память кончится.

    Net nu sam po sebe metod on bespolezen. Polezno imenno vot to xchto artists mogut zabit o limitations – tochnee u nih vsio ravno est limitation po resolution etoy neebicheskoy texturi…

    Kstati – a u tebya ono rabotaet na proizvolnoy scene ? Te na vhode – taki “alya terrain” ili prosto Max/Maya scene s randomno mapped textures ?

  • http://games.1c.ru CybeRUS

    > Net nu sam po sebe metod on bespolezen. Polezno imenno vot to xchto artists mogut zabit o limitations – tochnee u
    > nih vsio ravno est limitation po resolution etoy neebicheskoy texturi…

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

    > Kstati – a u tebya ono rabotaet na proizvolnoy scene ? Te na vhode – taki “alya terrain” ili prosto Max/Maya scene
    > s randomno mapped textures ?

    Алгоритм работает с произвольной геометрией, главное что бы мэппинг не выходил за пределы 0..1

  • Sergei_am

    Сам по себе метод далеко не бесполезен, ибо его спокойно можно заюзать на уже существующие обьектъ, чисто в виде текстурного кеша – оно сьекономит VRAM, за счет чтения с диска/закачки из RAM.

  • http://games.1c.ru CybeRUS

    >Сам по себе метод далеко не бесполезен, ибо его спокойно можно заюзать на уже существующие обьектъ, чисто в виде
    >текстурного кеша – оно сьекономит VRAM, за счет чтения с диска/закачки из RAM.

    Я полностью согласен! А на консолях еще и кеш обновлять можно быстро, нет никаких AGP/PCI-E

  • kirill@gaijin.ru

    а как это – тайлинг от если мэппинг в пределах 0..1?

  • todace

    конвертер это все же не тулза. проще обычно.

  • http://games.1c.ru CybeRUS

    >а как это – тайлинг от если мэппинг в пределах 0..1?

    “Тайлинг” это использование текстуры или её части несколько раз на модели, если ты про этот тайлинг, то это просто – текстурные координаты, ведь при выборке из текстуры (при настройках WRAP) используется только дробная часть.

  • http://games.1c.ru CybeRUS

    > конвертер это все же не тулза. проще обычно

    Про какой конвертор речь?